访问者模式:在不改变一个已存在的类的层次结构的情况下,为这个层次结构中的某些类定义一个新的操作,这个新的操作作用于(操作)已存在的类对象,也即新的操作需要访问被作用的对象。
一句话: 为一个稳定的类结构增加操作. 也即把易变化的类的行为搬到访问者中.
特点:
1 访问者角色(Visitor)作用于具体的元素执行相关的操作;
2 元素角色(Element)定义了accept方法接受一个访问者,并通过调用Visitor的方法执行操作;
3 对象结构角色(Object structure)容许访问者访问每个元素。
个人认为访问者模式是最复杂最难理解的模式。
基本代码:
再举一个例子,例子的来源于《大话设计模式》,作者试图从如下的几句话中抽象几个角色:
当男人成功时,背后多半有一个伟大的女人
当女人成功时,背后大多有一个不成功的男人
当男人失败时,闷头喝酒,谁也不用劝
当女人失败时,眼泪汪汪,谁劝也没用
当男人恋爱时,凡事不懂也装懂
当女人恋爱时,遇事懂也装不懂
。。。。
我们很容易写出这样的代码:
但是这样写出现了两个问题:
1 代码中有坏味道, if else充斥着整个方法体;
2 外部状态(成功,失败,恋爱,结婚....)是非稳定的因素, 他们可能随时会改变, 可能随时会增加, 如果增加了新的状态, 比如生病,升迁,当官等, 我们就得修改代码, 这就违背了开放封闭原则(关于开放封闭原则, 将在后面写blog解释).
因为人分两种, 男人, 女人, 这种类结构几乎不会发生变化, 而外在的状态(成功,失败,恋爱,结婚....)却可以随时改变, 所以我们用访问者模式来改进上面的代码:
再举一例,我们假设银行只有两种经典业务:存款,取款,这两种业务种类自从有银行开始都没有变过, 所以他们是稳定因素,然而随着时代的变迁,银行的客户却在逐渐细分,增加。过去有普通存款,取款类型, 公司存款取款类型,现在有了一些新的客户群,比如股票第三方存取款客户,代理基金业务客户等。而且银行在不断的开辟新的客户。 可以认为,银行的服务结构没有变,变的是外在的客户,可以用访问者模式。
优点:
对类结构增加新的操作很容易,只需要增加一个新的访问者。
缺点:
1 复杂
2 当数据结构或类发生变化的时候改动太大。
经典案例:
找ing。。。