目录
合成复用原则(Composite Reuse Principle, CRP)是面向对象设计中的一个重要指导原则,强调通过组合(而不是继承)来实现代码复用。它鼓励开发者利用对象的组合关系来增强软件的灵活性和可维护性。
一、概念
1. 合成
合成是一种“拥有关系”,即一个对象可以包含其他对象,形成复合对象。通过这种方式,一个类可以使用其他类的功能,而无需直接继承。
2. 复用
复用指的是通过已有的组件来构建新的功能,而不是从零开始。
二、 合成复用原则的优点
1. 降低耦合度
使用合成可以减少不同模块之间的依赖关系,从而降低耦合度。特别是在大型系统中,低耦合可以提升代码的可维护性。
2. 提高灵活性
通过合成,可以更容易地替换或扩展对象的行为,只需替换组合的组件,而不必修改已有的类结构。
3. 避免继承的复杂性
继承往往会引入复杂的层次结构和潜在的错误,而合成则能提供更灵活和清晰的设计。
三、示例
设计一个图形绘制应用,需要不同类型的形状(如圆形和矩形),我们可能使用继承来创建这些形状。
class Shape {
public void draw() {}
}
class Circle extends Shape {
@Override
public void draw() {
// 绘制圆形
}
}
class Rectangle extends Shape {
@Override
public void draw() {
// 绘制矩形
}
}
在这个设计中,如果我们想为每种形状添加新功能,比如填充颜色,我们可能需要更改现有的类,甚至可能得创建许多子类,这可能导致代码难以维护。 合成复用设计:使用合成,我们可以设计一个 Shape 接口和多个具体的形状类,而将颜色的填充功能提取到一个独立的类中。
interface Shape {
void draw();
}
class Circle implements Shape {
@Override
public void draw() {
// 绘制圆形
}
}
class Rectangle implements Shape {
@Override
public void draw() {
// 绘制矩形
}
}
class ColorFill {
private String color;
public ColorFill(String color) {
this.color = color;
}
public void applyFill(Shape shape) {
// 应用颜色填充到形状
}
}
// 使用组合
class ShapeWithColor {
private Shape shape;
private ColorFill colorFill;
public ShapeWithColor(Shape shape, ColorFill colorFill) {
this.shape = shape;
this.colorFill = colorFill;
}
public void draw() {
shape.draw();
colorFill.applyFill(shape);
}
}
在这个设计中,形状类(如 Circle 和 Rectangle)与填充颜色的功能(ColorFill)是分开的。可以轻松地组合不同的形状和颜色,而不需要创建复杂的类层次结构。