访问者模式
- 概述:表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作.
- 访问者模式所包含的角色
- Visitor : 抽象访问者角色.为该对象结构中具体元素角色声明一个访问操作接口.该操作接口的名字和参数标识了发送访问请求给具体访问者的具体元素角色.这样访问者就可以通过该元素角色的特定接口直接访问它.
- ConcreteVisit : 具体访问者角色.实现Visit声明的接口
- Element : 元素角色.定义一个Accept操作.它以一个访问者对象为参数
- Concrete : 具体元素角色.实现由元素角色提供的Accept操作
- ObjectStructure : 对象结果角色.这是使用访问者模式所必备的角色.它具备以下特征:
- 能枚举它的元素
- 可以提供一个高层的接口以允许该访问者访问它的元素
- 可以是一个复合(组合模式) 或是一个集合
- 使用场景
- 不同的子类,依赖于不同的其它对象
- 需要对一组对象进行许多不相关的操作,但是不想在类中实现这些方法
- 定义的类很少改变,但是执行的操作却经常变化
- 优点
- 符合单一职责原则 : 凡是适用访问者模式的场景中,元素类中需要封装在访问者中的操作必定是与元素类本身关系不大并且易变的操作.使用访问者模式一方面符合单一职责原则.另一方面,因为被封装的操作通常来说都是易变的.所以当发生变化时,就可以在不改变元素类本身的前提下,实现对该变化部分的扩展
- 扩展性良好 : 元素类可以通过不同的访问者来实现对不同操作的扩展
- 缺点
- 具体元素对访问者公布细节,违反了迪米特原则
- 具体元素变更比较困难
- 违反了依赖倒置原则,依赖了实体类,没有依赖对象
代码实现
示例: 现在一直使用CSDN来记录自己的技术学习,现在CSDN有web端和手机端,都可以用来阅读CSDN中的文章,现在根据文章,博客,阅读者这几个概念使用访问者模式来实现这一场景.
抽象访问者类
package VisitorPattern;
/**
* Created by looper on 2017/8/25.
*/
public interface Visitor {
public void visit(ComputerElement computerElement);
public void visit(WapElement wapElement);
}
具体访问者类
package VisitorPattern;
/**
* Created by looper on 2017/8/25.
*/
public class ConcreteVisitor implements Visitor {
@Override
public void visit(ComputerElement computerElement) {
computerElement.accept(this);
}
@Override
public void visit(WapElement wapElement) {
wapElement.accept(this);
}
}
抽象元素类
package VisitorPattern;
/**
* Created by looper on 2017/8/25.
*/
public abstract class Element {
public abstract void accept(Visitor visitor);
}
具体元素类1(使用电脑)
package VisitorPattern;
/**
* Created by looper on 2017/8/25.
*/
public class ComputerElement extends Element {
@Override
public void accept(Visitor visitor) {
System.out.println("使用电脑登录CSDN查看博客");
}
}
具体元素类2(使用手机)
package VisitorPattern;
/**
* Created by looper on 2017/8/25.
*/
public class WapElement extends Element{
@Override
public void accept(Visitor visitor) {
System.out.println("使用手机登录CSDN查看博客");
}
}
对象结果类
package VisitorPattern;
import java.util.ArrayList;
import java.util.List;
/**
* Created by looper on 2017/8/25.
*/
public class ObjectStruture {
public static List<Element> getList(){
List<Element> elementList = new ArrayList<>();
elementList.add(new ComputerElement());
elementList.add(new WapElement());
return elementList;
}
}
测试类
package VisitorPattern;
import java.util.List;
/**
* Created by looper on 2017/8/25.
*/
public class VisitorPatternTest {
public static void main(String[] args) {
List<Element> elementList = ObjectStruture.getList();
for (Element element : elementList) {
element.accept(new ConcreteVisitor());
}
}
}
我将23种设计模式的全部代码上传到CSDN,有用得到的同学 可以去下载.
下载地址 : 点我