惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

W
WeLiveSecurity
博客园 - 【当耐特】
Microsoft Azure Blog
Microsoft Azure Blog
WordPress大学
WordPress大学
Stack Overflow Blog
Stack Overflow Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
IT之家
IT之家
Cloudbric
Cloudbric
The Register - Security
The Register - Security
小众软件
小众软件
PCI Perspectives
PCI Perspectives
G
Google Developers Blog
AI
AI
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Google DeepMind News
Google DeepMind News
Google DeepMind News
Google DeepMind News
宝玉的分享
宝玉的分享
Recent Commits to openclaw:main
Recent Commits to openclaw:main
量子位
TaoSecurity Blog
TaoSecurity Blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
F
Full Disclosure
N
Netflix TechBlog - Medium
博客园_首页
Last Week in AI
Last Week in AI
A
Arctic Wolf
B
Blog RSS Feed
J
Java Code Geeks
C
Cybersecurity and Infrastructure Security Agency CISA
I
InfoQ
aimingoo的专栏
aimingoo的专栏
云风的 BLOG
云风的 BLOG
NISL@THU
NISL@THU
MyScale Blog
MyScale Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Jina AI
Jina AI
有赞技术团队
有赞技术团队
S
Schneier on Security
L
Lohrmann on Cybersecurity
P
Privacy & Cybersecurity Law Blog
T
Threat Research - Cisco Blogs
P
Palo Alto Networks Blog
S
Security @ Cisco Blogs
Security Archives - TechRepublic
Security Archives - TechRepublic
Security Latest
Security Latest
Vercel News
Vercel News
博客园 - 司徒正美
Webroot Blog
Webroot Blog
Hacker News: Ask HN
Hacker News: Ask HN
A
About on SuperTechFans

博客园 - 李华星

[原创]解决某物流企业二维码打印问题 The Workflow Management Coalition Specification 招聘.net软件开发工程师 AgilePoint BPMS软件评估分析 谈谈对BPM的理解 SharePoint WebPart开发步骤 原创对联大观园 SmartPublisher设计之旅 — 软件设计无需后悔莫及 .NET环境下的SNMP编程 - 李华星 - 博客园 SNMP基础简介 SmartPublisher设计之旅 — 软件开发之前先做个梦 SmartPublisher设计之旅 — 让理想在仇恨中茁壮成长 - 李华星 没事儿就来说些荒唐事儿 SmartPublisher设计之旅 — 优秀的设计才是让软件永葆青春的秘诀 - 李华星 SmartPublisher设计之旅 — 打好基础是实现理想的首要任务 - 李华星 分享一套.Net开发环境下的界面框架组件 SmartPublisher设计之旅 — 让梦想成为理想 SmartPublisher设计之旅 设计模式系列漫谈之十二 - 职责链模式
设计模式系列漫谈之十三 - 访问者模式
李华星 · 2008-01-09 · via 博客园 - 李华星

有这么一则笑话:

         话说有对一年轻夫妇生了一对双胞胎男孩。俩小子长得一模一样,还特别调皮。 平时一般都是妈妈照顾俩小子。可是有一天, 妈妈出差了,晚上爸爸给俩小子胎洗完澡,把他放到床上,催他们快睡觉,小宝就笑起来了:“哥哥都洗两次了,我都还没洗澡呢。”。爸爸:“还好不是喂饭” 。

访问者模式(Visitor)解决方案

      访问者模式适用于数据结构相对稳定的系统(两个小孩、负责喂饭和洗澡),它把数据结构和作用于结构上的操作之间的耦合解脱开,使得操作集合可以相对自由地演化。数据结构的每一个节点都可以接受一个访问者的调用,此节点向访问者对象传入节点对象,而访问者对象则反过来执行节点对象的操作。这样的过程叫做"双重分派"。节点调用访问者,将它自己传入,访问者则将某算法针对此节点执行。

访问者模式涉及到抽象访问者角色、具体访问者角色、抽象节点角色、具体节点角色、结构对象角色以及客户端角色。
抽象访问者(Visitor)角色:声明了一个或者多个访问操作,形成所有的具体元素角色必须实现的接口。如Visitor类
具体访问者(ConcreteVisitor)角色:实现抽象访问者角色所声明的接口,也就是抽象访问者所声明的各个访问操作。 如Wash类、Feed类。
抽象节点(Element)角色:声明一个接受操作,接受一个访问者对象作为一个参量。如Child类。
具体节点(ConcreteElement)角色:实现了抽象元素所规定的接受操作。如Son类。
结构对象(ObiectStructure)角色:可以遍历结构中的所有元素;如ObiectStructure

Visitor类如下:

public abstract class Visitor
{
    
public abstract void Visitor(Son son);
}

Wash类如下:

public class Wash:Visitor
{
    
public override void Visitor(Son son)
    {
        son.Washed
=true;
    }
}

Feed类如下:

public class Feed:Visitor
{
    
public override void Visitor(Son son)
    {
        son.Feeded
=true;
    }
}

Child类如下:

public abstract class Child
{
    
public string Name;
    
public bool Washed=false;
    
public bool Feeded=false;
    
public Child(string name)
    {
        Name
=name;
    }
    
public abstract void Accept(Visitor visitor);
}

Son类如下:

public class Son:Child
{
    
public Son(string name):base(name)
    {
    }
    
public override void Accept(Visitor visitor)
    {
        visitor.Visitor(
this);
    }
}

ObiectStructure类如下:

public class ObiectStructure
{
    
private List<Child> list=new List<Child>();
    
    
public void Add(Child ch)
    {
        list.Add(ch);
    }
    
public void Remove(Child ch)
    {
        list.Remove(ch);
    }
    
public void TakeCareofChildren(Visitor visitor)
    {
        
foreach(Child ch in list)
        {
            ch.Accept(visitor);
        }
    }
}

客户端调用如下:

public class Client
{
    
public static void Main()
    {
        ObjectStructure obj
=new ObjectStructure();
        obj.Add(
new Son("小宝"));
        obj.Add(
new Son("大宝"));

        Wash w

=new Wash();
        obj.TakeCareofChildren(w);

        Feed f

=new Feed();
        obj.TakeCareofChildren(f);
    }
}