zoukankan      html  css  js  c++  java
  • 访问者模式

    场景:部队招人时的面试官以及工厂招人的面试官是visitor,被面试的男人和女人是被访问的Element,

    要点:

    1. 抽象的Person(又叫Element)里有个accept(visitor)函数,该函数里调用了visitor.visit(this)。

    2. 抽象的Visitor(抽象面试官)里分别定义了visit(Man)和visit(Women)两个抽象方法。方法名相同,但参数不同,应该叫做重载吧。

    3. 具体的ConcreteVisitor(例如ArmyVisitor和FactoryVisitor)根据自己的逻辑对visit(Man)和visit(Women)进行了实现。这个没啥。

    下面这个UML图我觉得不标准,Visitor应该有虚线的依赖具体的Main和Woman,而抽象的Person应该有虚线的依赖接口Visitor

    有几个疑问,为什么不能在使用程序里(比如Main()函数)直接调用visitor.visit(man),而非要通过man.accept(visitor)来绕一圈呢?有啥好处?

    ---------分割线以下的是我后来想明白了补充的-----------------------------------------------------------------------

    如果你用的语言支持函数重载,那么就像我的疑问里提的,完全可以直接在使用程序里直接调用visitor.visit(man),没必要用访问者模式,用了也没啥好处,反而降低了代码的可读性。

    但是有一些语言不支持函数重载(像C,python,javascript),这种情况下的访问者模式就不能像上面那么写了。应该咋写呢?看下图

    区别只有一点,对于不支持函数重载的语言,visitor只能定义不同的函数名来访问不同的具体Element了。(支持重载的语言里,visitor是通过相同的函数名传入不同的具体Element参数,通过函数重载实现的。)

    这时候,有这么一种场景:有一个person的list,list里有多个对象(男人1,男人2,女人1,女人2,男人3,男人4,男人5,女人3……)。

    如果不使用访问者模式,遍历访问list的时候,应该对list里的每个元素先判断一下是男人还是女人,如果是男人则调用visitor.visitMan(),是女人则调用visitor.visitWoman()。总之比较麻烦啦。

    而用了访问者模式了呢?只需要对list里的persion们挨个调用一下persion.accept(visitor)即可。

    最后总结一下不适用场景

    1. 被访问的Element可以有多个具体实例,但Element的子类必须是固定的。

    如果不是固定的,时不时多加个子类,那么没添加一个子类,Visitor就必须要添加一个visit函数,并且visitor所有的子类也要跟着修改。太麻烦了。

    打个比方,比如在Man和Woman的基础上又添加个机器人,那么Visitor接口就必须要添加一个visit(Robot)函数,并且ArmyVisitor和FactoryVisitor也要实现这个函数。如果还有其他的visitor改的更多。

  • 相关阅读:
    JAVA实现微信支付功能
    avue设置表格显示图片
    职工管理系统----删除职工
    职工管理系统---显示职工
    职工管理系统---读文件
    职工管理系统---写文件
    职工管理系统-------添加职工
    职工管理系统-----实现职工类
    职工管理系统-------实现退出功能
    职工管理系统-------菜单功能
  • 原文地址:https://www.cnblogs.com/james6176/p/4448825.html
Copyright © 2011-2022 走看看