前端设计模式

1. 工厂模式

用于生成各种实例的函数(最常见的,构造函数)

复杂工厂模式:
父类:是一个抽象类,不可以直接实例
子类执行自己的业务逻辑,实现自身的实例方法

function BicycleShop(name){
	this.name = name;
	this.method = function() {
		return this.name;
	}
}

BicycleShop.prototype = {
	constructor: BicycleShop, // 为什么这里需要重新指定constructor属性呢?因为系统为BicycleShop分配的原型对象已经被你改变了,所以要重新指定。
	sellBicycle: function() {
		let bicycle = this.createBicycle();
		
		bicycle.a();
		bicycle.b();
		return bicycle;
	},
	createBicycle: function() {
		throw new Error('父类不能直接实例,需要子类来实例');
	}
}

// 通过原型链继承
function extend(Sub, Sup) {
	let F = function() {};
	F.prototype = Sup.prototype;
	Sub.prototype = new F();
	Sub.prototype.constructor = Sub;
	Sub.sup = Sup.prototype;
}

function BicycleChild(name) {
	this.name = name;
	BicycleShop.call(this, name);
}

extend(BicycleChild, BicycleShop);

BicycleChild.prototype.createBicycle = function(){
	let a = function(){
		console.log('执行a');
	}
	let b = function(){
		console.log('执行b');
	}
	return {
		a,
		b
	}
}

const bicycleChild = new BicycleChild();

2. 单例模式

划分命名空间,并将属性和方法组织在一起的一种方式;
只实例化一次,每次返回的实例都是同一对象。

function Singleton(name) {
	this.name = name;
}

Singleton.prototype.getName = function() {
	console.log(this.name);
}

let getInstance = (function(name){
	let instance;
	return function(name) {
		if(!instance) {
			instance = new Singleton(name);
		}

		return instance;
	}
})();

// 绑定到静态属性
Singleton.getInstance = ....

let a = getInstance('张三');
let b = getInstance('李四');
// 都是张三

未完待续

3. 策略模式

将策略单独封装起来,比如 switch 替换成对象属性

4. 发布订阅模式–重要

定义对象一对多之间的依赖关系

典型:dom1.addEventListener(‘click’, function(){}) , eventBus

// 1. 主题 (售楼处)
// 2. 缓存列表
// 3. 当事件触发的时候(状态发生变化),依次执行回调函数

let salesOffices = {};
salesOffices.clientList = [];

salesOffices.listen = function(key, fn){
	if(!this.clientList[key]){
		this.clientList[key] = [];
	}
	this.clientList[key].push(fn);
}

salesOffices.trigger = function(){
	const key = Array.prototype.shift.call(arguments),
		fns = this.clientList[key];
	for(let i = 0; i < fns.length; i++) {
		fns[i].apply(this, arguments);
	}
}

-----------------------------------------------------------------

const Event = {
	clientList: [];
	listen: function(key, fn){
		if(!this.clientList[key]){
			this.clientList[key] = [];
		}
		this.clientList[key].push(fn);
	},
	trigger(){
		const key = Array.prototype.shift.call(arguments),
			fns = this.clientList[key];
		for(let i = 0; i < fns.length; i++) {
			fns[i].apply(this, arguments);
		}
	}
}

function installEvent(target, Source) {
	// for (let i in Source) {
	// 	target[i] = Source[i];
	// }
	// return target

	return Object.assign(target, Source);
}

let salesOffices = installEvent(salesOffices, Event);

-----------------------------

// 类
class Event {
	constructor() {
		this.clientList = {};
	}
	listen(key, fn){
		if(!this.clientList[key]){
			this.clientList[key] = [];
		}
		this.clientList[key].push(fn);
	},
	trigger(){
		const key = Array.prototype.shift.call(arguments),
			fns = this.clientList[key];
		for(let i = 0; i < fns.length; i++) {
			fns[i].apply(this, arguments);
		}
		// this.events[eventName] && this.events[eventName].forEach(fn => fn());
	}

	// 移除订阅事件
	removeListener(eventName, callback) {
	    if (this.events[eventName]) {
	        this.events[eventName] = this.events[eventName].filter(cb => cb != callback)
	    }
	}

	// 只执行一次订阅的事件,然后移除
    once(eventName,callback) {
        // 绑定的时fn, 执行的时候会触发fn函数
        let fn = () => {
           callback(); // fn函数中调用原有的callback
           this.removeListener(eventName,fn); // 删除fn, 再次执行的时候之后执行一次
        }
        this.on(eventName,fn)
    }
}

class SalesOffices extends Event {
	constructor() {
		super();
	}
}

let salesOffices  = new SalesOffices();
--------------------------------

salesOffices.listen('square88', function(price, squareMeter){
	console.log('价格:'+ price);
})
salesOffices.listen
salesOffices.listen

salesOffices.trigger('square88', 1000, 88);

5. 适配器模式

类比 电源适配器,笔记本充电器20v,家用220v

接口更新、数据格式更新

6. 装饰器模式

为对象添加新功能
不改变其原有的结构和功能

class Circle {
    draw() {
        console.log("画一个圆形");
    }
}

class Decorator {
    constructor(circle){
        this.circle = circle;
    }
    draw() {
        this.circle.draw();
        this.setRedBorder(this.circle);
    }
    setRedBorder(circle) {
        console.log("设置红色边框")
    }
}
// 测试代码
let circle = new Circle();
circle.draw()

let dec = new Decorator(circle);
dec.setRedBorder();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值