js设计模式
·29 字·1 分钟阅读
js
工厂模式
<!-- 工厂模式:根据不同的输入返回不同类的实例,一般用来创建同一类对象。 -->
// 饭店方法
function restaurant(menu) {
switch (menu) {
case '鱼香肉丝':
return new YuXiangRouSi();
case '宫保鸡丁':
return new GongBaoJiDin();
default:
throw new Error('这个菜本店没有');
}
};
// 鱼香肉丝类
function YuXiangRouSi() { this.type = '鱼香肉丝' };
YuXiangRouSi.prototype.eat = function () {
console.log(this.type + ' 真香');
};
// 宫保鸡丁类
function GongBaoJiDin() { this.type = '宫保鸡丁' };
GongBaoJiDin.prototype.eat = function () {
console.log(this.type + ' 让我想起了外婆做的菜~');
};
const dish1 = restaurant('鱼香肉丝');
dish1.eat();
// 鱼香肉丝 真香
const dish2 = restaurant('红烧排骨');
// Error 这个菜本店没有
建造者模式
// 建造者,汽车部件厂家,提供具体零部件的生产
class CarBuilder {
constructor({ color = 'white', weight = 0 }) {
this.color = color;
this.weight = weight;
}
// 生产部件,轮胎
buildTyre(type) {
const tyre = {}
switch (type) {
case 'small':
tyre.tyreType = '小号轮胎'
tyre.tyreIntro = '正在使用小号轮胎'
break
case 'normal':
tyre.tyreType = '中号轮胎'
tyre.tyreIntro = '正在使用中号轮胎'
break
case 'big':
tyre.tyreType = '大号轮胎'
tyre.tyreIntro = '正在使用大号轮胎'
break
}
this.tyre = tyre;
}
// 生产部件,发动机
buildEngine(type) {
const engine = {}
switch (type) {
case 'small':
engine.engineType = '小马力发动机'
engine.engineIntro = '正在使用小马力发动机'
break
case 'normal':
engine.engineType = '中马力发动机'
engine.engineIntro = '正在使用中马力发动机'
break
case 'big':
engine.engineType = '大马力发动机'
engine.engineIntro = '正在使用大马力发动机'
break
}
this.engine = engine
}
};
// 指挥者,负责最终汽车产品的装配
class BenChiDirector {
constructor(tyre, engine, param) {
const car = new CarBuilder(param);
car.buildTyre(tyre);
car.buildEngine(engine);
return car;
}
};
// 获得产品实例
const benchi = new BenChiDirector('small', 'big', { color: 'red', weight: '1600kg' });
发布订阅模式
// 发布、订阅中心
class PubSub{
#list = []
// 订阅
subscribe(sub){
this.#list.push(sub)
}
// 发布
publish(){
this.#list.forEach(item=>{
item.update()
})
}
// 退订
unsubscribe(sub){
this.#list = this.#list.filter(item=>item!==sub)
}
}
// 订阅者
class Subscriber{
constructor(name){
this.name = name
}
// 主要逻辑
update(){
console.log(this.name)
}
}
//
const pubsub = new PubSub()
let subscriber1 = new Subscriber('xiaoming')
let subscriber2 = new Subscriber('tiechui')
// 开始订阅
pubsub.subscribe(subscriber1)
pubsub.subscribe(subscriber2)
// 退订
// pubsub.unsubscribe(subscriber1)
// 当符合情况时,进行发布
pubsub.publish()
单例模式
class Single{
constructor(name, age){
if(!Single.instance){
this.name = name;
this.age = age;
Single.instance = this;
}
return Single.instance;
}
}
let a = new Single("tom", 18);
let b = new Single("tiechui", 28);
console.log(a)
// Single {name: 'tom', age: 18}
console.log(b)
// Single {name: 'tom', age: 18}
适配器模式
// 将一个类(对象)的接口(方法、属性)转化为用户需要的另一个接口。解决类(对象)之间接口不兼容的问题
class TencentMap{
show(){
console.log('开始渲染腾讯地图');
}
}
class BaiduMap{
display(){
console.log('开始渲染百度地图');
}
}
// 百度的适配器
class BaiduAdapator extends BaiduMap{
constructor(){
super();
}
show(){
this.display()
}
}
// 只支持腾讯地图,所以要给百度写一个适配器
function renderMap(map){
map.show();
}
renderMap(new TencentMap());
renderMap(new BaiduAdapator());
装饰器模式
// 前置函数
Function.prototype.before = function (fn) {
var _this = this;
return function () {
// 先进行前置函数的调用
fn.apply(this, arguments);
// 再调用原函数
return _this.apply(_this, arguments);
}
}
// 后置函数
Function.prototype.after = function (fn) {
var _this = this;
return function () {
// 先调用原函数
var result = _this.apply(_this, arguments);
// 再进行后置函数的调用
fn.apply(this, arguments);
return result;
}
}
function test(params) {
console.log(params);
}
var test1 = test.before(function (params) {
console.log('前置函数');
params.token = 'ajsbasczxc';
});
var test2 = test.after(function (params) {
console.log('后置函数');
params.date = new Date()
});
test1({
name: 'zhe'
})
/*
前置函数
index.html:32 {name: 'zhe', token: 'ajsbasczxc'}
*/
test2({
name: 'zhe'
})
/*
{name: 'zhe'}
index.html:39 后置函数
*/