访问者模式(Visitor)
表示一个作用于对象结构中的各元素的操作。它使你可以不在改变各元素的类的前提下定义作用于这些元素的新操作。
在GoF23种设计模式中,属于行为型模式( Behavioral Patterns)
。
访问者模式可以在不改变类的前提下,对访问类进行加工处理。从而可以将访问的数据结构跟访问操作进行分离,提高系统拓展性。
- 优点
- 便于访问者(数据操作)的增加与修改
- 解耦了访问者(数据操作)与访问对象(数据结构)的关系
- 缺点
- 不利于访问对象(数据结构)的修改
- 使用场景
- 在不改变对象的前提下,需要对一个对象进行许多不相关的操作
实例
角色说明
- Visitor
- 访问者接口
- 定义每一个具体元素的访问操作
- ConcreteVisitor
- 具体访问者
- 实现具体访问操作
- Element
- 访问对象接口
- ConcreteElement
- 具体访问对象
- ObjectStructure
- 枚举访问对象
- Client
- 调用方
举例
普通人和专业人士到电影院看同一部电影,却看到了不一样的内容。
角色说明
- Visitor(Visitor)
- 观众
- NormalVisitor(ConcreteVisitor)
- 普通观众
- ProfessionalVisitor(ConcreteVisitor)
- 专业影评人
- Movie(Element)
- 电影
- Avatar(ConcreteElement)
- 阿凡达
- ToyStory(ConcreteElement)
- 玩具总动员
- Cinema(ObjectStructure)
- 电影院
code
- Movie.java
public interface Movie {
void accept(Visitor visitor);
}
- Avatar.java
public class Avatar implements Movie {
private String name = "阿凡达";
private String content = "一部精彩的科幻片";
private String meaning = "开辟了科幻电影的新纪元";
public String getName() {
return name;
}
public String getContent() {
return content;
}
public String getMeaning() {
return meaning;
}
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
- ToyStory.java
public class ToyStory implements Movie {
private String name = "玩具总动员";
private String content = "一部搞笑真挚感人的动画片";
private String meaning = "是第一部全靠CG制作的电影";
public String getName() {
return name;
}
public String getContent() {
return content;
}
public String getMeaning() {
return meaning;
}
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
- Cinema.java
public class Cinema {
private List<Movie> movieList;
public Cinema(List<Movie> movieList) {
this.movieList = movieList;
}
public void accept(Visitor visitor) {
for (Movie movie : movieList) {
movie.accept(visitor);
}
}
}
- Visitor.java
public interface Visitor {
void visit(ToyStory toyStory);
void visit(Avatar avatar);
}
- NormalVisitor.java
public class NormalVisitor implements Visitor {
@Override
public void visit(ToyStory toyStory) {
System.out.println("《" + toyStory.getName() + "》这是" + toyStory.getContent());
}
@Override
public void visit(Avatar avatar) {
System.out.println("《" + avatar.getName() + "》这是" + avatar.getContent());
}
}
- ProfessionalVisitor.java
public class ProfessionalVisitor implements Visitor {
@Override
public void visit(ToyStory toyStory) {
System.out.println("《" + toyStory.getName() + "》这是" + toyStory.getContent() + "。并且它还" + toyStory.getMeaning());
}
@Override
public void visit(Avatar avatar) {
System.out.println("《" + avatar.getName() + "》这是" + avatar.getContent() + "。并且它还" + avatar.getMeaning());
}
}
- Client.java
public class Client {
public static void main(String[] args) {
Cinema cinema = new Cinema(Lists.newArrayList(new Avatar(), new ToyStory()));
System.out.println("普通人看电影:");
cinema.accept(new NormalVisitor());
System.out.println("\n专业人士看电影:");
cinema.accept(new ProfessionalVisitor());
}
}
- output
普通人看电影:
《阿凡达》这是一部精彩的科幻片
《玩具总动员》这是一部搞笑真挚感人的动画片
专业人士看电影:
《阿凡达》这是一部精彩的科幻片。并且它还开辟了科幻电影的新纪元
《玩具总动员》这是一部搞笑真挚感人的动画片。并且它还是第一部全靠CG制作的电影
实例
code:org.springframework.beans.factory.config.BeanDefinitionVisitor
角色说明
- BeanDefinitionVisitor(visitor)
- StringValueResolver(Element)
总结
访问者模式可以在不改变对象的前提下,对对象内容进行多种不相关的数据操作。
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名,转载请标明出处
最后编辑时间为:
2019-12-22