创建型模式
工厂模式
在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
1 2 3
| const objectFactory = (name,age)=>{ return {name,age} }; const myObject = objectFactory('张三',18);
|
抽象工厂模式
抽象工厂模式(Abstract Factory Pattern)提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。
给工厂再抽象一层
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| function AbstractFactory(factoryType){ if(AbstractFactory[factoryType]){ return AbstractFactory[factoryType] }else{ throw new Error('没有当前类型的工厂') } }
AbstractFactory.childFactory1 = function(name){ return {name,type:'chidFactory1'} }
AbstractFactory.childFactory2 = function(name){ return {name,type:'chidFactory2'} }
let obj1 = AbstractFactory('childFactory1'); let obj2 = AbstractFactory('childFactory2');
|
原型模式
原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。例如,一个对象需要在一个高代价的数据库操作之后被创建。我们可以缓存该对象,在下一个请求时返回它的克隆,在需要的时候更新数据库,以此来减少数据库调用。
1 2 3 4 5 6 7
| function Person(){ this.property.name = '张三'; this.property.say = function(){return this.name} };
const zhangsan = new Person(); zhangsan.say();
|
单例模式
单例模式(Singleton Pattern)涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
该模式的特点:
单例类只能有一个实例。
单例类必须自己创建自己的唯一实例。
单例类必须给所有其他对象提供这一实例。
1 2 3 4 5 6 7 8 9 10 11 12 13
| let singleObject = null;
const createSingleObject = ()=>{ if(!singleObject) { signleObject = { } return singleObject; } let a = createSingleObject(); let b = createSingleObject();
|
结构型模式
桥接模式
桥接(Bridge)是用于把抽象化与实现化解耦,使得二者可以独立变化。这种模式涉及到一个作为桥接的接口,使得实体类的功能独立于接口实现类。这两种类型的类可被结构化改变而互不影响。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| class Color{ constructor(cl){this.color = cl}; draw(){ } class Speed{ constructor(v){this.v = v}; run(){ } class Speak{ constructor(word){this.word = word}; say(){ }
class Car(){ constructor(){ this.color = new Color('red'); this.speed = new Speed(10); } init(){ this.color.draw(); } } class Men(){ constructor(){ this.speed = new Speed(1); this.speak = new Speak('hello'); } init(){ this.speak.say(); } } const car = new Car(); const human = new Men();
|
外观模式
外观模式(Facade)为子系统中的一组接口提供了一个一致的界面,此模块定义了一个高层接口,这个接口值得这一子系统更加容易使用。
外观模式在JS中常常用于解决浏览器兼容性问题。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| class BigObject{ func1(){ } func2(){ } simpleFunc(){ if(xx) { func1()} else { func2() } } }
const obj = new BigObject(); obj.simpleFunc();
|
适配器模式
适配器模式(Adapter)是将一个类(对象)的接口(方法或属性)转化成客户希望的另外一个接口(方法或属性),适配器模式使得原本由于接口不兼容而不能一起工作的那些类(对象)可以一些工作。
1 2 3 4 5 6 7 8 9
| function old2New(oldObj){ return { newProperty:oldObj.oldProperty } } var oldObj = {xxx}
let newObj = old2New(oldObj)
|
代理模式
在代理模式(Proxy Pattern)中,一个类代表另一个类的功能。为其他对象提供一种代理以控制对这个对象的访问。
1 2 3 4
| let obj ={}
let proxyObj = new Proxy(obj,{})
|
行为型模式
观察者模式
观察者模式又叫发布订阅模式(Publish/Subscribe),它定义了一种一对多的关系,让多个观察者对象同时监听某一个主题对象,这个主题对象的状态发生变化时就会通知所有的观察者对象,使得它们能够自动更新自己。
使用观察者模式的好处:
- 支持简单的广播通信,自动通知所有已经订阅过的对象。
- 目标对象与观察者存在的是动态关联,增加了灵活性。
- 目标对象与观察者之间的抽象耦合关系能够单独扩展以及重用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| let publisher = { let _events=[];
addListen(func){ _events.push(fuc) }
removeListen(func){ _events=_events.filter(x=>x!=func) }
run(){ _events.foreach(t=>t();) } }
let f1 = ()=>{ let f2 = ()=>{ publisher.addListen(f1); publisher.addListen(f2); publisher.run();
|
策略模式
策略模式的定义是:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。
优点:策略模式的使用,避免过多的 if…else… 判断,也可以替代简单逻辑的 switch。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| const func = (type){ if(type==0){return '000'} else if(type==1){return '111'} else if(type==2){return '222'} }
const func =(type){ const _types={ 0:'000', 1:'111', 2:'222' } return _types[type] }
|