再一次,javascript设计模式与开发实践-开放-封闭原则

定义

很多时候,一个程序具有良好的设计,它通常是符合开发-封闭原则的。

软件实体(类、模块、函数)等应该是可以扩展的,但是不可修改的。

例子

过多的if是造成违反开发-封闭原则的一个常见原因。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var markSound = function (animal) {
    if (animal instanceof Duck) {
        console.log('嘎嘎嘎');
    }
    else if (animal instanceof Chicken) {
        console.log('咯咯咯');
    }
};

var Duck    = function () {};
var Chicken = function () {};

markSound(Duck());
markSound(Chicken());

显然如果动物世界再增加一只狗之后,我们必须改写markSound函数。

如果利用多态的思想,把程序中不变的部分隔离开来(动物都会叫),然后把可变的部分封装起来(不同的叫声),那么程序就具有可扩展性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
var markSound = function (animal) {
    animal.sound();
};

var Duck = function () {};

Duck.prototype.sound = function () {
    console.log('嘎嘎嘎');
};

var Chicken = function () {};

Chicken.prototype.sound = function () {
    console.log('咯咯咯');
};

markSound(new Duck());
markSound(new Chicken());


var Dog = function () {};

Dog.prototype.sound = function () {
    console.log('汪汪汪');
};

找出变化的部分

最明显的就是找出程序中发生变化的地方,然后把变化封装起来。

开发-封闭原则的相对性

实际上让程序保持完全封闭是不容易做到的,总会存在一些无法对其封闭的变化,作为程序猿,我们可以做到下面两点。

  • 挑出最容易发生变化的地方,然后 构造抽象来封闭这些变化。
  • 在不可避免发生修改的时候,尽量修改那些相对容易修改的地方。

接受第一次的愚弄

有句古老的谚语:愚弄我一次,应该羞愧的是你,再次愚弄我,应该羞愧的是我。

让程序一开始就尽量遵守开发-封闭原则,并不是容易的事情。
一方面我们需要知道程序哪些地方会发现变化,这要求我们有一些”未卜先知”的能力,另一方面留给需求排期的时间并不是无限的。
所以我们可以说服自己去接受不合理的代码带来的第一次愚弄。
在最初编写代码的时候,先假设永远不会发生变化,这有利于我们迅速完成需求,当变化发生且对我们工作造成影响时,可以再回过头来封装这些变化。