设计模式的六大原则
设计模式的六大原则
1. 单一职责原则 (Single Responsibility Principle, SRP)
一个类应该只负责一项职责。
示例代码
// 不好的设计:一个类承担多个职责
typedef struct {
void (*read_data)(void);
void (*process_data)(void);
void (*save_data)(void);
void (*display_data)(void);
} DataManager;
// 好的设计:职责分离
typedef struct {
void (*read_data)(void);
} DataReader;
typedef struct {
void (*process_data)(void);
} DataProcessor;
typedef struct {
void (*save_data)(void);
} DataStorage;
typedef struct {
void (*display_data)(void);
} DataDisplay;
2. 开闭原则 (Open-Closed Principle, OCP)
软件实体应该对扩展开放,对修改关闭。
示例代码
// 不好的设计:需要修改原有代码来添加新功能
typedef struct {
void (*process)(int type) {
if(type == 1) {
// 处理类型1
} else if(type == 2) {
// 处理类型2
}
// 添加新类型需要修改此处
}
} Processor;
// 好的设计:通过接口扩展
typedef struct {
void (*process)(void* self);
} ProcessorInterface;
typedef struct {
ProcessorInterface base;
// Type1特有属性
} Type1Processor;
typedef struct {
ProcessorInterface base;
// Type2特有属性
} Type2Processor;
// 添加新类型只需要实现接口
3. 里氏替换原则 (Liskov Substitution Principle, LSP)
子类必须能够替换其基类。
示例代码
// 基类
typedef struct {
int (*calculate_area)(void* self);
} Shape;
// 子类必须正确实现基类的行为
typedef struct {
Shape base;
int width;
int height;
} Rectangle;
typedef struct {
Shape base;
int side;
} Square;
// 任何使用Shape的地方都可以使用其子类
void print_area(Shape* shape) {
printf("面积: %d\n", shape->calculate_area(shape));
}
4. 接口隔离原则 (Interface Segregation Principle, ISP)
客户端不应该依赖它不需要的接口。
示例代码
// 不好的设计:一个大而全的接口
typedef struct {
void (*read)(void);
void (*write)(void);
void (*connect)(void);
void (*disconnect)(void);
void (*encrypt)(void);
void (*decrypt)(void);
} DeviceInterface;
// 好的设计:接口分离
typedef struct {
void (*read)(void);
void (*write)(void);
} IOInterface;
typedef struct {
void (*connect)(void);
void (*disconnect)(void);
} ConnectionInterface;
typedef struct {
void (*encrypt)(void);
void (*decrypt)(void);
} CryptoInterface;
5. 依赖倒置原则 (Dependency Inversion Principle, DIP)
高层模块不应该依赖低层模块,两者都应该依赖其抽象。
示例代码
// 不好的设计:直接依赖具体实现
typedef struct {
void (*save_to_file)(const char* data);
} FileStorage;
// 好的设计:依赖抽象接口
typedef struct {
void (*save)(void* self, const char* data);
} StorageInterface;
typedef struct {
StorageInterface interface;
// 文件存储特有属性
} FileStorage;
typedef struct {
StorageInterface interface;
// 数据库存储特有属性
} DatabaseStorage;
// 高层模块依赖StorageInterface,而不是具体实现
6. 迪米特法则 (Law of Demeter, LoD)
一个对象应该对其他对象保持最少的了解。
示例代码
// 不好的设计:对象之间过度耦合
typedef struct {
void (*process_data)(CustomerData* customer,
AccountData* account,
TransactionData* transaction);
} OrderProcessor;
// 好的设计:通过中介者模式减少耦合
typedef struct {
void (*notify)(void* self, const char* event, void* data);
} Mediator;
typedef struct {
Mediator* mediator;
void (*process_order)(void* self);
} OrderProcessor;
typedef struct {
Mediator* mediator;
void (*handle_customer)(void* self);
} CustomerManager;
typedef struct {
Mediator* mediator;
void (*handle_transaction)(void* self);
} TransactionManager;
总结
- 单一职责原则:一个类只做一件事
- 开闭原则:对扩展开放,对修改关闭
- 里氏替换原则:子类可以替换父类
- 接口隔离原则:接口要小而专一
- 依赖倒置原则:依赖抽象而不是具体
- 迪米特法则:降低对象之间的耦合
这六大原则是设计模式的基础,遵循这些原则可以帮助我们写出更好的代码。它们不是硬性规定,而是指导原则,需要根据实际情况灵活运用。