设计模式:是实战设计经验的总结。能够让我们,站在巨人的肩膀上,构建项目代码。
设计原则:
- 开闭原则:对扩展开放,对修改关闭。(PS:高考试卷)
- 里氏代换原则:子类继承父类,单独调用可以独立运行。(PS :盗版光盘。)
- 依赖倒转原则:引用一个对象,如果这个对象有底层类,直接引用底层。(PS:三个和尚抬水,也可以直接从井里打水)
- 接口隔离原则:每一个接口应该是一种角色(PS:汽车点烟器接口)
- 合成/聚合复用原则:新对象应使用一些已有的对象,使之成为新对象的一部分。(PS:利用手里有一些相机零件,制造新相机)
- 迪米特原则:一个对象应该对其他对象有尽可能少的了解。(PS:现实种男女的对象)
工厂模式
概念:定义一个用于创建对象的接口,由子类决定设立化哪个类。类的实例化延迟到了子类。而子类可以重写接口方法,以便创建的时候指定自己的对象类型(抽象工厂)
常用举例:尤其是创建对象流程赋值时,如依赖于很多设置文件等。
作用:
- 对象的构建十分复杂。
- 需要依赖具体的环境创建不同的实例
- 处理大量具有相同属性的小对象
先复习一下,JS 的继承写法
简单工厂
抽象工厂
单例模式
作用
- 模块间通信
- 系统某个类的实例只能存在一个
- 保护自己的属性和方法
注意
- 闭包是 变量作用域的链式提升123456789101112131415161718192021222324252627//1.独立对象 xiaowang ,xiaoli//2.让xiaowang和xiaoli 通过门铃通信//3.先看xiaowang家有没有门,无门建门,然后通过门铃“叮咚”$(document).ready(function(){var xiaowang = (function(){var men = null;var info = {receiveMessage : function(msg){if(!men){men = {};}men.menling = msg;console.log(`xiaowang men.menling : ${men.menling} ` );return men.menling;}};return info;})();var xiaoli = {callXiaowang:function(msg){xiaowang.receiveMessage(msg);}};xiaoli.callXiaowang("叮咚");});
|
|
构造函数模式
如下例,常和单例模式配合使用
代理模式
为其他对象提供一种代理以控制对这个对象的访问。
作用
- 远程代理
- 虚拟代理
- 安全代理
- 智能代理12345678910111213141516171819$(document).ready(function(){var HouseOwner = function(buyer){this.buyer = buyer;this.sellHouse = function(money){console.info(`买家:${this.buyer.name} ,房价:${money}`);}};var Agency = function(){};Agency.prototype.trade = function() {var ho = new HouseOwner(new Buyer('小明'));ho.sellHouse('200万')};var Buyer = function(name){this.name = name || "anonym"};new Agency().trade();});
建造者模式
用途:
- 分步创建一个复杂的对象
- 解耦封装过程和具体创建的组件
- 无需关系组件如何组装12345678910111213141516171819202122232425262728293031323334$(document).ready(function(){function House(){this.kitchen = "";this.bedroom = "";this.livingroom ="";}function Headman(){this.buildHouse = function(worker){worker.buildbedroom();worker.buildKitchen();worker.buildLivingroom();var house = new House();house.kitchen = "finish";house.bedroom = "finish";house.livingroom = "finish";return house;}}function Worker(){this.buildKitchen = function(){console.info("kitchen ok!");}this.buildbedroom = function(){console.info("bedroom ok!");}this.buildLivingroom = function(){console.info("livingroom ok!");}}var headman = new Headman();var house = headman.buildHouse(new Worker());console.log(house);});
命令模式
作用:
- 将函数的封装、请求、调用结合为一体。
- 调用具体函数解耦命令对象雨接收对象。
- 提高程序模块化的灵活性。
注意:
- 不需要接口一致,直接调用函数即可,以免浪费。
|
|
观察者模式
(又名发布订阅模式 publish / subscrib)
定义了一种一对多的关系,让多个观察者对象同时监听某一主题对象,这个主题对象的状态发生变化时,就会通知所有的观察者对象,使他们能够自己更新自己。
作用
- 支持简单的广播通信,自动通知所有已经订阅过的对象。
- 页面载入后目标对象很容易与观察者存在一种动态关联,增加了灵活性。
- 目标对象与观察者之间的抽象耦合关系能够单独扩展以及重用。
版本一
根据jQuery1.7版新增的on/off功能,我们也可以定义jQuery版的观察者:
总结
观察者的使用场合就是:当一个对象的改变需要同时改变其它对象,并且它不知道具体有多少对象需要改变的时候,就应该考虑使用观察者模式。
总的来说,观察者模式所做的工作就是在解耦,让耦合的双方都依赖于抽象,而不是依赖于具体。从而使得各自的变化都不会影响到另一边的变化。
参考资料
适配器模式
|
|
职责链模式
|
|
迭代器模式
作用:
- 为遍历不同的集合结构提供一个统一的接口。从而支持同样的算法,在不同的集合结构上进行操作
- 对集合内部结果常常变化各异,我们不想暴露其内部结构的化,但又想让客户代码透明访问其中的元素。
注:
- 一般迭代,至少要又两个方法 hasNext(),next(),这样才可以遍历所有对象
- 遍历的同时更改迭代器所在的集合结构可能会导致问题(比如c# 的foreach 里不允许修改item)
|
|
外观模式
又称:Facade (门面模式)。
作用
- 在设计初期,应该要有意识地将不同地两个层分离,比如经典地三层结构
- 在开发阶段,子系统往往因为不断地重构演化而变得越来越复杂,增加外观Facade,可以提供一个简单的接口,减少他们之间的依赖。
- 在维护一个遗留的大型系统时,为系统开发一个Facade类,为设计粗糙和高度复杂的遗留代码提供较清晰的接口,让新系统和Facade交互。
注意
- 外观模式被连续开发时,会产生一定的性能问题,因为在每次调用时,都要检测功能的可行性。
例1:12345678910111213141516`use strict`var fuhao = {};fuhao.huofang = function(){return "馒头";};fuhao.chuliliangshi = function(){return "面粉";};fuhao.mantou = function(){this.chuliliangshi();this.huofang();}//人们想拿到馒头,第一个需要做的就是让系统产生馒头fuhao.facade = function(){return this.mantou();};
例2:
策略模式
作用:
- 所有的这些算法都是做相同的事情,只是实现不同。
- 以相同的方式调用所有的方法,减少了各种算法与使用算法之间的耦合
- 单独定义算法类,也方便了单元测试
注意: - 不仅可以用来封装算法,也可以用来封装几乎任何类型的规则。123456789101112131415161718192021222324252627282930313233343536`use strict`$(document).ready(function(){var input = $("#ipt_tel");$.fn.validate = function(option){var ret = true;for(key in option){if('isEmpty' === key){console.log("isEmpty = " + isEmpty());ret = (isEmpty() === option[key]) && ret;}if('isNum' === key){console.log("isNum " + isNum() );ret =(isNum() === option[key]) && ret;}}function isEmpty(){var ret = false;if(!input.val()){ret = true;}return ret;}function isNum(){var reg = /[0-9]+/;return reg.test(input.val());}return ret;}$('#btn_a').click(function(e){var result = input.validate({isEmpty:false,isNum : true});console.info(result);});});
中介者模式
用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显示地相互引用,从而使其耦合松散,而且可以对立的改变他们之间的交互。
原型模式
|
|
使用Object.create() 来实现面向对象继承,避免执行两次构造函数
模板模式
|
|
装饰模式
|
|
组合模式
|
|