一、概念
- 在访问者模式(Visitor Pattern)中,我们使用了一个访问者类,它改变了元素类的执行算法。通过这种方式,元素的执行算法可以随着访问者改变而改变。这种类型的设计模式属于行为型模式。根据模式,元素对象已接受访问者对象,这样访问者对象就可以处理元素对象上的操作。
二、场景
- 对象结构中对象对应的类很少改变,但经常需要在此对象结构上定义新的操作。
- 需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作"污染"这些对象的类,也不希望在增加新操作时修改这些类。
三、实现
- 条件
- java
- 场景
- 以电商项目出订单报表为场景,实现访问者模式。
- 代码实现
- 新建业务抽象类,类名:AbstractVisitor
package com.VisitorPattern; import java.util.ArrayList; import java.util.List; /** * 业务抽象类 */ public abstract class AbstractVisitor { //报表集合类 protected List<IVisitor> list =new ArrayList<>(); //添加报表对象 public void Add(IVisitor visitor) { list.add(visitor); } }
- 新建配置类,类名:VisitorConfig
package com.VisitorPattern; /** * 配置类 */ public class VisitorConfig { //添加配置类 public void AddConfig(AbstractVisitor abstractVisitor) { abstractVisitor.Add(new ColumnarVisitor()); abstractVisitor.Add(new SectorVisitor()); } }
- 新建订单了类,类名:Order
package com.VisitorPattern; import java.util.ArrayList; import java.util.List; /** * 业务实现类 */ public class Order extends AbstractVisitor { //订单编号 public String orderNum; //创建报表 public void CreateReport () { list.forEach(o ->{ o.visitor(orderNum); }); } }
- 新建报表接口类,类名:IVisitor
package com.VisitorPattern; /** * 访问者接口类 */ public interface IVisitor { //生成报表 void visitor(String orderNum); }
- 新建柱状报表类,类名:ColumnarVisitor
package com.VisitorPattern; /** * 访问者实现类 */ public class ColumnarVisitor implements IVisitor { //生成报表类 @Override public void visitor(String orderNum) { System.out.println(orderNum+"生成柱状报表!"); } }
- 新建扇形报表类,类名:SectorVisitor
package com.VisitorPattern; /** * 访问者实现类 */ public class SectorVisitor implements IVisitor { //生成报表类 @Override public void visitor(String orderNum) { System.out.println(orderNum+"生成扇形报表!"); } }
- 入口函数类
Order order = new Order(); order.orderNum = "123112312"; //配置类 VisitorConfig visitorConfig = new VisitorConfig(); visitorConfig.AddConfig(order); order.CreateReport();
- 新建业务抽象类,类名:AbstractVisitor
四、优缺点
- 优点
- 符合单一职责原则。
- 优秀的扩展性。
- 灵活性。
- 缺点
- 具体元素对访问者公布细节,违反了迪米特原则 。
- 具体元素变更比较困难。
- 违反了依赖倒置原则,依赖了具体类,没有依赖抽象。