1、引言
1.1 设计模式重要性
软件工程中,设计模式(design pattern)是对软件设计中存在的普遍问题,所提出的解决方案。
设计模式的重要性在于 提升代码质量 和 开发效率,为软件开发提供了一套 成熟、灵活 的工具,能够:
- 减少代码的复杂性和耦合性。
- 提高代码的可读性、可复用性和扩展性。
- 帮助团队协作、实现快速开发。
2、七大设计原则
设计模式需要依托七大设计原则,是因为这些原则提供为设计模式提供了理论基础和指导方向。设计模式的核心目标是解决实际开发中的复杂问题,而设计原则是为代码结构的设计提供了规范,确保代码灵活性、可扩展性和可维护性。通过遵循这些原则,可以设计出更加模块化、低耦合和高内聚的软件架构。
2.1单一职责原则(Single Responsibility Principle)
定义:
一个类应该有一个引起他变化的原因,即一个类只负责一个功能或职责。
目的:
- 降低代码的复杂度。
- 提高类的可读性,可维护性。
- 降低变更引起的风险。
优点:
- 降低耦合性:只做一件事,避免过多职责耦合。
- 增强可维护性:职责明确能够进行修改,不会影响其他功能。
示例:
错误示例:一个类同时负责用户数据管理和日志记录。
class User {
void saveUser() { ... } // 保存用户数据
void logUserAction() { ... } // 日志记录
}
优化:日志功能拆分到单独的类当中。
class User {
void saveUser() { ... }
}
class Logger {
void logUserAction() { ... }
}
2.2 接口隔离原则(Interface Segregate Principle)
定义:
一个类不应该被强迫实现它不需要的接口,即接口应该尽量小而精简。
目的:
- 避免接口臃肿,确保类只实现需要的功能。
- 提高系统的灵活性。
优点:
- 减少代码冗余。
- 降低类的复杂程度。
示例:
错误示范:
interface Animal {
void eat();
void fly(); // 对不能飞的动物不合理
}
class Dog implements Animal {
void eat() { ... }
void fly() { throw new UnsupportedOperationException(); }
}
优化:拆分为多个接口
interface Eatable { void eat(); }
interface Flyable { void fly(); }
class Dog implements Eatable {
void eat() { ... }
}
2.3 依赖倒转原则(Dependency Inversion Principle)
定义:
高层模块不应该依赖底层模块,二者都应该依赖于抽象,抽象不应该依赖细节,细节应该依赖抽象。
目的:
- 减少模块之间的耦合。
- 方便进行模块的替换和测试。
示例:
错误示范:高层代码依赖底层代码
class MySQLDatabase {
void connect() { ... }
}
class App {
void run() {
MySQLDatabase db = new MySQLDatabase();
db.connect();
}
}
优化:通过接口依赖抽象。
interface Database {
void connect();
}
class MySQLDatabase implements Database {
void connect() { ... }
}
class App {
private Database db;
App(Database db) { this.db = db; }
void run() { db.connect(); }
}
2.4 里氏替换原则( Liskov Substitution Principle )
定义:
子类能够替换掉父类,而不会影响程序的正确性。
目的:
确保类之间的继承关系正确合理,避免因子类修改导致程序错误。
优点:
- 确保子类的行为符合父类的约定。
- 提高代码的可靠性和稳定性。
示例:
错误示范:子类破坏父类的行为。
class Rectangle {
void setWidth(int w) { ... }
void setHeight(int h) { ... }
}
class Square extends Rectangle {
void setWidth(int w) { ... } // 破坏了矩形的行为
}
优化:去掉不合理的继承,改为组合。
class Rectangle { ... }
class Square {
private Rectangle rect;
// 通过组合实现宽高设置
}