设计模式
前言:
什么叫设计模式?所谓的设计模式是一套经过反复使用、多人知晓的、经过分类的、代码设计经验的总结,说白了就是一些人们约定俗成的东西即潜规则。
为什么要学设计模式?
在团队协作中,为了代码的重用性,也为了别人能够看懂你的代码,使代码的编写更加的工程化
设计模式有哪些?(了解)
构造器模式,模块化模式,暴露模块模式,单例模式,中介者模式,原型模式,命令模式,外观模式,工厂模式,Mixin模式,装饰模式,亨元(Flyweight)模式,MVC模式,MVP模式,MVVM模式,组合模式,适配器模式,外观模式,观察者模式,迭代器模式,惰性初始模式,代理模式,建造者模式
一、单例模式:
单例模式,只有一个对象,即便是多次创建,也要返回同一个对象,这就叫单例模式。
function fn(){
if(!fn.obj) { //给函数添加一个属性。
//因为函数是全局的,所以该属性一旦添加一直存在;
fn.obj = {
name : “liyang"
};
}
return fn.obj;
}
var obj1 = new fn();
var obj2 = new fn();
console.log(obj1 == obj2);
二、组合模式
把多个对象组成树状结构来表示局部与整体,使得用户可以同时操作单个对象和对象的组合。
function ImageItem( src ){
this.element = document.createElement("img");
this.element.src = src;
this.element.className = "img-item";
}
ImageItem.prototype = {
constructor:ImageItem,
add:function( child ){
console.log("this is image object, no add function");
},
remove:function( child ){
console.log("this is image object, no remove function");
},
show:function(){
this.element.style.border = "solid 2px black";
},
hide:function(){
this.element.style.border = 'none';
},
getElement:function(){
return this.element;
}
}
使用组合模式组织起来的对象具有出色的层次结构,每当对顶层组合对象执行一个操作的时候,实际上是在对整个结构进行深度优先的节点搜索。但是这些优点都是用操作的代价换取的,比如每次顶级执行一次show方法,实际的操作就是整个树形结构的节点都会被遍历一次。但是组合对象的每个对象之间的耦合非常松散,可以简单的操作处理复杂的结果。
三、观察者模式
观察者模式又叫发布订阅模式(Publish/Subscribe),它定义了一种一对多的关系,让多个观察者对象同时监听某一个主题对象,这个主题对象的状态发生变化时就会通知所有的观察者对象,使得它们能够自动更新自己。
class myEvent{
constructor(){
// 消息盒子
this.message = {
}
}
on(type, cb){
if(this.message[type]){
this.message[type].push(cb)
}else{
this.message[type] = [cb]
}
}
off(type, cb){
if(!this.message[type]) return;
for(var i=0;i<this.message[type].length;i++){
if(this.message[type][i] === cb){
this.message[type].splice(i, 1)
break;
}
}
}
emit(type){
if(!this.message[type]) return;
for(var i=0;i<this.message[type].length;i++){
this.message[type][i]()
}
}
}
var me = new myEvent();
me.on("a",fn1)
function fn1(){
console.log("a事件的事件处理函数1被触发了")
}
me.on("a",fn2)
function fn2(){
console.log("a事件事件处理函数2被触发了")
}
me.on("a",fn3)
function fn3(){
console.log("a事件事件处理函数3被触发了")
}
me.off("a", fn2)
me.emit("a")
console.log(me.message)
四、代理模式
代理模式分成两个部分,一个部分是本体; 即为你想要实现的功能;另一部分为代理;代理可以代替本体实例化;
代理一般使用在非常耗时的数据上,也会用在体积十分庞大的本体上。
一句话总结代理模式:为其他对象提供代理,以控制这个对象的访问;
//小姑娘(姑娘的名字);
var girl = function(name){
this.name = name;
}
//小伙子(想要送给谁);
var boy = function(girl){
this.girl = girl;
this.sendGift = function(gift){
alert("你好,漂亮的"+this.girl.name+",这是我送你的:"+gift);
}
}
//快递小哥(知道送给谁);
var porxyLitterBrother = function(girl){
this.girl = girl;
this.send = function(gift){
// console.log(gift)
gift = "香水"
var b = new boy(girl)
b.sendGift(gift);
}
}
var g = new girl("翠花")
// var b = new boy(g);
// b.sendGift("口红")
var p = new porxyLitterBrother(g)
p.send("口红")
五、适配器模式
//我们要对所有产品都进行一个标准化的测试,测试流程其中包括了
电话、短信、游戏、音乐等等功能
//但是对于一个平板来说,电话功能是无法使用的,因此测试会出问题。
所以将平板进行了包装(类似于代理)
//这样就简单的解决了兼容问题
// 生产手机:打电话,玩游戏
// 生产平板:玩游戏
// 一套测试设备:玩游戏,打电话
function Phone(){
this.name = "手机"
this.game = function(){
console.log("玩游戏")
}
this.call = function(){
console.log("打电话")
}
}
function Pad(){
this.name = "平板"
this.game = function(){
console.log("玩游戏")
}
}
function test(o){
if(o.call){
o.call();
}else{
console.log(o.name + "没有打电话功能")
}
if(o.game){
o.game();
}else{
console.log(o.name + "没有玩游戏功能")
}
}
var p1 = new Phone();
var p2 = new Pad();
test(p2);