> For the complete documentation index, see [llms.txt](https://coffe1891.gitbook.io/frontend-hard-mode-interview/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://coffe1891.gitbook.io/frontend-hard-mode-interview/id-6/1.solid-yuan-ze/6.1.3.md).

# 陆.1.3 开放封闭原则

## 01.官方定义

开闭原则，英文缩写**OCP**，全称 **Open Closed Principle**。

原始定义：

> Software entities (classes, modules, functions) should be open for extension but closed for modification。

严谨的翻译：

> 软件实体（包括类、模块、功能等）应该对扩展开放，但是对修改关闭。

## **02.原理解释**

### 对扩展开放

模块对扩展开放，就意味着需求变化时，可以对模块扩展，使其具有满足那些改变的新行为。换句话说，模块通过扩展的方式去应对需求的变化。

### 对修改关闭

模块对修改关闭，表示当需求变化时，关闭对模块源代码的修改，当然这里的“关闭”应该是尽可能不修改的意思，也就是说，应该尽量在不修改源代码的基础上面扩展组件。

## **03.为什么要“开”和“闭”**

一般情况，我们接到需求变更的通知，通常方式可能就是修改模块的源代码，然而修改已经存在的源代码是存在很大风险的，尤其是项目上线运行一段时间后，开发人员发生变化，这种风险可能就更大。所以，为了避免这种风险，在面对需求变更时，我们一般不修改源代码，即所谓的对修改关闭。不允许修改源代码，我们如何应对需求变更呢？答案就是我们下面要说的对扩展开放。

通过扩展去应对需求变化，就要求我们必须要面向接口编程，或者说面向抽象编程。所有参数类型、引用传递的对象必须使用抽象（接口或者抽象类）的方式定义，不能使用实现类的方式定义；通过抽象去界定扩展，比如我们定义了一个接口A的参数，那么我们的扩展只能是接口A的实现类。

## **04.总结**

有一个经验可以快速检验代码是否遵守了该原则：如果我必须打开你某个模块的js文件并进行修改具体代码才能增强该模块的功能，则你写的这个模块无法通过“开放封闭原则”的检验。

```javascript
//iceCreamMaker.js
let iceCreamFlavors = ['chocolate', 'vanilla'];//口味
let iceCreamMaker = {
  makeIceCream(flavor) {
    if (iceCreamFlavors.indexOf(flavor) > -1) {
      console.log('您选的口味有货，马上给您做冰激凌。');
    } else {
      console.log('哎呀，您选的口味我们没有。');
    }
  },
};
export default iceCreamMaker;
```

如你所见，上面这段代码，不编辑`iceCreamFlavor`数组就无法添加冰淇淋口味！我们来改进一下：

```javascript
//iceCreamMaker.js
let iceCreamFlavors = ['chocolate', 'vanilla'];//口味
let iceCreamMaker = {
  makeIceCream(flavor) {
    if (iceCreamFlavors.indexOf(flavor) > -1) {
      console.log('您选的口味有货，马上给您做冰激凌。');
    } else {
      console.log('哎呀，您选的口味我们没有。');
    }
  },
  //增加口味
  addFlavor(flavor) {
    iceCreamFlavors.push(flavor);
  },
};
export default iceCreamMaker;
```

现在，我们可以在代码中的任何位置调用addFlavor函数，以便添加美味的冰淇淋口味，而无需打开编辑iceCreamMaker.js文件。 确实是可靠的(solid)JavaScript，😋 ！

**总之，开放封闭原则可提高软件的可维护性与代码的重用性。**
