设计模式之------访问者模式(Visitor Pattern)

一、概念

①、什么是访问者模式?

        表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

②、访问者模式中例子为什么是男人、女人呢,与访问者是什么关联呢,谁是访问者,谁是被访问者?

        个人理解:我们将对象结构看成是一个“房间”,将男人女人实例化到对象结构中去,可以看做是在对象结构这个“屋子”中放入一个男人,一个女人,他(她)们的身份是被访问者。此时状态(成功)作为访问者进入房间后依次访问男人、女人并实现他们;随后状态(失败)也作为一个访问者去对象结构这个“房间”逐一访问男人、女人并实现他们。

③、主要解决什么问题?

        稳定的数据结构与易变的操作耦合问题。

④、如何解决?

        在被访问的类里面加一个对外提供接待访问者的接口。(例子中的对象结构就是这个接口)

⑤、应用实例?

       您在朋友家里做客,您是访问者,朋友接受您的访问,您通过朋友的描述,然后对朋友描述做出一个判断,这就是访问者模式。

⑥、使用场景?

       1、对象结构中对象对应的类很少改变,但经常需要在此对象结构上定义新的操作。

       2、需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作“污染”这些对象的类,也不希望在增加新操作时修改这些类。

⑦、优缺点?

优点: 

     1、符合单一职责原则。

     2、优秀的扩展性。

     3、灵活性。

缺点:

      1、具体元素对访问者公布细节,违反了迪米特原则。

      2、具体元素变更比较困难。

      3、违反了依赖倒置原则,依赖了具体类,没有依赖抽象。

二、图

①、结构图

②、拓展图

三、代码

①、代码类图

②、代码

客户端

 class Program
    {
        static void Main(string[] args)
        {                                                //创建对象结构,并向结构中添加具体类对象
            ObjectStructure o = new ObjectStructure();   //用对象结构类实例化一个o对象,创建一个集合,用来存放元素
            o.Attach(new Man());                         //调取对象结构的添加方法,添加一个Man类对象
            o.Attach(new Woman());                       //调取对象结构的添加方法,添加一个Woman类对象
            //状态类,成功时反应
            Success v1 = new Success();                  //实例化具体状态:成功类对象
            o.Display(v1);                               //调取对象结构的显示方法,把实例化的成功类对象作为参数传递过去
            Failing v2 = new Failing();
            o.Display(v2);
            Amativeness v3 = new Amativeness();
            o.Display(v3);

            Console.Read();
            
        }
    }

抽象人类

abstract class Person
    {
        public abstract void Accept(Action visitor);     //人类接受的抽象方法,接受的内容是什么,括号内的参数:状态
    }

具体“男人”类

 class Man:Person
    {
        public override void Accept(Action visitor)
        {
            visitor.GetManConclusion(this);
        }
    }

具体“女人”类

    class Woman:Person
    {
        public override void Accept(Action visitor)
        {
            visitor.GetWomanConclusion(this);
        }
    }

抽象状态类

 abstract class Action
    {
        public abstract void GetManConclusion(Man concreteElementA);
        public abstract void GetWomanConclusion(Woman  concreteElementB);
    }

具体状态成功类

    class Success:Action
    {
        public override void GetManConclusion(Man concreteElementA)
        {
            Console.WriteLine("{0}{1}时,背后多半有一个伟大的女人。", concreteElementA.GetType().Name, this.GetType().Name);
        }
        public override void GetWomanConclusion(Woman concreteElementB)
        {
            Console.WriteLine("{0}{1}时,背后大多有一个不成功的男人。", concreteElementB.GetType().Name, this.GetType().Name);
        }
    }

具体状态失败类

    //失败状态
    class Failing:Action
    {
        public override void GetManConclusion(Man concreteElementA)
        {
            Console.WriteLine("{0}{1}时,闷头喝酒,谁也不用劝。", concreteElementA.GetType().Name, this.GetType().Name);
        }
        public override void GetWomanConclusion(Woman concreteElementB)
        {
            Console.WriteLine("{0}{1}时,眼泪汪汪,谁也劝不了。",concreteElementB.GetType().Name,this.GetType().Name );
        }
    }

具体状态恋爱类

class Amativeness :Action
    {
        public override void GetManConclusion(Man concreteElementA)
        {
            Console.WriteLine("{0}{1}时,凡是不懂也要装懂。",concreteElementA.GetType().Name,this.GetType().Name);
        }
        public override void GetWomanConclusion(Woman concreteElementB)
        {
            Console.WriteLine("{0}{1}时,遇事懂也装做不懂。",concreteElementB.GetType().Name,this.GetType().Name);
        }
    }

 对象结构类

class ObjectStructure
    {
        private IList<Person> elements = new List<Person>();
         //增加
        public void Attach(Person element)               //创建一个增加方法
        {
            elements.Add(element);                       //增加的参数为元素,即人类
        }
        //移除
        public void Detach(Person element)
        {
            elements.Remove(element);
        }
        //查看显示
        public void Display(Action visitor)
        {
            foreach (Person e in elements)
            {
                e.Accept(visitor);
            }
        }
    }

四、拓展

https://www.cnblogs.com/edisonchou/p/7247990.html

 

 

评论 24
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Elsa~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值