设计模式(一)
零、原则
S – Single Responsibility Principle 单一职责原则
- 一个程序只做好一件事
- 如果功能过于复杂就拆分开,每个部分保持独立
O – OpenClosed Principle 开放/封闭原则
- 对扩展开放,对修改封闭
- 增加需求时,扩展新代码,而非修改已有代码
L – Liskov Substitution Principle 里氏替换原则
- 子类能覆盖父类
- 父类能出现的地方子类就能出现
I – Interface Segregation Principle 接口隔离原则
- 保持接口的单一独立
- 类似单一职责原则,这里更关注接口
D – Dependency Inversion Principle 依赖倒转原则
- 面向接口编程,依赖于抽象而不依赖于具体
- 使用方只关注接口而不关注具体类的实现
一、工厂模式
创建对象,使一个类的实例化延迟到了子类内。
模式作用:
- 对象的构建十分复杂。
- 需要依赖具体的环境创建不同实例。
- 处理大量具有相同属性的小对象。
注意事项:
- 不能滥用工厂,有时候仅仅是给代码增加复杂度。
示例:
// 简单工厂 class Apple { phone(){ console.log('iPhone'); } } class SAMSUNG { phone(){ console.log('Galaxy'); } } class Factory { create(type){ // 复杂操作 let obj = null; switch (type) { case 'Apple': obj = new Apple(); break; case 'SAMSUNG': obj = new SAMSUNG(); break; default: new Error('No type!'); } return obj; } } let factory = new Factory() let phone1 = factory.create('Apple'); let phone2 = factory.create('SAMSUNG'); phone1.phone(); // iPhone phone2.phone(); // Galaxy // 或者直接添加在工厂类上添加方法 class Apple { phone(){ console.log('iPhone'); } } class SAMSUNG { phone(){ console.log('Galaxy'); } } class Factory { } Factory.create = function(type){ let obj = null; switch (type) { case 'Apple': obj = new Apple(); break; case 'SAMSUNG': obj = new SAMSUNG(); break; default: new Error('No type!'); } return obj; } let phone1 = Factory.create('Apple'); let phone2 = Factory.create('SAMSUNG'); phone1.phone(); // iPhone phone2.phone(); // Galaxy
拓展:抽象的来说,工厂可以根据类型来生产产品,或是在子类中覆盖或添加其他的东西。
二、单例模式
保证一个类仅有一个实例,并提供一个访问它的全局访问点。
模式作用:
一个单一对象,比如弹窗,无论点击多少次,弹窗只应该被创建一次。
示例:
class CreateUser { constructor(name) { this.name = name; this.getName(); } getName() { return this.name; } } // 代理实现单例模式 var ProxyMode = (function() { var instance = null; return function(name) { if(!instance) { instance = new CreateUser(name); } return instance; } })(); // 测试单体模式的实例 var a = new ProxyMode("aaa"); var b = new ProxyMode("bbb"); // 因为单体模式是只实例化一次,所以下面的实例是相等的 console.log(a === b); //true // ************************************************ class LoginForm { constructor() { this.state = 'hide' } show() { if (this.state === 'show') { alert('已经显示') return } this.state = 'show' console.log('登录框显示成功') } hide() { if (this.state === 'hide') { alert('已经隐藏') return } this.state = 'hide' console.log('登录框隐藏成功') } } LoginForm.getInstance = (function () { let instance return function () { if (!instance) { instance = new LoginForm() } return instance } })() let obj1 = LoginForm.getInstance() obj1.show() let obj2 = LoginForm.getInstance() obj2.hide() console.log(obj1 === obj2)
三、策略模式
第一个部分是一组策略类(可变),策略类封装了具体的算法,并负责具体的计算过程。第二个部分是环境类(不变),接受客户的请求,随后将请求委托给某一个策略类。
作用:
- 将实现和使用分开。
- 避免多重条件选择语句。
- 符合开放-封闭原则,将算法封装在独立的策略中,使得它们易于切换、扩展。
示例:
/*策略类*/ var levelOBJ = { "A": function(money) { return money * 4; }, "B" : function(money) { return money * 3; }, "C" : function(money) { return money * 2; } }; /*环境类*/ var calculateBouns =function(level,money) { return levelOBJ[level](money); }; console.log(calculateBouns('A',10000)); // 40000
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!