版权声明:本文为博主原创文章,转载请注明出处 https://blog.csdn.net/qq_23934475/article/details/83176635
设计模式之访问者模式(Visitor)
本篇为 https://github.com/iluwatar/java-design-patterns/tree/master/visitor 阅读笔记
意图
主要将数据结构与数据操作分离。
关键代码
在数据基础类里面有一个方法接受访问者,将自身引用传入访问者。
优点
1、符合单一职责原则。
2、优秀的扩展性。
3、灵活性。
缺点
1、具体元素对访问者公布细节,违反了迪米特原则。
2、具体元素变更比较困难。
3、违反了依赖倒置原则,依赖了具体类,没有依赖抽象。
场景
指挥官,军官,士兵组成的军队了,每一等级可以接受其下属等级的问候
抽象军人
public abstract class Unit {
private Unit[] children;
public Unit(Unit... children) {
this.children = children;
}
public void accept(UnitVisitor visitor){
for (Unit child : children){
child.accept(visitor);
}
}
}
```指挥官
```java
public class Commander extends Unit {
public Commander(Unit... children) {
super(children);
}
@Override
public void accept(UnitVisitor visitor) {
visitor.visitCommander(this);
super.accept(visitor);
}
@Override
public String toString() {
return "Commander";
}
}
军官
public class Sergeant extends Unit {
public Sergeant(Unit... children) {
super(children);
}
@Override
public void accept(UnitVisitor visitor) {
visitor.visitSergeant(this);
super.accept(visitor);
}
@Override
public String toString() {
return "Sergeant";
}
}
士兵
public class Soldier extends Unit {
public Soldier(Unit... children) {
super(children);
}
@Override
public void accept(UnitVisitor visitor) {
visitor.visitSolder(this);
super.accept(visitor);
}
@Override
public String toString(){
return "soldier";
}
}
访问者接口
public interface UnitVisitor {
void visitSolder(Soldier soldier);
void visitSergeant(Sergeant sergeant);
void visitCommander(Commander commander);
}
指挥官访问者
public class CommanderVisitor implements UnitVisitor {
@Override
public void visitSolder(Soldier soldier) {
}
@Override
public void visitSergeant(Sergeant sergeant) {
}
@Override
public void visitCommander(Commander commander) {
System.out.println(MessageFormat.format("Greeting {0}", commander));
}
}
军官访问者
public class SergeantVisitor implements UnitVisitor {
@Override
public void visitSolder(Soldier soldier) {
}
@Override
public void visitSergeant(Sergeant sergeant) {
System.out.println(MessageFormat.format("Greeting {0}", sergeant));
}
@Override
public void visitCommander(Commander commander) {
}
}
士兵访问者
public class SoldierVisitor implements UnitVisitor {
@Override
public void visitSolder(Soldier soldier) {
System.out.println(MessageFormat.format("Greeting {0}", soldier));
}
@Override
public void visitSergeant(Sergeant sergeant) {
}
@Override
public void visitCommander(Commander commander) {
}
}
测试
@Test
public void visitorTest() {
Commander commander = new Commander(
new Sergeant(
new Soldier(),
new Soldier(),
new Soldier()),
new Sergeant(
new Soldier(),
new Soldier(),
new Soldier())
);
commander.accept(new SoldierVisitor());
commander.accept(new SergeantVisitor());
commander.accept(new CommanderVisitor());
}
关键部分代码为
@Override
public void accept(UnitVisitor visitor) {
//visitor.visitSolder(this);
//visitor.visitSergeant(this);
visitor.visitCommander(this);
super.accept(visitor);
}
父类的accept方法为
public void accept(UnitVisitor visitor){
for (Unit child : children){
child.accept(visitor);
}
}
在数据基础类里面有一个方法接受访问者,将自身引用传入访问者。