Software Construction Series(4)

​ 在进行Coding时,常常遇到这样一种情况:设计的ADT,将来可能要扩展某些操作,但根据OCP原则,不应当修改已经实现的代码,所以需要提前留下扩展手段。设计模式中的Visitor模式就是契合这样一种设计理念的方法。

先看它的UML模型:


模型看起来有些复杂,不妨先明确几个概念:

Visitor模式的实质

1、封装一些数据结构的各元素操作,降低操作间的耦合性。

2、将数据结构和数据操作解耦,使得易于扩展。


Visitor模式角色分工

1、Visitor: 抽象访问者, 在重载的visit方法中声明可以访问的对象

2、Concrete Visitor: 实现访问者对一个具体元素的操作

3、Element: 抽象元素, 提供重载的accpet方法(意义在于赋予访问权限,提高安全性)

4、Concrete Element: 实现accept方法

5、Object structure: 容纳多个Element



Attention: Visitor模式的基本流程是Element是ADT,但不希望在其中实现一些操作(因为与本身关联度低),所以留了一个后门(accept方法),可以让特定的类获得它本身,从而进行相应的操作。特定的类同时需要有相应的进入后门的办法(visit方法),才能实现。

一个例子:

统计学生中男女生各自的数量

abstract class Student {
  ...
  public abstract void accept(Visitor visitor);
  ...
}

class MaleStudent {
  ...
  @Override
  public void accept(Visitor visitor) {
    visitor.visit(this);
  }
}

class FemaleStudent {
  ...
  @Override
  public void accept(Visitor visitor) {
    visitor.visit(this);
  }
}

interface Visitor {
  public void visit(MaleStudent ms);
  public void visit(FemaleStudent fs);
}

class CountVisitor implements Visitor {
  private int male = 0;
  private int female = 0;
  
  @Override 
  public void visit(MaleStudent ms) {
    male++;
  }
  
  public void visit(FemaleStudent fs) {
    female++;
  }
}

public class Main {
  public static void main(String[] args) {
  ArrayList<Student> list = new ArrayList<>();
  
  MaleStudent a = ...;
  FeMaleStudent b = ...;
  
  list.add(a);
  list.add(b);
  
  Visitor v = new CountVisitor();
  for (Student s : list) {
    s.accept(v);
  }
  }
}




优缺点:

1、优点:将操作与数据分离,防止新操作污染原ADT的一致性。易于扩展。

2、缺点:visitor模式依赖具体实现(Visitor根据Student具体的类型决定哪个方法),违背了DIP(依赖倒置原则)。

猜你喜欢

转载自www.cnblogs.com/KarlZhang/p/9135916.html