白话-23种设计模式21-访客者模式
【摘要】 一、白话 访客者模式就是,访客和被访者以及组合角色三者之间的一个封装。访客者需要有访问接口,被访客者需要有被访问接口,组合角色需要有所有访客访问被访者的组合。还是比较绕,我看过最形象的比喻就是:人喂动物。人就是访客,动物是被访者。人可以有丈夫,妻子,动物可以有猫、狗。这里就能形成四种组合,这四种方式封装起来就是组合角色(结构角色)。这样就完成了访客者模式,丈夫去喂动物或者妻子喂动物的时候,...
一、白话
访客者模式就是,访客和被访者以及组合角色三者之间的一个封装。访客者需要有访问接口,被访客者需要有被访问接口,组合角色需要有所有访客访问被访者的组合。还是比较绕,我看过最形象的比喻就是:人喂动物。人就是访客,动物是被访者。人可以有丈夫,妻子,动物可以有猫、狗。这里就能形成四种组合,这四种方式封装起来就是组合角色(结构角色)。这样就完成了访客者模式,丈夫去喂动物或者妻子喂动物的时候,就能有不同的表现。而不用去改内部结构。
二、定义
元素的执行算法可以随着访问者改变而改变。
- Visitor是抽象访问者:为该对象结构中的ConcreteElement的每一个类声明一个visit操作
- ConcreteVisitor具体访问者:是一个具体的访问值实现每个有Visitor声明的操作,是每个操作实现的部分
- ObjectStructure结构对象:能枚举它的元素,可以提供一个高层的接口,用来允许访问者访问元素
- Element抽象元素:定义一个accept 方法,接收一个访问者对象
- ConcreteElement具体元素:实现了accept方法
三、示例
// 抽象元素-定义被访问接口
public interface Animal {
public void accept(Person person);
}
// 具体元素-实现被访问细节
public class Cat implements Animal {
@Override
public void accept(Person person) {
// 重点:具体细节交给了访问者,被访问者接受了访客访问,把自己交给了访客,访客来访问被访者
person.visit(this);
}
}
// 具体元素-实现被访问细节
public class Dog implements Animal {
@Override
public void accept(Person person) {
// 重点:具体细节交给了访问者,被访问者接受了访客访问,把自己交给了访客,访客来访问被访者
person.visit(this);
}
}
// 抽象访问者-定义访问接口
public interface Person {
public void visit(Animal animal);
}
// 具体访问者-实现访问细节
public class Husband implements Person {
// 这里就是定义细节,实现不同访客访问出现不同的细节
@Override
public void visit(Animal animal) {
System.out.println("丈夫,总是会给很多食物");
if (animal instanceof Cat) {
System.out.println("猫咪很开心,喵喵");
} else {
System.out.println("小狗很开心,旺旺");
}
}
// 具体访问者-实现访问细节
public class Wife implements Person {
// 这里就是定义细节,实现不同访客访问出现不同的细节
@Override
public void visit(Animal animal) {
System.out.println("妻子,总是会给很少食物");
if (animal instanceof Cat) {
System.out.println("猫咪很难过,呜呜");
} else {
System.out.println("小狗很难过,呜呜");
}
}
}
// 结构对象-拥有所有元素,实现所有元素被访问的场景
public class Home {
// 定义所有对象, 不一定非得是集合,多个单独存在的对象也是可以的
private List<Animal> animals = new ArrayList<>();
// 结构对象-定义访问者访问被访者 接口
public void action(Person person) {
for (Animal animal : animals) {
animal.accept(person);
}
}
// 新增元素
public void add(Animal animal) {
animals.add(animal);
}
}
public class VisitorApplication {
// 客户端调用
public static void main(String[] args) {
// 新增结构对象
Home home = new Home();
// 添加元素
home.add(new Dog());
home.add(new Cat());
// 定义访问者
Person husband = new Husband();
Person wife = new Wife();
// 开启访问
home.action(husband);
home.action(wife);
}
}
输出示例:
丈夫,总是会给很多食物
小狗很开心,旺旺
丈夫,总是会给很多食物
猫咪很开心,喵喵
妻子,总是会给很少食物
小狗很难过,呜呜
妻子,总是会给很少食物
猫咪很难过,呜呜
四、总结
特点:1、符合单一职责原则。 2、优秀的扩展性。 3、灵活性。4、具体元素变更比较困难。 5、违反了依赖倒置原则,依赖了具体类,没有依赖抽象。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)