一个例子 - 看尽JS中的访问者模式

2019-08-26  本文已影响0人  Jason_Zeng
  1. 为什么要用访问者模式:在OOP中,我们用类来组织代码,类的属性我们当然在类内部获取,方法也在内部实现,使用就new一个类调用方法,但是当我们需要对类的数据进行很多与类定义不相关的操作的时候,这个时候我们又不想污染类的对象,因为这些操作引起的副作用可能根本与类无关,那么我们就应该把这些操作抽离出来单独封装,但是你抽离出来还是要用类的数据呀,怎么办呢,好了,所有类实现一个访问的接口,接受访问者,内部调用访问者的行为,但是具体这些行为干了什么,是访问者在外面实现的,就好像你作为一个访问者去拜访朋友家,朋友说你可以在我家做饭,用我家东西,但是具体怎么做是你的事,你朋友家并不关心,这样,换朋友来访问,同样也可以让他们做饭,但是做饭的方式就不一样了撒

  2. 访问者的目的: 主要将稳定的数据结构和易变的操作分开,方便扩展多变的操作方法而保持稳定的数据结构

  3. 访问者的实现: talk is cheap, show you the code

// 定义奖金的访问者,在js中简单的用一个函数模拟,
// 如果在c#等强类型语言中,需要声明一个接口,不同的visitor实现不同的计算奖金方法,
// 比如下面的管理者和开发者奖金不一样
function bonusVisitor(employee) {
  if (employee instanceof Manager)
    employee.bonus = employee.salary * 2;
  if (employee instanceof Developer)
    employee.bonus = employee.salary;
}

// 定义员工类,注意继承此类的必须都带有accept这个接受visitor的方法,
// 就是用来接待访问者,进而内部用访问者调用自己方法实现一些操作,
// 此例中直接调用函数visitor(this)
class Employee {

  constructor(salary) {
    this.bonus = 0;
    this.salary = salary;
  }

  accept(visitor) {
    visitor(this);
  }
}

// 管理者实现员工类
class Manager extends Employee {
  constructor(salary) {
    super(salary);
  }
}

// 开发者实现员工类
class Developer extends Employee {
  constructor(salary) {
    super(salary);
  }
}

测试代码

   // 管理员工集合
    let employees = [];

    // 不同的员工
    const john = new Developer(4000);
    const christian = new Manager(10000);

   // 放入员工集合中
    employees.push(john);
    employees.push(christian);

     // 分别接收访问者并调用
    employees.forEach(e => {
      e.accept(bonusVisitor);
    });

参考:
https://www.runoob.com/design-pattern/visitor-pattern.html
https://cnblogs.com/Terrylee/archive/2006/07/17/334911.html

上一篇下一篇

猜你喜欢

热点阅读