软件设计模式(Design pattern),又称设计模式,是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。
比较权威的是GOF(四人帮,全拼 Gang of Four)出版的《设计模式》,该书首次提到了软件开发中设计模式的概念。
设计模式中比较被认可的目前大致是23种,这23种模式可以分为三类
创建型模式(Creational Patterns):对象实例化的模式,创建型模式用于解耦对象的实例化过程。
结构型模式(Structural Patterns):把类或对象结合在一起形成一个更大的结构。
行为型模式(Behavioral Patterns):类和对象如何交互,及划分责任和算法。
';
return $(str).appendTo($("body"));
}
var getUploadObj = getActiveUploadObj.after(getFlashUploadObj).after(getFormUploadObj);
console.log(getUploadObj());
7.命令模式
定义:指的是 一个执行某些待定事情的指令。
应用:点菜
var client = { // 顾客(命令发出者)
name: '铁蛋儿'
}
var cook = { // 厨师(命令发执行者)
makeFood: function (food) {
console.log('开始做:', food)
},
serveFood: function (client) {
console.log('上菜给:', client.name)
}
}
function OrderCommand(receiver, food) { // 命令对象
this.receiver = receiver
this.food = food
}
OrderCommand.prototype.execute = function (cook) { // 提供执行方法
cook.makeFood(this.food)
cook.serveFood(this.receiver)
}
var command = new OrderCommand(client, '宫保鸡丁')
command.execute(cook) // 开始做:宫保鸡丁; 上菜给铁蛋儿
8.备忘录模式
定义:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到保存的状态。
应用:新闻翻页缓存器
// Page备忘录
var Page = function() {
// 缓存器
var cache = {};
return function(page, fn) {
if (cache[page]) {
// 1-如果缓存中存在指定页的数据,直接使用
showPage(page, cache[page]);
fn && fn();
} else {
// 2-如果缓存中不存在指定页的数据,则从服务端获取,并将其缓存下来
$.post('server_api_url', {page: page}, function(res) {
if (res.success) {
showPage(page, res.data);
cache[page] = res.data;
fn && fn();
} else {
// ajax error
}
});
}
}
}();
// 事件:下一页
$('#next_page_btn').click(function() {
// 获取新闻列表容器
var $news = $('#news_content');
// 获取当前页号
var page = $news.data('page');
Page(page, function() {
$news.data('page', page+1);
});
});
// 事件:上一页
$('#pre_page_btn').click(function() {
// 获取新闻列表容器
var $news = $('#news_content');
// 获取当前页号
var page = $news.data('page');
Page(page, function() {
$news.data('page', page-1);
});
});
9.状态模式
定义:允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它所属的类。
应用场景:超级玛丽的动作
class SuperMarry {
constructor() {
this._currentState = []
this.states = {
jump() {console.log('跳跃!')},
move() {console.log('移动!')},
shoot() {console.log('射击!')},
squat() {console.log('蹲下!')}
}
}
change(arr) { // 更改当前动作
this._currentState = arr
return this
}
go() {
console.log('触发动作')
this._currentState.forEach(T => this.states[T] && this.states[T]())
return this
}
}
new SuperMarry()
.change(['jump', 'shoot'])
.go() // 触发动作 跳跃! 射击!
.go() // 触发动作 跳跃! 射击!
.change(['squat'])
.go()
10.访问者模式
定义:表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
应用场景:使对象拥有像数组的push pop和splice方法。
var Visitor = (function() {
return {
splice: function(){
var args = Array.prototype.splice.call(arguments, 1)
return Array.prototype.splice.apply(arguments[0], args)
},
push: function(){
var len = arguments[0].length || 0
var args = this.splice(arguments, 1)
arguments[0].length = len + arguments.length - 1
return Array.prototype.push.apply(arguments[0], args)
},
pop: function(){
return Array.prototype.pop.apply(arguments[0])
}
}
})()
var a = new Object()
console.log(a.length)
Visitor.push(a, 1, 2, 3, 4)
console.log(a.length)
Visitor.push(a, 4, 5, 6)
console.log(a.length)
Visitor.pop(a)
console.log(a)
console.log(a.length)
Visitor.splice(a, 2)
console.log(a)
11.中介者模式
定义:用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
应用场景:MVC 框架,其中C(控制器)就是 M(模型)和 V(视图)的中介者。
// 创建模型,管理多个数据
class Model{
model1(){
return "hello";
}
model2(){
return "world";
}
model3(){
return "你好";
}
}
// 创建视图,管理多种渲染方式
class View{
view1(data){
console.log(data);
}
view2(data){
document.write(data);
}
view3(data){
alert(data);
}
}
// 创建控制器,设定对应的指令
class Ctrl{
constructor(){
// 初始化模型和视图
this.m = new Model();
this.v = new View();
}
// 在指令中,可以读取对应的数据,放在对应的视图中
ctrl1(){
var data = this.m.model1();
this.v.view1(data);
}
ctrl2(){
var data = this.m.model2();
this.v.view3(data);
}
}
var c = new Ctrl();
c.ctrl1();
c.ctrl2();