设计模式一直是程序员谈论的“高端”话题之一,总有一种敬而远之的心态。在了解后才知道在将函数作为一等对象的语言中,有许多需要利用对象多态性的设计模式,比如单例模式、 策略模式等,这些模式的结构与传统面向对象语言的结构大相径庭,实际上已经融入到了语言之中,我们可能经常使用它们,只是不知道它们的名字而已。
设计模式
相信了解的,都知道有 20 多种…
其中按类型分有三种。为“创建型”封装了创建对象的变化过程,“结构型”将对象之间组合的变化封装,“行为型”则是抽离对象的变化行为。
接下来,本文将以常用原则中从“单一功能”和“开放封闭”这两大原则为主线,分别介绍“创建型”、“结构型”和“行为型”中最具代表性的单例、策略、代理、观察者这几大设计模式。
1 常用原则
这些设计原则通常指的是单一职责原则、里氏替换原则、依赖倒置原则、接口隔离原则、合成复用原则和最少知识原则。因为案例中涉及单一职责原则和开放-封闭原则,所以只介绍这两部分。
1.1 单一职责原则(SRP)
一个对象(方法)只做一件事情
如果我们有两个动机去改写一个方法,那么这个方法就具有两个职责。每个职责都是变化的一个轴线,如果一个方法承担了过多的职责,那么在需求的变迁过程中,需要改写这个方法的可能性就越大。
SRP 原则的优点是降低了单个类或者对象的复杂度,按照职责把对象分解成更小的粒度, 这有助于代码的复用,也有利于进行单元测试。当一个职责需要变更的时候,不会影响到其他的职责。
但 SRP 原则也有一些缺点,最明显的是会增加编写代码的复杂度。当我们按照职责把对象分解成更小的粒度之后,实际上也增大了这些对象之间相互联系的难度。
1.2 开放-封闭原则
对象(类、模块、函数等)应该是可扩展但不可修改的。
就算我们作为维护者,拿到的是一份混淆压缩过的代码也没有关系。只要它从前是个稳定运行的函数,那么以后也不会因为我们的新增需求而产生错误。新增的代码和原有的代码可以井水不犯河水。
2 单例模式
单例模式 (Singleton Pattern)又称为单体模式,保证一个类只有一个实例,并提供一个访问它的全局访问点。也就是说,第二次使用同一个类创建新对象的时候,应该得到与第一次创建的对象完全相同的对象。
2.1 举个 🌰 登录弹窗
我们正在开发一个网站,网站类型是一个视频网站,网站有个登录按钮,点击登录会弹出一个登录框进行登录,你现在可能已经联想到,这个登录框一定是页面唯一的一个 dom 节点,一个页面存在两个登录框是不存在的!
如果要实现这种效果第一种解决方案就是在页面加载的时候就已经创建好 dom 节点,并且设置样式为 display 为 none,当点击登录时修改为 block 显示。这种方式有一个问题,也许我们进入当前网站只是玩玩游戏或者看看天气,根本不需要进行登录操作,因为登录浮窗总是一开始就被创建好,那么很有可能将白白浪费一些 DOM 节点。所以开始改进,当我们每次点击登录按钮的时候,再创建一个新的登录浮窗 div。
虽然我们可以在点击浮窗上的关闭按钮时(此处未实现)把这个浮窗从页面中删除掉,但这样频繁地创建和删除节点明显是不合理的,也是不必要的。所以我们再次进行改进,用一个变量来判断是否已经创建过登录浮窗。