提高代码的重用性,可读性,使代码更容易的维护和扩展
设计模式有六大原则:
开闭原则。就是说模块应对扩展开放,而对修改关闭。
里氏代换原则。如果调用的是父类的话,那么换成子类也完全可以运行。
依赖倒转原则。把父类都替换成它的子类,程序的行为没有变化。
接口隔离原则,每一个接口应该是一种角色,不多不少,不干不该干的事,该干的事都要干。
单一职责原则。
迪米特法则。 最少知识原则。
定义:保证一个类仅有一个实例,并提供一个访问它全局的点
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(); //阻止表单提交默认行为
if(!that.checkForm()) return;
that.ajaxSubmit();
}
},
checkForm : function () {
return true; //可使用正则表达式验证
},
ajaxSubmit : function () {
my_ajax.post(this.submitUrl,new FormData(this.form),this.submitResult)
},
submitResult : function (result) {
console.log(result);
}
}
submitObj._init();
</script>
</body>
</html>
定义:适配器模式(Adapter)是将一个类(对象)的接口(方法或属性)转化成客户希望的另外一个接口(方法或属性),适配器模式使得原本由于接口不兼容而不能一起工作的那些类(对象)可以一些工作。俗称包装器(wrapper)。
DOCTYPE html>
<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">
//适配器模式:在不修改旧的模式的前提下,来适应新的变化
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>
定义:观察者模式又叫发布订阅模式(Publish/Subscribe),它定义了一种一对多的关系,让多个观察者对象同时监听某一个主题对象,这个主题对象的状态发生变化时就会通知所有的观察者对象,使得它们能够自动更新自己。
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<button id="btn1">发布信息</button>
<button id="btn2">删除订阅者</button>
<script>
var publisher = {
//注册订阅者信息
register: function (event, subscriber) { //event为publisher的一个属性
//判断subscriber是否是函数
if (typeof subscriber != "function") return;
//判断指定事件是否存在
if (!this[event]) this[event] = [];
this[event].push(subscriber); //存储订阅者的信息函数
},
//向订阅者发送消息
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);
}
}
//向订阅者发布信息,订阅者使用函数充当
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>
DOCTYPE html>
<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 = [];
//设置鼠标点击的监听事件
this.addEventListener("mousedown",function handleClick() {
//点击事件间隔很长的时候
if(this.times.length == 3){
// [100, 200, 300]
this.times.shift();
}
this.times.push(new Date().getTime());
//当三次点击间隔很短的时候
if(this.times.length == 3){
if(this.times[2] - this.times[0]<500){
this.times.length = 0; //清空时间数组
for (var tc of this.three){
tc(); //调用函数,即f
}
}
}
})
}
btn1.addMyEventListener("three",function (){
console.log("你点击了按钮一共三次");
})
btn2.addMyEventListener("three",function (){
console.log("你点击了按钮二共三次");
})
</script>
</body>
</html>