JAVA设计模式之访问者模式

来源:互联网 发布:vscode terminal 编辑:程序博客网 时间:2024/05/29 19:57

定义:封装某些作用于某种数据结构中各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作。(通俗点就是说在不修改原对象行为方法的情况下为该方法增加新的行为操作)

类型:行为类模式


简单来说,访问者模式就是一种分离对象数据结构与行为的方法,通过这种分离,可达到为一个被访问者动态添加新的操作而无需做其它的修改的效果。以上图为例的代码实现场景:

publicinterface Visitor {publicvoid visit(Subject sub);}publicclass MyVisitor implements Visitor {@Overridepublicvoid visit(Subject sub) {System.out.println("visit the subject:"+sub.getSubject());}}publicinterface Subject {publicvoid accept(Visitor visitor);public String getSubject();}publicclass MySubject implements Subject {@Overridepublicvoid accept(Visitor visitor) {visitor.visit(this);}@Overridepublic String getSubject() {return"love";}}publicclass Test {publicstaticvoid main(String[] args) {Visitor visitor = new MyVisitor();Subject sub = new MySubject();sub.accept(visitor);}}
输出:visit the subject:love



以上图为例,下面我们就来说一下访问者模式的通用实现,通过类图可以看到,在访问者模式中,主要包括下面几个角色:

  • 抽象访问者:抽象类或者接口,声明访问者可以访问哪些元素,具体到程序中就是visit方法中的参数定义哪些对象是可以被访问的。

  • 访问者:实现抽象访问者所声明的方法,它影响到访问者访问到一个类后该干什么,要做什么事情。

  • 抽象元素类:接口或者抽象类,声明接受哪一类访问者访问,程序上是通过accept方法中的参数来定义的。抽象元素一般有两类方法,一部分是本身的业务逻辑,另外就是允许接收哪类访问者来访问。

  • 元素类:实现抽象元素类所声明的accept方法,通常都是visitor.visit(this),基本上已经形成一种定式了。

  • 结构对象:一个元素的容器,一般包含一个容纳多个不同类、不同接口的容器,如List、Set、Map等,在项目中一般很少抽象出这个角色。


abstractclass Element {publicabstractvoid accept(IVisitor visitor);publicabstractvoid doSomething();}interface IVisitor {publicvoid visit(ConcreteElement1 el1);publicvoid visit(ConcreteElement2 el2);}class ConcreteElement1 extends Element {publicvoid doSomething(){System.out.println("这是元素1");}publicvoid accept(IVisitor visitor) {visitor.visit(this);}}class ConcreteElement2 extends Element {publicvoid doSomething(){System.out.println("这是元素2");}publicvoid accept(IVisitor visitor) {visitor.visit(this);}}class Visitor implements IVisitor {publicvoid visit(ConcreteElement1 el1) {el1.doSomething();}publicvoid visit(ConcreteElement2 el2) {el2.doSomething();}}class ObjectStruture {publicstatic List<Element> getList(){List<Element> list = new ArrayList<Element>();Random ran = new Random();for(int i=0; i<10; i++){int a = ran.nextInt(100);if(a>50){list.add(new ConcreteElement1());}else{list.add(new ConcreteElement2());}}return list;}}publicclass Client {publicstaticvoid main(String[] args){List<Element> list = ObjectStruture.getList();for(Element e: list){e.accept(new Visitor());}}}


总结:

该模式适用场景:如果我们想为一个现有的类增加新功能,不得不考虑几个事情:1、新功能会不会与现有功能出现兼容性问题?2、以后会不会再需要添加?3、如果类不允许修改代码怎么办?面对这些问题,最好的解决方法就是使用访问者模式,访问者模式适用于数据结构相对稳定的系统,把数据结构和算法解耦.


原创粉丝点击