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

推荐订阅源

U
Unit 42
T
The Blog of Author Tim Ferriss
H
Help Net Security
博客园 - 叶小钗
云风的 BLOG
云风的 BLOG
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
D
DataBreaches.Net
博客园 - 聂微东
A
About on SuperTechFans
大猫的无限游戏
大猫的无限游戏
P
Proofpoint News Feed
Martin Fowler
Martin Fowler
博客园 - 【当耐特】
S
SegmentFault 最新的问题
Blog — PlanetScale
Blog — PlanetScale
酷 壳 – CoolShell
酷 壳 – CoolShell
G
Google Developers Blog
I
InfoQ
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
GbyAI
GbyAI
B
Blog
Engineering at Meta
Engineering at Meta
V
V2EX
Hugging Face - Blog
Hugging Face - Blog

博客园 - hzwang

Administering your Windows Internal Database (MICROSOFT##SSEE) instance(转) VS 2008如何连接TFS 2010 learning F#(1):编程环境 learning F#: 开篇 Tip for using Fiddler on localhost (转载)ASP.NET MVC – Add CSS class Attribute I will write at least one blog every week 使用位逻辑运算来实现位向量 对象判等 sql bcp Utility工具使用 C# 3.0 —— 扩展方法 读代码随笔(一):using语句的使用 抽象类与接口(转) 在 C# 中实现 Singleton (转) 设置VSS2005使支持通过Internet访问 VSS使用手册 ASP.NET Forms 身份验证控制流 Cookie使用总结 不断努力,不断学习
visitor(访问者)模式 - hzwang - 博客园
hzwang · 2007-05-20 · via 博客园 - hzwang

using System;

namespace Visitor
{
    
public abstract class Animal
    
{
        
public void Run()
        
{
            Console.WriteLine(
"I'm running!");
        }


        
public abstract void Accept(AnimalVisitor visitor);
    }


    
public class Dog:Animal
    
{
        
public override void Accept(AnimalVisitor visitor)
        
{
            visitor.Visit(
this);
        }

    }


    
public class Cat:Animal
    
{
        
public override void Accept(AnimalVisitor visitor)
        
{
            visitor.Visit(
this);
        }


    }


    
public abstract class AnimalVisitor
    
{
        
public abstract void Visit(Dog animal);
        
public abstract void Visit(Cat animal);
    }


    
public class MyVisitor:AnimalVisitor
    
{
        
public override void Visit(Cat animal)
        
{
            Console.WriteLine(
"Cat's new method");
        }

        
public override void Visit(Dog animal)
        
{
            Console.WriteLine(
"Dog's new method");
        }

    }

    
public class JumpVisitor:AnimalVisitor
    
{
        
public override void Visit(Cat animal)
        
{
            Console.WriteLine(
"Cat is jumping!");
        }

        
public override void Visit(Dog animal)
        
{
            Console.WriteLine(
"Dog is jumping!");
        }

    }


    
public class App
    
{
        
public static void Main()
        
{
            Animal[] animals 
= new Animal[2];
            animals[
0= new Dog();
            animals[
1= new Cat();
            animals[
0].Accept(new MyVisitor());
            animals[
0].Accept(new JumpVisitor());
            animals[
1].Accept(new MyVisitor());
            animals[
1].Accept(new JumpVisitor());
        }

    }

}

    这里只是我学习设计模式一个笔记式的记录,在这里我不过多的介绍这个模式,有许多人写的好,
我个人比较喜欢吕震宇的博客(www.cnblogs.com/zhenyulu)。
    这是我学习访问模式时自己做的一个小例子,访问者模式是为了使你在不改变各元素的类的前提
下定义作用于这些元素的新操作。
    在我的这个例子里,基类animal只有一个默认的方法Run(),子类继承时获得了这个方法,子类也可
以覆写这个方法,但是这种方式会导致一个问题,就是无法动态辨析子类,调用合适的方法,如果
要加入多态特性的话,就要用到虚方法或抽象方法,这里这个Run()只是个示例,也许这样用并不合
适。
    现在回到正题,如果要给这个类层次体系统一填加一个方法,我们可以修改源代码,在基类中加
入一个抽象方法,子类来实现这个方法,但是这样违背了“开--闭原则”,所以这里引入了访问者
角色,不同的具体的访问者角色表示不同的行为,通过两次多态的动态辨析,为特定的子类填加了
特定的方法。当有新的行为要填加时,只需继承抽象访问者角色,建立一个新的具体的访问者类即
可。
    任何设计模式都不是万能的,设计模式是为了应对变化,封装变化。每一个论计模式都有自己适
用的情况,但没有万能的设计模式,我们总是假设什么是变的,什么是不变的,在项目设计初期,
我们要预计将来,什么变什么不变,从而进行良好的设计应对变化。
    在访问者模式里,我们把类层次结构看做不变的,而类层次结构的形为是多变的,如果类层次结
构变化的话,我们就要修改任何一个访问者类,这是我们所不想看到的