# 架构设计基本原则


<!--more-->


## 1.开闭原则

软件实体应当对扩展开放，对修改关闭，这就是开闭原则的经典定义。

软件实体包括：1.项目中划分出的模块； 2.类与接口；3.方法

开闭原则的含义是：当应用的需求改变时，在不修改软件实体的源代码或者二进制代码的前提下，可以扩展模块的功能，使其满足新的需求。

**作用：**

- 对软件测试的影响
- 可以提高代码的可复用性
- 可以提高软件的可维护性

**实现方法：**

可以通过“抽象约束、封装变化”来实现开闭原则，即通过接口或者抽象类为软件实体定义一个相对稳定的抽象层，而将相同的可变因素封装在相同的具体实现类中。



## 2.单一职责原则

### 2.1 定义

单一职责原则又称单一功能原则，这里的职责是指类变化的原因，单一职责原则规定一个类应该有且仅有一个引起它变化的原因，否则类应该被拆分。

该原则提出对象不应该承担太多职责，如果一个对象承担了太多的职责，至少存在以下两个缺点：

- 一个职责的变化可能会削弱或者抑制这个类实现其他职责的能力；
- 当客户端需要该对象的某一个职责时，不得不将其他不需要的职责全都包含进来，从而造成冗余代码或代码的浪费。

### 2.2 优点

- 降低类的复杂度
- 提高类的可读性
- 提高系统的可维护性
- 变更引起的风险降低

### 2.3 实现方法

单一职责原则是最简单但又最难运用的原则，需要设计人员发现类的不同职责并将其分离，再封装到不同的类或模块中。而发现类的多重职责需要设计人员具有较强的分析设计能力和相关重构经验

![img_52](https://img.zhaojq.top/20260727091841912.png "img_52")



## 3.接口隔离原则

### 3.1 定义

接口隔离原则要求程序员尽量将臃肿庞大的接口拆分成更小的和更具体的接口，让接口中只包含客户感兴趣的方法。

接口隔离原则和单一职责都是为了提高类的内聚性、降低它们之间的耦合性，体现了封装的思想，但两者是不同的

- 单一职责原则注重的是职责，而接口隔离原则注重的是对接口依赖的隔离。
- 单一职责原则主要是约束类，它针对的是程序中的实现和细节；接口隔离原则主要约束接口，主要针对抽象和程序整体框架的构建。

### 3.2 优点

1. 提高系统的灵活性和可维护性
2. 降低系统的耦合性。
3. 保证系统的稳定性
4. 使用多个专门的接口还能够体现对象的层次，因为可以通过接口的继承，实现对总接口的定义。

5. 能减少项目工程中的代码冗余

### 3.3 实现方法

- 接口尽量小，但是要有限度。一个接口只服务于一个子模块或业务逻辑。
- 为依赖接口的类定制服务。只提供调用者需要的方法，屏蔽不需要的方法。
- 了解环境，拒绝盲从。每个项目或产品都有选定的环境因素，环境不同，接口拆分的标准就不同深入了解业务逻辑。
- 提高内聚，减少对外交互。使接口用最少的方法去完成最多的事情。

## 4.里氏替换原则

### 4.1 定义

里氏替换原则主要阐述了有关继承的一些原则。里氏替换原则是继承复用的基础，它反映了基类与子类之间的关系，是对开闭原则的补充，是对实现抽象化的具体步骤的规范。总结:**子类可以扩展父类的功能，但不能改变父类原有的功能**

### 4.2 作用

1.	里氏替换原则是实现开闭原则的重要方式之一。
2.	它克服了继承中重写父类造成的可复用性变差的缺点。
3.	它是动作正确性的保证。即类的扩展不会给已有的系统引入新的错误，降低了代码出错的可能性。

4. 加强程序的健壮性，同时变更时可以做到非常好的兼容性，提高程序的维护性、可扩展性，降低需求变更时引入的风险。

### 4.3 实现方法

1. 子类可以实现父类的抽象方法，但不能覆盖父类的非抽象方法
2. 子类中可以增加自己特有的方法

## 5.依赖倒置原则

### 5.1 定义

依赖倒置原则的原始定义为：高层模块不应该依赖低层模块，两者都应该依赖其抽象；抽象不应该依赖细节，细节应该依赖抽象。其核心思想是：**要面向接口编程，不要面向实现编程**。

### 5.2 作用

1.	可以降低类间的耦合性。
2.	可以提高系统的稳定性。
3.	可以减少并行开发引起的风险。

4. 可以提高代码的可读性和可维护性。

### 5.3 实现方法

![img_53](https://img.zhaojq.top/20260727091842109.png "img_53")



## 6.迪米特法则

### 6.1 定义

迪米特法则又叫作**最少知识原则**,   迪米特法则的定义是：**只与你的直接朋友交谈，不跟“陌生人”说话**。其含义是：如果两个软件实体无须直接通信，那么就不应当发生直接的相互调用，可以通过第三方转发该调用。其目的是降低类之间的耦合度，提高模块的相对独立性。

### 6.2 优点

1.	降低了类之间的耦合度，提高了模块的相对独立性。

2. 由于亲合度降低，从而提高了类的可复用性和系统的扩展性。

### 6.3 实现方法

1.	从依赖者的角度来说，只依赖应该依赖的对象。

2. 从被依赖者的角度说，只暴露应该暴露的方法。

![img_54](https://img.zhaojq.top/20260727091842272.png "img_54")



## 7.合成复用原则

### 7.1 定义

合成复用原则（Composite Reuse Principle，CRP）又叫组合/聚合复用原则
（Composition/Aggregate Reuse Principle，CARP）。它要求在软件复用时，要尽量先使用组合或者聚合等关联关系来实现，其次才考虑使用继承关系来实现。

如果要使用继承关系，则必须严格遵循里氏替换原则。合成复用原则同里氏替换原则相辅相成的，两者都是开闭原则的具体实现规范。

### 7.2 重要性

通常类的复用分为**继承复用**和合成复用两种，继承复用虽然有简单和易实现的优点，但它也存在以下缺点

1.	继承复用破坏了类的封装性
2.	子类与父类的耦合度高

3. 它限制了复用的灵活性

采用合成复用原则时，他可以将已有对象纳入新对象中，使之成为新对象的一部分，新对象可以调用已有对象的功能，它有以下优点。

1.	它维持了类的封装性
2.	新旧类之间的耦合度低

3. 复用的灵活性高

### 7.3 实现方法

合成复用原则是通过将已有的对象纳入新对象中，作为新对象的成员对象来实现的，新对象可以调用已有对象的功能，从而达到复用。

![img_55](https://img.zhaojq.top/20260727091842485.png "img_55")

 从上图 可以看出用继承关系实现会产生很多子类，而且增加新的“动力源”或者增加新的“颜色”都要修改源代码，这违背了开闭原则，显然不可取。但如果改用组合关系实现就能很好地解决以上问题

![img_56](https://img.zhaojq.top/20260727091842807.png "img_56")

