設(shè)計(jì)者模式
1.特點(diǎn)
提高代碼的重用性,可讀性,使代碼更容易的維護(hù)和擴(kuò)展
2.原則
設(shè)計(jì)模式有六大原則:
- 開(kāi)閉原則晒骇。就是說(shuō)模塊應(yīng)對(duì)擴(kuò)展開(kāi)放,而對(duì)修改關(guān)閉磺浙。
- 里氏代換原則洪囤。如果調(diào)用的是父類的話,那么換成子類也完全可以運(yùn)行撕氧。
- 依賴倒轉(zhuǎn)原則瘤缩。把父類都替換成它的子類,程序的行為沒(méi)有變化呵曹。
- 接口隔離原則款咖,每一個(gè)接口應(yīng)該是一種角色,不多不少奄喂,不干不該干的事,該干的事都要干海洼。
- 單一職責(zé)原則跨新。
- 迪米特法則。 最少知識(shí)原則坏逢。
3.單例設(shè)計(jì)模式
定義:保證一個(gè)類僅有一個(gè)實(shí)例,并提供一個(gè)訪問(wèn)它全局的點(diǎn)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="../my_ajax.js"></script>
</head>
<body>
<form action="">
<input type="text" name="user">
<input type="password" name="pwd">
<input type="submit" value="登錄">
</form>
<script type="text/javascript">
var submitObj = {
form : document.forms[0],
submitUrl : "data2.php",
_init : function () {
this.handSubmit();
},
handSubmit : function () {
var that = this;
this.form.onsubmit = function (e) {
e.preventDefault(); //阻止表單提交默認(rèn)行為
if(!that.checkForm()) return;
that.ajaxSubmit();
}
},
checkForm : function () {
return true; //可使用正則表達(dá)式驗(yàn)證
},
ajaxSubmit : function () {
my_ajax.post(this.submitUrl,new FormData(this.form),this.submitResult)
},
submitResult : function (result) {
console.log(result);
}
}
submitObj._init();
</script>
</body>
</html></pre>
4.適配器模式
定義:適配器模式(Adapter)是將一個(gè)類(對(duì)象)的接口(方法或?qū)傩裕┺D(zhuǎn)化成客戶希望的另外一個(gè)接口(方法或?qū)傩裕┯蛘剩m配器模式使得原本由于接口不兼容而不能一起工作的那些類(對(duì)象)可以一些工作赘被。俗稱包裝器(wrapper)。
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="../my_ajax.js"></script>
</head>
<body>
<p id="p1"></p>
<p id="p2"></p>
?
<script type="text/javascript">
//適配器模式:在不修改舊的模式的前提下,來(lái)適應(yīng)新的變化
my_ajax.get("data3.json",function (result) {
showMsg(JSON.parse(result),p1);
})
my_ajax.get("data4.json",function (result) {
showMsgAdapter(JSON.parse(result),p2);
})
function showMsg(obj,p) {
p.innerHTML = obj.name;
}
function showMsgAdapter(arr,p) {
showMsg(arr[0],p2);
}
</script>
</body>
</html></pre>
5.觀察者模式
定義:觀察者模式又叫發(fā)布訂閱模式(Publish/Subscribe)肖揣,它定義了一種一對(duì)多的關(guān)系民假,讓多個(gè)觀察者對(duì)象同時(shí)監(jiān)聽(tīng)某一個(gè)主題對(duì)象,這個(gè)主題對(duì)象的狀態(tài)發(fā)生變化時(shí)就會(huì)通知所有的觀察者對(duì)象龙优,使得它們能夠自動(dòng)更新自己羊异。
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<button id="btn1">發(fā)布信息</button>
<button id="btn2">刪除訂閱者</button>
<script>
var publisher = {
//注冊(cè)訂閱者信息
register: function (event, subscriber) { //event為publisher的一個(gè)屬性
//判斷subscriber是否是函數(shù)
if (typeof subscriber != "function") return;
//判斷指定事件是否存在
if (!this[event]) this[event] = [];
this[event].push(subscriber); //存儲(chǔ)訂閱者的信息函數(shù)
},
//向訂閱者發(fā)送消息
publish: function (event, msg) {
if (!this[event]) return; //判斷指定事件是否存在
for (var sub of this[event]) {
sub(msg);
}
},
//刪除訂閱者
remove: function (event, sub) {
if (!this[event] || this[event].indexOf(sub) == -1) return;
this[event].splice(this[event].indexOf(sub), 1);
}
}
//向訂閱者發(fā)布信息,訂閱者使用函數(shù)充當(dāng)
var f = function (msg) {
console.log("第一條消息是" + msg);
}
publisher.register("500", f);
publisher.register("600", function (msg) {
console.log("第二條消息是" + msg);
})
publisher.register("500", function (msg) {
console.log("第三條消息是" + msg);
})
publisher.register("700", function (msg) {
console.log("第四條消息是" + msg);
})
btn1.onclick = function () {
publisher.publish("500", "最新消息500");
// publisher.publish("700","最新消息700");
}
btn2.onclick = function () {
publisher.remove("500", f);
}
</script>
</body>
</html></pre>
利用觀察者模式定義三次點(diǎn)擊事件
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<button id="btn1">按鈕一</button>
<button id="btn2">按鈕二</button>
<script type="text/javascript">
//給button的原型添加方法
HTMLButtonElement.prototype.addMyEventListener = function (event,f) {
if(!this[event]) this[event] = [];
this[event].push(f);
this.times = [];
//設(shè)置鼠標(biāo)點(diǎn)擊的監(jiān)聽(tīng)事件
this.addEventListener("mousedown",function handleClick() {
//點(diǎn)擊事件間隔很長(zhǎng)的時(shí)候
if(this.times.length == 3){
// [100, 200, 300]
this.times.shift();
}
this.times.push(new Date().getTime());
//當(dāng)三次點(diǎn)擊間隔很短的時(shí)候
if(this.times.length == 3){
if(this.times[2] - this.times[0]<500){
this.times.length = 0; //清空時(shí)間數(shù)組
for (var tc of this.three){
tc(); //調(diào)用函數(shù),即f
}
}
}
})
}
btn1.addMyEventListener("three",function (){
console.log("你點(diǎn)擊了按鈕一共三次");
})
btn2.addMyEventListener("three",function (){
console.log("你點(diǎn)擊了按鈕二共三次");
})
</script>
</body>
</html></pre>
</article>