设计模式的分类
我们都知道有 23 种设计模式,这 23 种设计模式可分为如下三类:
设计模式系列文章传送门
设计模式的 7 大原则
设计模式–单例模式【创建型模式】
设计模式–工厂方法模式【创建型模式】
设计模式–抽象工厂模式【创建型模式】
设计模式–建造者模式【创建型模式】
设计模式–原型模式【创建型模式】
设计模式–适配器模式【结构型模式】
设计模式–装饰器模式【结构型模式】
设计模式–代理模式【结构型模式】
设计模式–外观模式(门面模式)【结构型模式】
设计模式–桥接模式【结构型模式】
设计模式–组合模式【结构型模式】
设计模式–享元模式【结构型模式】
设计模式–策略模式【行为型模式】
设计模式–模板方法模式【行为型模式】
设计模式–观察者模式【行为型模式】
设计模式–迭代器模式【行为型模式】
设计模式–责任链模式【行为型模式】
设计模式–命令模式【行为型模式】
设计模式–备忘录模式【行为型模式】
设计模式–状态模式【行为型模式】
什么是访问者模式
访问者模式(Visitor Pattern)是一种行为型设计模式,通过定义一个访问者对象,实现对数据结构中各个元素进行访问和处理,访问者模式可以将数据结构与数据操作分离,使得在增加新的操作时,不需要修改现有的数据结构相关的类。
访问者模式的组成部分
访问者模式模式在生活中其实是有很多场景的,比如我们开一家早餐店,其中粉、面、粥、包子是各种不同的餐食,顾客可以根据自己的喜好选择餐食,这里的顾客就是访问者,而不同的食物则可以看做是元素,根据顾客的选择来提供不同的食物,下面我们使用代码来演示这个场景。
Food(抽象元素)
Food 食物就是本案例中的抽象元素,定义了一个接受访问者访问的方法,代码如下:
public interface Food {
//接受访问的方法
void accept(Customer customer);
}
Pink(具体元素)
Pink 粉就是具体食物,也是一种具体的元素,实现了抽象元素 Food 接口,并重写了访问方法,将自身传递给访问者,并提供了一个制作粉的方法,代码如下:
public class Pink implements Food {
@Override
public void accept(Customer customer) {
//将 粉 元素传递给访问者
customer.visit(this);
}
//制作粉
public void makePink() {
System.out.println("我是一份广东炒粉...");
}
}
Noodle(具体元素)
Noodle 面也是具体食物,同样是一种具体的元素,实现了抽象元素 Food 接口,并重写了访问方法,将自身传递给访问者,并提供了一个制作面的方法,代码如下:
public class Noodle implements Food {
@Override
public void accept(Customer customer) {
customer.visit(this);
}
//制作面
public void makeNoodle() {
System.out.println("我是一份重庆小面...");
}
}
Bun(具体元素)
Bun 包子也具体食物,也是一种具体的元素,实现了抽象元素 Food 接口,并重写了访问方法,将自身传递给访问者,并提供了一个制作包子的方法,代码如下:
public class Bun implements Food {
@Override
public void accept(Customer customer) {
customer.visit(this);
}
//制作包子
public void makeBun() {
System.out.println("我是一份上海小笼包...");
}
}
Customer(访问者)
Customer 访问者,在本案例中顾客就是一个访问者,访问者中定义了粉、面、包子的访问方法,代码如下:
public interface Customer {
//粉
void visit(Pink pink);
//面
void visit(Noodle noodle);
//包子
void visit(Bun bun);
}
SpecificCustomer(具体访问者)
SpecificCustomer 是一个具体访问者,重写了 Customer 中的粉、面、包子的访问方法,代码如下:
public class SpecificCustomer implements Customer{
@Override
public void visit(Pink pink) {
System.out.println("后厨,小王要了一份广东炒粉...安排起来");
pink.makePink();
}
@Override
public void visit(Noodle noodle) {
System.out.println("后厨,小李要了一份重庆小面...安排起来");
noodle.makeNoodle();
}
@Override
public void visit(Bun bun) {
System.out.println("后厨,小美要了一份上海小笼包...安排起来");
bun.makeBun();
}
}
FoodCollection(对象结构)
FoodCollection 就是本案例中的对象结构,FoodCollection 中有一个 List 容器,存储了 Food 食物,并提供了添加食物和访问食物的方法,代码如下:
public class FoodCollection {
List<Food> foodList = new ArrayList<>();
public void addFood(Food food){
foodList.add(food);
}
public void accept(Customer customer){
for (Food food : foodList) {
food.accept(customer);
}
}
}
VisitorClient(客户端代码)
三位顾客分别要了不同的食物,代码如下:
public class VisitorClient {
public static void main(String[] args) {
//对象结构
FoodCollection foodCollection = new FoodCollection();
//粉--元素
Pink pink = new Pink();
//面--元素
Noodle noodle = new Noodle();
//包子--元素
Bun bun = new Bun();
//添加到数据集合中
foodCollection.addFood(pink);
foodCollection.addFood(noodle);
foodCollection.addFood(bun);
//具体访问者
SpecificCustomer customer = new SpecificCustomer();
//开始访问
foodCollection.accept(customer);
}
}
执行结果如下:
后厨,小王要了一份广东炒粉...安排起来
我是一份广东炒粉...
后厨,小李要了一份重庆小面...安排起来
我是一份重庆小面...
后厨,小美要了一份上海小笼包...安排起来
我是一份上海小笼包...
执行结果符合预期。
访问者模式的优缺点
优点:
缺点:
访问者模式的使用场景
总结:本篇分享了访问者模式设计模式,感觉访问者设计模式还是有一点复杂的感觉,它除了元素和访问者之外还有一个对象结构的概念,我们使用餐厅有有不同餐食的场景演示了访问者模式,希望可以帮助不太熟悉访问者模式的朋友加深理解。
如有不正确的地方欢迎各位指出纠正。