设计模式初探
单例模式
内部定义变量,并通过闭包判断,不存在则生成新的
策略模式
- 符合单一职责原则
- 增加或减少策略,无需大改原有的代码
- 针对同一问题的多种处理方式,仅仅是具体行为有差别时
const listString={
add:0,
del:1,
update:2
}
const strFunc={
add:function(){
return listString['add'];
},
del:function(){
return listString['del'];
},
update:function(){
return listString['update'];
}
}
function getData(name){
return strFunc[name]?strFunc[name]():0;
}
console.log(getData('add'));
代理模式
在访问主体之前进行控制,对方法内容的判断
举个例子:比如点击登录后的 数据校验,只有通过了才会访问登录接口
const login(name){
console.log(name+'进行了登录');
}
const proxyCheckLogin(name){
if(!name)return
login(name);
}
发布-订阅模式
一方发布事件,另一方订阅接收事件
举个例子: 例如vue的vuex, React的mobx|redux都是这种形式
缺点:
- 常驻内存增加性能开销
- 当项目越来越大时,会出现较难跟踪订阅的情况
中介者模式
所有的方法都通过中介者方法来实现,当内容改变时,通知中介者进行改变即可
举个例子:将方法中共用的部分抽成单独函数进行调用
function add(name){
let temp='1';
consoleFunc(temp,name);
}
function update(name){
let temp='2';
consoleFunc(temp,name);
}
function consoleFunc(temp,name){
console.log(name+'输出了:'+temp);
}
add('zhangsan');
update('lisi');
装饰者模式
对已有对象或方法的内容补充与扩展,赋予更多的能力
举个例子: 小明原本吃饭只会用筷子,通过装饰器后,学会了用刀叉
function Person() {
}
Person.prototype.skill = function() {
console.log('数学');
};
// 装饰器,还会音乐
function MusicDecorator(person) {
this.person = person;
}
MusicDecorator.prototype.skill = function() {
this.person.skill();
console.log('音乐');
};
var person = new Person();
// 装饰一下
var person1 = new MusicDecorator(person);
person.skill(); // 数学
person1.skill(); // 数学 音乐
状态模式
封装状态,状态是已经定义好的,用户无需知道
举个例子: 开灯,关灯, 通过状态模式只是改变了状态
适配器模式
对方法间不适配的部分进行适配
举个例子: foreach解析数组数据,但是传入了一个对象,这时候就要判断并适配了
// 渲染数据,格式限制为数组了
function renderData(data) {
data.forEach(function(item) {
console.log(item);
});
}
// 对非数组的进行转换适配
function arrayAdapter(data) {
if (typeof data !== 'object') {
return [];
}
if (Object.prototype.toString.call(data) === '[object Array]') {
return data;
}
var temp = [];
for (var item in data) {
if (data.hasOwnProperty(item)) {
temp.push(data[item]);
}
}
return temp;
}
var data = {
0: 'A',
1: 'B',
2: 'C'
};
renderData(arrayAdapter(data)); // A B C
外观模式
定义一个函数用来收纳其它函数,然后统一执行
举个例子:就是美化一下…
// 三个处理函数
function add() {
console.log('add');
}
function update() {
console.log('update');
}
// 外观函数,将一些处理统一起来,方便调用
function execute() {
add();
update();
}
// 调用init开始执行
function init() {
// 此处直接调用了高层函数,也可以选择越过它直接调用相关的函数
execute();
}
init(); // add update
迭代器模式
迭代器模式是指提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示
暂无使用场景
function add(){
console.log('add');
return false;
}
function update(){
console.log('update');
return false;
}
function iteratorFunc() {
for (var i = 0; i < arguments.length; ++i) {
var ret = arguments[i]();
if (ret !== false) {
return ret;
}
}
}
var temp=iteratorFunc(add,update);
职责链模式
逐一调用,直至有一个函数方法会处理该请求
举个例子:类似于if/else
模板方法模式
封装子类方法,并指导子类以何种顺序去执行哪些方法
享元模式
减少共享对象的数量
组合模式
是用小的子对象来构建更大的 对象,而这些小的子对象本身也许是由更小 的“孙对象”构成的
命令模式
命令指的是一个执行某些特定事情的指令
参考文章:JS中常见的十五种设计模式