学习而来,代码是自己敲的。也有些自己的理解在里边,有问题希望大家指出。

行为型模式,我之所以把他放到第一个,是因为它号称是GoF中最难的一个。

 

模式的定义与特点

      在访问者模式中(Visitor Pattern)中,我们使用了一个访问者类,他改变了元素类的执行算法。通过这种方式,元素的执行算法可以随着访问者改变而改变。根据访问者模式,元素对象已接受访问者对象,这样访问者对象就可以处理元素对象上的操作。

模式的优点

  • 符合单一职责原则。
  • 拥有优秀的扩展性。
  • 非常灵活。

模式的缺点

  • 具体元素对访问者公布细节,违反了迪米特法则。
  • 具体元素变更比较困难。
  • 依赖了具体类,没有依赖抽象,这违反了依赖倒置原则。

举例使用场景

      说在某个厨师交流会上,有三个人一拍即合要开餐馆。这三个人分别是一个老板、一个中国厨师、一个西方厨师。餐馆开起来后客人络绎不绝,但两位厨师用的没油了,提出要加服务员跑腿。老板不同意啊,多一个人就得多开钱啊,于是让两位厨师自行解决。并且说不管是这次的油,还是之后还有别的需求都让两个厨师自己解决。

分析故事:永远只有三个人,所有事情都需要两个厨师自己解决

想到的解决办法:

  • 更改厨师类,新增获取油或者是其他需求时,进行类的扩展,这样不符合开闭原则
  • 抽象厨师类,每次有新的需求时新增一个厨师就行,这样看似符合开闭原则,且解决了问题,但题目内容本身,是不允许新增员工的。
  • 被制作的东西告诉厨师:"1、你需要做我。2、我是你怎么做出来的 ",然后厨师做出了这个东西。这样之后厨师需要做什么,原有代码都不需要修改,只需要增加被生产的内容类即可。这样符合开闭原则,也完美的解决了问题。

根据题目与结论得出,应该有俩厨师类一个被生产类

俩厨师类来做东西(访问者),通过访问者:“1:告知厨师类需求做出自己,2:告知厨师类怎么制作自己”。

internal class Program {
    static void Main(string[] args) {
        List<Cooker> cookers = new List<Cooker>() {           //获取所有厨师
            new ChineseChef(),
            new WesternChef(),
        }; 
        Visitor meat = new MeatVisitor();         //获取肉类访问者
        Visitor oil = new GetOilVisitor();        //获取油类访问者
        for (int i = cookers.Count - 1; i >= 0; i--) {
            //cookers[i].Cooking(meat);              //告诉厨师需要做什么内容(肉)
            cookers[i].Cooking(oil);              //告诉厨师需要做什么内容(油)
        }
        Console.ReadLine();
    }
}
//===================================================================================================
internal abstract class Cooker {        //厨师抽象类
    public string Name;                 //厨师
    public abstract void Cooking(Visitor visitors);    //抽象出做东西    参数:做的内容(访问者)
}
internal class ChineseChef : Cooker {
    public override void Cooking(Visitor visitors) {
        Name = "中国厨师";
        visitors.Chinesechef(this);                    //告诉访问者,现在是中国厨师在做
    }
}
internal class WesternChef : Cooker {
    public override void Cooking(Visitor visitors){
        Name = "西方厨师";
        visitors.Westernchef(this);                    //告诉访问者,现在是西方厨师在做
    }
}
//===================================================================================================
internal abstract class Visitor {       //访问者类抽象
    public abstract void Chinesechef(Cooker cookers);    //抽象出  中国厨师怎么做自己
    public abstract void Westernchef(Cooker cookers);    //抽象出  西方厨师怎么做自己
}
internal class MeatVisitor : Visitor {        //定义访问者自身为肉
    public override void Chinesechef(Cooker cookers) {    //告诉中国厨师自己怎么做
        Console.WriteLine($"{cookers.Name}认为,肉 要煮的吃");
        //Console.WriteLine("中国厨师认为,肉 要煮的吃");
    }
    public override void Westernchef(Cooker cookers) {    //告诉西方厨师自己怎么做
        Console.WriteLine($"{cookers.Name}认为,肉 要煎的吃");
        //Console.WriteLine("西方厨师认为,肉 要煎的吃");
    }
}
internal class GetOilVisitor : Visitor {
    public override void Chinesechef(Cooker cookers) {
        Console.WriteLine($"{cookers.Name}认为,油 可以通过肉炼出来");
        //Console.WriteLine("中国厨师认为,油 可以通过肉炼出来");
    }
    public override void Westernchef(Cooker cookers) {
        Console.WriteLine($"{cookers.Name}认为,油 应该去超市买");
        //Console.WriteLine("西方厨师认为,油 应该去超市买");
    }
}


 

希望大家:点赞,留言,关注咯~    
????????????????

唠家常

        今日分享结束啦,小伙伴们你们get到了么,你们有没有更好的办法呢,可以评论区留言分享,也可以加QQ:841298494,大家一起进步。

  • 客官,看完get之后记得点赞哟!
  • 小伙伴你还想要别的知识?好的呀,分享给你们????

今日推荐