在设计模式中,有这样一个模式,它提供一个访问者类,这个访问者类可以更改我们目标对象类的执行算法,它将数据结构与数据操作解耦。
访问者模式简介
- 访问者模式属于行为型模式
- 访问者模式提供一个访问者类可以随意更改目标的执行算法
访问者模式的优缺点
访问者模式的优点
- 访问者模式符合设计模式原则之一的单一职责原则
- 访问者模式具有高可拓展性和高弹性
访问者模式的缺点
- 因为访问的具体目标对访问者类提供了具体的细节,违反了迪米特原则和依赖倒置原则。对于新手小白想更轻松的学好Java提升,Java架构,web开发、大数据,数据分析,人工智能等技术,这里给大家分享系统教学资源,扩列下我尉(同英):CGMX9880 【教程/工具/方法/解疑】
- 修改具体目标改动不易
访问者模式的结构
访问者模式主要分为抽象访问者(Visitor)、具体访问者(ConcreteVisitor)、抽象目标(target)、具体目标(ConcreteTarget)和对象结构(ObjectStructure)五种角色,以结构来看,访问者模式相对于其余的设计模式是相对复杂一点的。
抽象访问者(Visitor):定义了一个访问元素的具体接口。
具体访问者(ConcreteVisitor):所有的具体访问者都必须实现抽象访问者,并实现访问操作。
抽象目标(target):声明了一个接收操作的接口。
具体目标(ConcreteTarget):实现了抽象目标和一些业务相关逻辑。
对象结构(ObjectStructure):包含了具体目标的容器。
Java实现访问者模式
定义目标对象
- Target
public interface Hello { void say(Visitor visitor);}
- ConcreteTarget…
public class ChineseHello implements Hello
{
@Override public void say(Visitor visitor)
{
visitor.visit(this);
}
}
public class EnglishHello implements Hello
{
@Override public void say(Visitor visitor)
{
visitor.visit(this);
}
}
- ObjectStructure
public class StructureHello implements Hello {
Hello[] hello;
{
hello = new Hello[]{new EnglishHello(), new ChineseHello()};
}
@Override
public void say(Visitor visitor)
{
Arrays.stream(hello).forEach(h -> h.say(visitor));
visitor.visit(this);
}
}
定义访问者对象
- 抽象访问者(Visitor)
public interface Visitor
{
void visit(EnglishHello hello);
void visit(ChineseHello hello);
void visit(StructureHello hello);
}
- 具体访问者(ConcreteVisitor)
public class ConcreteVisitor implements Visitor
{
@Override public void visit(EnglishHello hello)
{
System.err.println("Hello world!");
}
@Override public void visit(ChineseHello hello)
{
System.err.println("你好世界!");
}
@Override
public void visit(StructureHello hello)
{
System.err.println("我是对象容器hello");
}
}
定义测试类喝运行结果
- 测试类
public class Test
{
public static void main(String[] args)
{
Hello hello = new StructureHello();
hello.say(new ConcreteVisitor());
}
}
- 运行结果
在上面举的例子中我们的目标对象接受一个参数是访问者,访问者接受一个参数是目标,我们目标里面没写别的业务,只是简单的将逻辑交给了访问者处理,其中StructureHello类对象就是对象结构容器角色了。由此,我们便实现了一个简单的访问者模式了。
访问者模式适用于对象里面有很多不同的操作,但是我们不希望这些操作全部写在一起,且不希望在新增或者修改的时候去修改原目标对象。