23种设计模式总览
创建型模式
结构型模式
- 外观模式(Facade)
- 适配器模式(Adapter)
- 代理模式(Proxy)
- 组合模式(Composite)
- 享元模式(Flyweight)
- 装饰模式(Decorator)
- 桥接模式(Bridge)
行为型模式
- 中介者模式(Mediator)
- 观察者模式(Observer)
- 命令模式(Command)
- 迭代器模式(Iterator)
- 模板方法模式(Template Method)
- 策略模式(Strategy)
- 状态模式(State)
- 备忘录模式(Memento)
- 解释器模式(Interpreter)
- 职责链模式(Chain of Responsibility)
- 访问者模式(Visitor)
定义
封装一些作用于某种数据结构中的各元素的操作,它可以在不改变这个数据结构的前提下,定义作用于这些元素的新操作。 主要将数据结构与数据操作分离。
优缺点
优点: 1、符合单一职责原则。 2、优秀的扩展性。 3、灵活性。
缺点: 1、具体元素对访问者公布细节,违反了迪米特原则。 2、具体元素变更比较困难。 3、违反了依赖倒置原则,依赖了具体类,没有依赖抽象。
使用场景
1、对象结构中对象对应的类很少改变,但经常需要在此对象结构上定义新的操作。
2、需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作"污染"这些对象的类,也不希望在增加新操作时修改这些类。
实现
我们可以通过生活中的一些例子来理解它,比如家里来了客人,客人就是访问者,他可以做一些事情,但是又不能做全部的事情; 又或者说去网吧上网的小明,小明也是访问者,他可以在网吧玩游戏、看视频、听音乐等等,但是不能破坏网吧中的设备等等。按照这么理解,我们大概就可以知道访问者模式主要是做什么了。
访问者模式主要由这五个角色组成,抽象访问者(Visitor)、具体访问者(ConcreteVisitor)、抽象节点(Node)、具体节点(ConcreteNode)和结构对象(ObjectStructure)。
- 抽象访问者(Visitor)角色:声明了一个或者多个方法操作,形成所有的具体访问者角色必须实现的接口。
- 具体访问者(ConcreteVisitor)角色:实现抽象访问者所声明的接口,也就是抽象访问者所声明的各个访问操作。
- 抽象节点(Node)角色:声明一个接受操作,接受一个访问者对象作为一个参数。
- 具体节点(ConcreteNode)角色:实现了抽象节点所规定的接受操作。
- 结构对象(ObjectStructure)角色:有如下的责任,可以遍历结构中的所有元素。
我们使用一个简单的示例来加以说明。 图书馆有一台电脑,但是只能玩游戏和看图片。张三和李四先后使用了这台电脑,那么他们就可以当作是访问者。 首先定义一个抽象的访问者,拥有玩游戏和看图片的方法;然后再定义一个抽象节点电脑,接受这个请求。
抽象访问者(Visitor)角色
//抽象访问者(Visitor)角色
interface Visitor {
//可以访问游戏
void visit(Games games);
//可以访问图片
void visit(Photos photos);
}
抽象节点(Node)角色
//抽象节点(Node)角色:声明一个接受操作,接受一个访问者对象作为一个参数。
interface Computer {
void accept(Visitor visitor);
}
具体节点(ConcreteNode)角色
//具体节点(ConcreteNode)角色:实现了抽象节点所规定的接受操作。
class Games implements Computer {
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
public String play() {
return "play Games";
}
}
//具体节点(ConcreteNode)角色:实现了抽象节点所规定的接受操作。
class Photos implements Computer {
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
public String watch() {
return "watch photos";
}
}
结构对象(ObjectStructure)角色
//结构对象(ObjectStructure)角色:有如下的责任,可以遍历结构中的所有元素。
class ObjectStructure {
private List<Computer> computers = new ArrayList<Computer>();
public void action(Visitor visitor) {
for (Computer c : computers) {
c.accept(visitor);
}
}
public void add(Computer computer) {
computers.add(computer);
}
}
验证结果
class Test {
public static void main(String[] args) {
// 创建一个结构对象
ObjectStructure os = new ObjectStructure();
// 给结构增加一个节点
os.add(new Games());
// 给结构增加一个节点
os.add(new Photos());
// 创建2个访问者
Visitor visitorZhangSan = new PersonVisitor("zhangsan");
Visitor visitorLisi = new PersonVisitor("lisi");
os.action(visitorZhangSan);
os.action(visitorLisi);
}
}
zhangsan-----play Games
zhangsan-----watch photos
lisi-----play Games
lisi-----watch photos