前言
简单工厂模式大家都会用, 它的主要作用就是把实例类隐藏起来, 提供一个接口类和一个工厂类. 这样不管有多少子类. 客户端只要知道两个类就行了.
但是客户端是直接调用生成的实例类属性和方法. 如果当实例类发生了改变, 那么可能会影响到客户端. 比如说接口的某个方法废弃了, 那么调用该方法的客户端就要改代码.
于是就有了策略模式的诞生, 策略模式就是我们在客户端和我们之间制造一个隔层. 我们对隔层提供统一的接口. 不管我们内部如何变化, 我们隔层提供的接口永远不变. 而我们只暴露给客户端这个接口. 那么我们就进一步实现了高内聚,低耦合.
实现
创建一个算法接口和三个算法实现
export interface IStragety{ getResult():void; }
export class StragetyA implements IStragety{ public getResult(){ console.log('使用算法A') } }
export class StragetyB implements IStragety{ public getResult(){ console.log('使用算法B') } }
export class StragetyC implements IStragety{ public getResult(){ console.log('使用算法C') } }
创建简单工厂+策略模式类
import { StragetyA, StragetyB, StragetyC, IStragety } from './stragety'
export class ContextAndFactory{ private stragety:IStragety=null;
constructor(name:string){ switch(name){ case 'A': this.stragety = new StragetyA(); break; case 'B': this.stragety = new StragetyB(); break; case 'C': this.stragety = new StragetyC(); break; } }
//对客户端暴露的接口方法, 永远不变 getResult(){ this.stragety.getResult() } }
测试
/**
- 简单工厂模式和策略模式组合
- 只暴露了一个ContextAndFactory类给客户端,耦合度1
- 当进行修改时, 不需要修改客户端, 只需要修改Context类中的方法.
- */ const testContextAndFactory = ()=>{ let context:ContextAndFactory = new ContextAndFactory('A') context.getResult() context = new ContextAndFactory('B') context.getResult() context = new ContextAndFactory('C') context.getResult() }
完整代码, 请点击我查看
总结
工厂模式: 只管生产实例,具体怎么使用工厂实例由调用方决定. 策略模式: 获取实例进行配置后才提供调用方使用。 简单工厂+ 策略模式: 生产实例, 并且对实例进行配置后提供调用方使用.
工厂模式调用方可以直接调用工厂实例的方法属性等,策略模式不能直接调用实例的方法属性,需要在策略类中封装策略后调用. 简单点说就是, 策略模式把变化封装起来, 提供给客户端统一的调用接口, 不管我们内部怎么变化, 调用我们的客户端不需要做任何调整. 也就是说加强了: 低耦合,高内聚.