java设计模式之合成复用原则使用举例
·
一、核心思想与优势
-
核心思想
优先使用对象组合(has-a)或聚合(contains-a)实现代码复用,而非继承(is-a)。通过将已有对象作为新对象的成员变量,动态调用其功能。 -
优势
- 降低耦合度:组合关系隐藏了成员对象的内部细节(黑箱复用),减少类间的直接依赖。
- 增强灵活性:可在运行时动态替换成员对象,无需修改原有代码(如依赖注入)。
- 符合开闭原则:扩展新功能时,通常只需新增类,无需修改现有代码。
二、典型应用场景与示例
- 数据库连接管理
- 问题:若
UserDao直接继承DBConnection,切换数据库(如从MySQL改为Oracle)需修改继承关系,导致高耦合。 - 合成复用实现
效果:新增// 定义接口 interface DatabaseConnection { String getConnection(); } // 具体实现类 class MySQLConnection implements DatabaseConnection { public String getConnection() { return "MySQL连接"; } } // 组合使用 class UserDao { private DatabaseConnection connection; public UserDao(DatabaseConnection connection) { this.connection = connection; } public void addData() { String conn = connection.getConnection(); System.out.println("使用" + conn + "操作数据库"); } }OracleConnection时,只需注入不同实现,无需修改UserDao。
- 图形绘制系统
- 问题:若通过继承实现不同图形(如圆形、矩形),新增“阴影效果”需为每种图形创建子类,导致类爆炸。
- 合成复用实现
效果:动态为任意图形添加阴影,无需修改原有类。// 定义图形接口 interface Shape { void draw(); } // 具体图形类 class Circle implements Shape { public void draw() { System.out.println("绘制圆形"); } } // 组合装饰器 class ShadowDecorator implements Shape { private Shape shape; public ShadowDecorator(Shape shape) { this.shape = shape; } public void draw() { shape.draw(); System.out.println("添加阴影效果"); } }
- 汽车分类管理
- 问题:若通过继承按“动力源”(汽油/电动)和“颜色”(红/黑)组合子类,新增颜色或动力源需新增多个子类。
- 合成复用实现
效果:新增动力源(如电力)只需实现// 组合属性 class Car { private EnergySource energy; private Color color; public Car(EnergySource energy, Color color) { this.energy = energy; this.color = color; } public void move() { System.out.println(color.getName() + energy.getName() + "汽车行驶"); } } // 动力源接口及实现 interface EnergySource { String getName(); } class Gasoline implements EnergySource { public String getName() { return "汽油"; } }EnergySource接口,无需修改Car类。
- 用户行为扩展(策略模式)
- 问题:若
Animal类直接包含固定行为(如狗吠、猫叫),新增行为需修改父类代码。 - 合成复用实现
效果:通过注入不同// 行为接口 interface SoundBehavior { void makeSound(); } // 动态组合行为 class Animal { private SoundBehavior behavior; public Animal(SoundBehavior behavior) { this.behavior = behavior; } public void performSound() { behavior.makeSound(); } } // 具体行为类 class Bark implements SoundBehavior { public void makeSound() { System.out.println("汪汪"); } }SoundBehavior实现动态行为切换。
三、总结
合成复用原则通过对象组合替代继承,解决了继承导致的高耦合、低扩展性问题。典型应用包括:
- 依赖注入(如Spring中Controller注入Service)。
- 装饰器模式(动态扩展功能)。
- 策略模式(算法或行为的灵活替换)。
实践建议:在设计时优先考虑“has-a”关系,仅在需要明确分类关系时(如子类是父类的逻辑扩展)使用继承。
更多推荐


所有评论(0)