1.代理模式
代理模式:是为一个对象提供一个代用品或占位符,以便控制对它的访问。
代理模式的生动理解可以类比为一个人找代理去购物。这个人想购买一些物品,但是由于某些原因无法亲自前往商店购买,于是他找到了一个代理人去帮他购买。
HTML元 素事件代理
xml
复制代码
<ul id="ul">
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<script>
let ul = document.querySelector('#ul');
ul.addEventListener('click', event => {
console.log(event.target);
});
</script>
优点:代理模式能将代理对象与被调用对象分离,降低了系统的耦合度。代理模式在客户端和目标对象之间起到一个中介作用,这样可以起到保护目标对象的作用代理对象可以扩展目标对象的功能;通过修改代理对象就可以了,符合开闭原则。
缺点:处理请求速度可能有差别,非直接访问存在开销。
2. 外观模式
外观模式(Facade Pattern)是一种结构型设计模式,其主要目的是简化复杂系统的接口并提供一个更高级别的接口以供外部使用。
可以将外观模式想象成一个门面或者外观,类似于房子的门面,它把整个系统隐藏在其背后。对于外部使用者而言,只需要通过门面提供的接口来操作系统,而不需要关心背后的实现细节。
外观模式的一个生动的例子是手机的操作界面。手机的操作界面为用户提供了一个简单易用的接口,可以通过点击屏幕上的图标、按钮来进行操作,但实际上在背后有许多不同的系统组件在协作工作。用户不需要关心这些组件的具体实现,只需要使用操作界面提供的接口即可。
很多我们常用的框架和库基本都遵循了外观设计模式,比如JQuery就把复杂的原生DOM操作进行了抽象和封装,并消除了浏览器之间的兼容问题,从而提供了一个更高级更易用的版本。
浏览器事件绑定
rust
复制代码
let addMyEvent = function (el, ev, fn) {
if (el.addEventListener) {
el.addEventListener(ev, fn, false)
} else if (el.attachEvent) {
el.attachEvent('on' + ev, fn)
} else {
el['on' + ev] = fn
}
};
3.单例模式
单例模式是一种创建型设计模式
javascript
复制代码
class GameManager {
constructor() {
if (GameManager.instance) {
return GameManager.instance;
}
this.score = 0;
GameManager.instance = this;
}
static getInstance() {
return GameManager.instance || new GameManager();
}
addScore(points) {
this.score += points;
console.log(`Score: ${this.score}`);
}
}
// 单例模式
const gameManager1 = new GameManager();
const gameManager2 = GameManager.getInstance();
gameManager1.addScore(10); // Score: 10
gameManager2.addScore(20); // Score: 30
console.log(gameManager1 === gameManager2); // true
顾名思义,单例模式中Class的实例个数最多为1。当需要一个对象去贯穿整个系统执行某些任务时,单例模式就派上了用场。
优点:划分命名空间,减少全局变量、增强模块性,把自己的代码组织在一个全局变量名下,放在单一位置,便于维护、且只会实例化一次。简化了代码的调试和维护
缺点:由于单例模式提供的是一种单点访问,所以它有可能导致模块间的强耦合、从而不利于单元测试。无法单独测试一个调用了来自单例的方法的类,而只能把它与那个单例作为一个单元一起测试。