day26 行为型:模版、策略和状态模式有什么区别?

小玄儿
• 阅读 730

策略模型类的行为模式

策略模式:核心思想是在运行时基于场景选择策略。
下面,我们可以通过一个红绿灯程序来看一下这一概念的实现。在这个例子中,我们可以看到 交通控制(TrafficControl)就决定了运行时环境的上下文,它可以通过转换( turn )这个方法来切换不同的策略。红绿灯(TrafficLight)是一个抽象类的策略,它可以根据环境需要,延伸出具体类的策略。

// encapsulation
class TrafficControl {
  turn(trafficlight) {
    return trafficlight.trafficcolor();
  }
}

class TrafficLight {
  trafficcolor() {
    return this.colorDesc;
  }
}

// strategy 1
class RedLight extends TrafficLight {
  constructor() {
    super();
    this.colorDesc = "Stop";
  }
}

// strategy 2
class YellowLight extends TrafficLight {
  constructor() {
    super();
    this.colorDesc = "Wait";
  }
}

// strategy 3
class GreenLight extends TrafficLight {
  constructor() {
    super();
    this.colorDesc = "Go";
  }
}

// usage
var trafficControl = new TrafficControl();

console.log(trafficControl.turn(new RedLight())); // Stop
console.log(trafficControl.turn(new YellowLight())); // Wait
console.log(trafficControl.turn(new GreenLight())); // Go

状态模式:它的核心概念是根据运行时状态的不同,切换不同的策略。算是策略模式的一个延伸。
酒店预定的订单状态例子:
day26  行为型:模版、策略和状态模式有什么区别?
同样,我们可以通过讲策略模式时的红绿灯案例做一些改造,加入状态 state,看看会发生什么。这里,我们可以看到每次当我们执行 turn 在做切换的时候,随着状态在红、黄、绿三种状态之间循环更新,红绿灯的指示也跟着更新。

class TrafficControl {
  constructor() {
    this.states = [new GreenLight(), new RedLight(), new YellowLight()];
    this.current = this.states[0];
  }
  turn() {
    const totalStates = this.states.length;
    let currentIndex = this.states.findIndex(light => light === this.current);
    if (currentIndex + 1 < totalStates) this.current = this.states[currentIndex + 1];
    else this.current = this.states[0];
  }
  desc() {
    return this.current.desc();
  }
}

class TrafficLight {
  constructor(light) {
    this.light = light;
  }
}

class RedLight extends TrafficLight {
  constructor() {
    super('red');
  }
  desc() {
    return 'Stop';
  }
}

class YellowLight extends TrafficLight {
  constructor() {
    super('yellow');
  }
  desc() {
    return 'Wait';
  }
}

class GreenLight extends TrafficLight {
  constructor() {
    super('green');
  }
  desc() {
    return 'Go';
  }
}

// usage
var trafficControl = new TrafficControl();
console.log(trafficControl.desc()); // 'Go'
trafficControl.turn();
console.log(trafficControl.desc()); // 'Stop'
trafficControl.turn();
console.log(trafficControl.desc()); // 'Wait'

模版模式:它的核心思想是在一个方法中定义一个业务逻辑模版,并将某些步骤推迟到子类中实现。所以它和策略模式有些类似。
day26  行为型:模版、策略和状态模式有什么区别?
下面我们可以看一个实现的例子。在这个例子里,我们看到员工 employee 里的工作 work 就是一个模版,它里面的任务 tasks 是延迟到开发 developer 和设计 designer 两个子类中去实现的。这就是一个简单的模版模式的设计实现。

class Employee {
  constructor(name, salary) {
  this.name = name;
  this.salary = salary;
  }
  work() {
    return `${this.name}负责${this.tasks()}`;
  }
  getPaid() {
    return `${this.name}薪资是${this.salary}`;
  }
}

class Developer extends Employee {
  constructor(name, salary) {
    super(name, salary);
  }
  // 细节由子类实现
  tasks() {
    return '写代码';
  }
}

class Designer extends Employee {
  constructor(name, salary) {
    super(name, salary);
  }
  // 细节由子类实现
  tasks() {
    return '做设计';
  }
}

// usage
var dev = new Developer('张三', 10000);
console.log(dev.getPaid()); // '张三薪资是10000'
console.log(dev.work()); // '张三负责写代码'
var designer = new Designer('李四', 11000);
console.log(designer.getPaid()); // '李四薪资是11000'
console.log(designer.work()); // '李四负责做设计'

无论是策略、状态还是模版模式,它们都是基于某种“策略模型”来实现的。比如策略模式中的策略是基于上行文来切换;在状态模式中是根据状态来做切换;而最后在模版模式的例子中,某些策略模版在父类中定义,有些则在子类中实现。

信息传递类的行为模式

中介模式:核心是使组件可以通过一个中心点相互交互。
现实生活中,航空地面塔台就是一个例子,我们不可能让飞机之间交谈,而是通过地面控制台协调。地面塔台人员需要确保所有飞机都接收到安全飞行所需的信息,而不会撞到其他飞机。
day26  行为型:模版、策略和状态模式有什么区别?
看一下代码的示例,塔台(TrafficTower)有着接收每架飞机坐标和获取某架飞机坐标方法。同时,飞机会登记自己的坐标和获取其它飞机的坐标。这些信息都是统一由塔台(TrafficTower)来管理的。

class TrafficTower {
  #airplanes;
  constructor() {
    this.#airplanes = [];
  }

  register(airplane) {
    this.#airplanes.push(airplane);
    airplane.register(this);
  }

  requestCoordinates(airplane) {
    return this.#airplanes.filter(plane => airplane !== plane).map(plane => plane.coordinates);
  }
}

class Airplane {
  constructor(coordinates) {
    this.coordinates = coordinates;
    this.trafficTower = null;
  }

  register(trafficTower) {
    this.trafficTower = trafficTower;
  }

  requestCoordinates() {
    if (this.trafficTower) return this.trafficTower.requestCoordinates(this);
    return null;
  }
}

// usage
var tower = new TrafficTower();

var airplanes = [new Airplane(10), new Airplane(20), new Airplane(30)];
airplanes.forEach(airplane => {
  tower.register(airplane);
});

console.log(airplanes.map(airplane => airplane.requestCoordinates())) 
// [[20, 30], [10, 30], [10, 20]]

命令模式:允许我们将命令和发起命令操作的对象分离,这么做的好处是对于处理具有特定生命周期或者列队执行的命令,它会给我们更多的控制权。并且它还提供了将方法调用作为传参的能力,这样做的好处是可以让方法按需执行。
day26  行为型:模版、策略和状态模式有什么区别?
举个例子,事务管理者 OperationManager 接到了执行任务,会根据不同的命令,如启动行动(StartOperationCommand)、追踪行动状态(TrackOperationCommand)及取消行动 CancelOperationCommand 等来执行。

class OperationManager {
  constructor() {
    this.operations = [];
  }

  execute(command, ...args) {
    return command.execute(this.operations, ...args);
  }
}

class Command {
  constructor(execute) {
    this.execute = execute;
  }
}

function StartOperationCommand(operation, id) {
  return new Command(operations => {
    operations.push(id);
    console.log(`你成功的启动了${operation}行动,代号${id}`);
  });
}

function CancelOperationCommand(id) {
  return new Command(operations => {
    operations = operations.filter(operation => operation.id !== id);
    console.log(`你取消了行动代号${id}`);
  });
}

function TrackOperationCommand(id) {
  return new Command(() =>
    console.log(`你的行动代号${id},目前正在执行中`)
  );
}

var manager = new OperationManager();

manager.execute(new StartOperationCommand("猎豹", "318"));
// 返回:你成功的启动了猎豹行动,代号318
manager.execute(new TrackOperationCommand("318"));
// 返回:你的行动代号318,目前正在执行中
manager.execute(new CancelOperationCommand("318"));
// 返回:你取消了行动代号318

命令模式可以在许多不同的情况下使用,特别是在创建重交互的 UI 上,比如编辑器里撤消的操作,因为它可以让 UI 对象和行为操作做到高度解耦。也可以用来代替回调函数,这也是因为它更支持模块化地将行为操作在对象之间传递。
职责链模式:核心是将请求的发送者和接收者解耦。
它的实现是通过一个对象链,链中的每个对象都可以处理请求或将其传递给下一个对象。
事件的捕获和冒泡就是采用这种方式;jQuery也是职责链每次返回一个对象来实现链式调用。
day26  行为型:模版、策略和状态模式有什么区别?
简单示例:

class CumulativeSum {
  constructor(intialValue = 0) {
    this.sum = intialValue;
  }

  add(value) {
    this.sum += value;
    return this;
  }
}

// usage
var sum = new CumulativeSum();
console.log(sum.add(10).add(2).add(50).sum); // 62

中介模式中,我们需要在网状的环境中,信息对多个对象中通过中介进行传输;命令模式中,我们看到了信息在对象和对象之间的传输;而最后,在职责链的模式中,我们又看到了信息在一个流水线中的传输。因此我说它们是偏向“数据传递”的设计模式。

此文章为2月Day5学习笔记,内容来源于极客时间《Jvascript进阶实战课》,大家共同进步💪💪
点赞
收藏
评论区
推荐文章
美凌格栋栋酱 美凌格栋栋酱
6个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Easter79 Easter79
3年前
spring中策略模式使用
策略模式工作中经常使用到策略模式工厂模式,实现一个接口多种实现的灵活调用与后续代码的扩展性。在spring中使用策略模式更为简单,所有的bean均为spring容器管理,只需获取该接口的所有实现类即可。下面以事件处理功能为例,接收到事件之后,根据事件类型调用不同的实现接口去处理。如需新增事件,只需扩展实现类即可,无需改动之前的代码。这样即
Stella981 Stella981
3年前
Hystrix实现ThreadLocal上下文的传递 转
springcloud微服务中,服务间传输全局类参数,如session信息等。一、问题背景Hystrix有2个隔离策略:THREAD以及SEMAPHORE,当隔离策略为THREAD时,是没办法拿到ThreadLocal中的值的。Hystrix提供了基于信号量和线程两种隔离模式,通过在Hystrix基础章节中已经验证过,通过
Stella981 Stella981
3年前
JavaScript面向对象编程的15种设计模式
在程序设计中有很多实用的设计模式,而其中大部分语言的实现都是基于“类”。在JavaScript中并没有类这种概念,面向对象编程不是基于类,而是基于原型去面向对象编程,JS中的函数属于一等对象,而基于JS中闭包与弱类型等特性,在实现一些设计模式的方式上与众不同。ps:本文之讲述面向对象编程的设计模式策略,JavaScript原型的基础请参考阮一峰面向
Wesley13 Wesley13
3年前
Java 设计模式系列(十二)策略模式(Strategy)
Java设计模式系列(十二)策略模式(Strategy)策略模式属于对象的行为模式。其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。一、策略模式的结构策略模式是对算
Wesley13 Wesley13
3年前
如何利用策略模式避免冗长的 if
策略模式。在实际的项目开发中,这个模式也比较常用。最常见的应用场景是,利用它来避免冗长的ifelse或switch分支判断。不过,它的作用还不止如此。它也可以像模板模式那样,提供框架的扩展点等等。对于策略模式。本篇我们讲解策略模式的原理和实现,以及如何用它来避免分支判断逻辑。后续我会通过一个具体的例子,来详细讲解策略模式的应用场景以及真正的设计意图
京东云开发者 京东云开发者
1个月前
设计模式-策略模式
作者:京东工业孙磊一、概念策略模式(StrategyPattern)也称为(PolicyParttern)。它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变换,不会影响到使用算法的客户。策略模式属性行为模式。策略模式结构图\二、实际
设计模式之策略模式:让你的代码灵活应对不同的算法 | 京东云技术团队
作为一个程序员,我们经常会面临着在不同的情况下选择不同的算法来解决问题的需求。这种情况下,策略模式是一个非常有用的设计模式。在本文中,我将向你介绍策略模式的概念、结构以及如何应用这个模式来使你的代码更灵活。
融云IM即时通讯 融云IM即时通讯
8个月前
融云IM干货丨IM聊天室中客户端如何确保消息同步的准确性?
客户端确保消息同步的准确性主要依赖于以下几个关键技术和策略:全局唯一的消息ID生成策略:为了保证消息可以通过ID进行识别和排重,IM系统采用全局唯一的消息ID生成策略。这种策略可以确保每条消息都有一个唯一的标识符,从而在消息的发送和接收过程中避免重复。客户
京东云开发者 京东云开发者
6个月前
设计模式-策略模式
作者:京东工业孙磊一、概念策略模式(StrategyPattern)也称为(PolicyParttern)。它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变换,不会影响到使用算法的客户。策略模式属性行为模式。策略模式结构图\二、实际
京东云开发者 京东云开发者
2个月前
设计模式-策略模式
作者:京东工业孙磊一、概念策略模式(StrategyPattern)也称为(PolicyParttern)。它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变换,不会影响到使用算法的客户。策略模式属性行为模式。策略模式结构图\二、实际