Java 中的子类沙箱模式:使用沙箱技术增强代码可重用性
大约 3 分钟
也称为
- 钩子方法
子类沙箱设计模式的意图
Java 中的子类沙箱设计模式允许子类通过提供某些方法的特定实现来改变类的核心行为,同时保持整体结构不变。
子类沙箱模式的详细解释,附带现实世界示例
现实世界示例
想象一个烹饪课,老师提供一个标准的食谱结构,包括“准备食材”、“烹饪”和“上菜”等步骤。每个学生都遵循这个结构,但可以定制具体的步骤来创造自己独特的菜肴。例如,一个学生可能选择准备沙拉,而另一个学生可能选择准备炒菜,两者都遵循相同的食谱格式。这样,老师可以确保所有菜肴都遵循一致的流程,但学生可以灵活地个性化他们食谱的关键部分。这反映了子类沙箱模式,其中核心结构由超类定义,而具体的行为在子类中定制。
通俗地说
子类沙箱模式允许子类在超类提供的预定义算法结构内定制特定行为。
gameprogrammingpatterns.com 表示
基类定义了一个抽象的沙箱方法和几个提供的操作。将它们标记为受保护的可以清楚地表明它们是供派生类使用。每个派生沙箱子类使用提供的操作实现沙箱方法。
Java 中子类沙箱模式的编程示例
使用子类沙箱模式,开发人员可以在 Java 应用程序中创建不同的功能,从而增强游戏开发和软件设计。
假设您想在一个游戏中创建各种超能力,每个超能力都需要以声音效果移动并生成粒子。您应该创建许多具有类似方法的类还是从基类派生它们?子类沙箱模式使您能够通过从公共基类派生这些类来有效地处理这个问题。
我们从基类 Superpower
开始。它包含一个抽象的沙箱方法 active
和一些提供的操作。
public abstract class Superpower {
protected Logger logger;
protected abstract void activate();
protected void move(double x, double y, double z) {
logger.info("Move to ( " + x + ", " + y + ", " + z + " )");
}
protected void playSound(String soundName, int volume) {
logger.info("Play " + soundName + " with volume " + volume);
}
protected void spawnParticles(String particleType, int count) {
logger.info("Spawn " + count + " particle with type " + particleType);
}
}
接下来,我们可以创建派生沙箱子类,它使用提供的操作来实现沙箱方法。这是第一个力量
public class SkyLaunch extends Superpower {
public SkyLaunch() {
super();
logger = LoggerFactory.getLogger(SkyLaunch.class);
}
@Override
protected void activate() {
move(0, 0, 20);
playSound("SKYLAUNCH_SOUND", 1);
spawnParticles("SKYLAUNCH_PARTICLE", 100);
}
}
这是第二个力量。
public class GroundDive extends Superpower {
public GroundDive() {
super();
logger = LoggerFactory.getLogger(GroundDive.class);
}
@Override
protected void activate() {
move(0, 0, -20);
playSound("GROUNDDIVE_SOUND", 5);
spawnParticles("GROUNDDIVE_PARTICLE", 20);
}
}
最后,这些超能力处于活动状态。
public static void main(String[] args) {
LOGGER.info("Use superpower: sky launch");
var skyLaunch = new SkyLaunch();
skyLaunch.activate();
LOGGER.info("Use superpower: ground dive");
var groundDive = new GroundDive();
groundDive.activate();
}
程序输出
13:10:23.177 [main] INFO com.iluwatar.subclasssandbox.App -- Use superpower: sky launch
13:10:23.179 [main] INFO com.iluwatar.subclasssandbox.SkyLaunch -- Move to ( 0.0, 0.0, 20.0 )
13:10:23.180 [main] INFO com.iluwatar.subclasssandbox.SkyLaunch -- Play SKYLAUNCH_SOUND with volume 1
13:10:23.180 [main] INFO com.iluwatar.subclasssandbox.SkyLaunch -- Spawn 100 particle with type SKYLAUNCH_PARTICLE
13:10:23.180 [main] INFO com.iluwatar.subclasssandbox.App -- Use superpower: ground dive
13:10:23.180 [main] INFO com.iluwatar.subclasssandbox.GroundDive -- Move to ( 0.0, 0.0, -20.0 )
13:10:23.180 [main] INFO com.iluwatar.subclasssandbox.GroundDive -- Play GROUNDDIVE_SOUND with volume 5
13:10:23.180 [main] INFO com.iluwatar.subclasssandbox.GroundDive -- Spawn 20 particle with type GROUNDDIVE_PARTICLE
何时在 Java 中使用子类沙箱模式
- 当您想创建一个框架,允许用户通过扩展类来定义自己的行为时使用。
- 适用于您需要强制执行特定算法结构,但允许覆盖某些步骤的场景。
Java 中子类沙箱模式的现实世界应用
- GUI 框架中的模板方法模式,其中框架提供结构,而子类实现细节。
- 游戏开发,其中定义了核心游戏循环,但特定行为由子类提供。
- 像
AbstractList
这样的 Java 库,其中定义了核心方法,并且可以通过扩展类来定制某些行为。
子类沙箱模式的优缺点
优点
Java 中的子类沙箱模式
- 通过允许超类中共享代码来鼓励代码重用。
- 通过子类化简化了新行为的添加。
- 通过将算法的结构与特定实现分离,增强了代码可读性和可维护性。
缺点
- 可能导致大量子类。
- 需要仔细设计以确保基类足够灵活以适应各种扩展。
- 由于多层继承,增加了理解代码流程的复杂性。