Java 中的扩展对象模式:灵活地增强对象功能
也称为
- 接口扩展
扩展对象设计模式的意图
扩展对象模式允许灵活地扩展对象的行为,而无需修改其结构,方法是附加额外的对象,这些对象可以动态地添加新功能。
扩展对象模式的详细说明,包含现实世界示例
现实世界示例
在模块化厨房电器中可以找到扩展对象设计模式的类似现实世界示例。考虑一个基本的搅拌机单元,可以添加不同的附件,例如食品处理器、榨汁机或研磨机。每个附件都为搅拌机添加了新功能,而无需改变基本单元本身。用户可以根据当前需求动态地在不同功能之间切换,这使得搅拌机高度灵活,可以适应各种任务。这反映了软件中的扩展对象模式,其中新功能被动态地且上下文地添加到对象中,从而增强了灵活性并提高了重用性。
通俗易懂
扩展对象模式用于动态地向对象添加功能,而无需修改其核心类。它是一种行为设计模式,用于在程序中向现有的类和对象添加新功能。该模式使程序员能够扩展/修改类功能,而无需重构现有的源代码。
维基百科说
在面向对象的计算机编程中,扩展对象模式是一种设计模式,在原始对象编译后添加到对象中。修改后的对象通常是一个类、一个原型或一个类型。扩展对象模式是某些面向对象编程语言的特性。调用扩展方法与调用在类型定义中声明的方法之间没有语法差异。
Java 中扩展对象模式的编程示例
扩展对象模式允许灵活地扩展对象的行为,而无需修改其结构,方法是附加额外的对象,这些对象可以动态地添加新功能。
在这个 Java 实现中,我们有三种类型的单位:SoldierUnit
、SergeantUnit
和 CommanderUnit
。每个单位都可以有提供附加功能的扩展。扩展是 SoldierExtension
、SergeantExtension
和 CommanderExtension
。
Unit
类是所有单位的基类。它有一个方法 getUnitExtension
,该方法根据扩展名称返回一个扩展对象。
public abstract class Unit {
private String name;
protected Unit(String name) {
this.name = name;
}
public String getName() {
return name;
}
public abstract UnitExtension getUnitExtension(String extensionName);
}
UnitExtension
接口是所有扩展的基接口。每个特定的扩展都将实现此接口。
public interface UnitExtension {
String getName();
}
SoldierUnit
类是一种特定类型的单位。它覆盖了 getUnitExtension
方法以返回一个 SoldierExtension
对象。
public class SoldierUnit extends Unit {
public SoldierUnit(String name) {
super(name);
}
@Override
public UnitExtension getUnitExtension(String extensionName) {
if ("SoldierExtension".equals(extensionName)) {
return new SoldierExtension(this);
}
return null;
}
}
SoldierExtension
类是一种特定类型的扩展。它实现了 UnitExtension
接口,并为 SoldierUnit
提供了附加功能。
public class SoldierExtension implements UnitExtension {
private SoldierUnit unit;
public SoldierExtension(SoldierUnit unit) {
this.unit = unit;
}
@Override
public String getName() {
return "SoldierExtension";
}
public void soldierReady() {
// additional functionality for SoldierUnit
}
}
在 main
应用程序中,我们创建了不同类型的单位,并检查每个单位是否具有扩展。如果扩展存在,则调用扩展对象上的特定方法。
public class App {
public static void main(String[] args) {
var soldierUnit = new SoldierUnit("SoldierUnit1");
var sergeantUnit = new SergeantUnit("SergeantUnit1");
var commanderUnit = new CommanderUnit("CommanderUnit1");
checkExtensionsForUnit(soldierUnit);
checkExtensionsForUnit(sergeantUnit);
checkExtensionsForUnit(commanderUnit);
}
private static void checkExtensionsForUnit(Unit unit) {
var extension = "SoldierExtension";
Optional.ofNullable(unit.getUnitExtension(extension))
.map(e -> (SoldierExtension) e)
.ifPresentOrElse(SoldierExtension::soldierReady, () -> System.out.println(unit.getName() + " without " + extension));
}
}
这将产生以下控制台输出。
22:58:03.779 [main] INFO concreteextensions.Soldier -- [Soldier] SoldierUnit1 is ready!
22:58:03.781 [main] INFO App -- SoldierUnit1 without SergeantExtension
22:58:03.782 [main] INFO App -- SoldierUnit1 without CommanderExtension
22:58:03.782 [main] INFO App -- SergeantUnit1 without SoldierExtension
22:58:03.783 [main] INFO concreteextensions.Sergeant -- [Sergeant] SergeantUnit1 is ready!
22:58:03.783 [main] INFO App -- SergeantUnit1 without CommanderExtension
22:58:03.783 [main] INFO App -- CommanderUnit1 without SoldierExtension
22:58:03.783 [main] INFO App -- CommanderUnit1 without SergeantExtension
22:58:03.783 [main] INFO concreteextensions.Commander -- [Commander] CommanderUnit1 is ready!
此示例演示了扩展对象模式如何允许灵活地扩展对象的 behavior,而无需修改其结构。
扩展对象模式的详细说明,包含现实世界示例

何时在 Java 中使用扩展对象模式
这种模式适用于需要在运行时扩展对象的功能的场景,从而避免了子类化的复杂性。它在需要在部署后增强对象功能的系统中特别有用,或者在功能可能在不同实例之间有很大差异的系统中特别有用。
Java 中扩展对象模式的现实世界应用
- 在应用程序服务器中扩展服务,而无需更改现有代码。
- IntelliJ IDEA 或 Eclipse 等 IDE 中的插件,为基本应用程序添加功能。
- 根据许可级别在企业软件中启用附加功能。
- OpenDoc
- 对象链接和嵌入
扩展对象模式的优势和权衡
优势
- 通过允许动态扩展对象的 capabilities 来增强灵活性。
- 促进基本对象与其扩展之间的松耦合。
- 通过保持对象对扩展开放,但对修改关闭,支持开闭原则。
权衡
- 由于需要管理扩展对象,因此可能会增加复杂性。
- 如果对象和扩展之间的交互没有被有效地设计,则可能会导致性能开销。