如何重构Java静态形状数据库以区分2D与3D图形?
区分2D与3D图形的最优面向对象方案选择
针对你的图形识别应用需求,三个方案的优劣分析如下:
方案1:使用枚举标记图形维度
- 优点:改动成本极低,只需给
ShapeData新增一个ShapeType枚举字段(D2/D3),就能快速实现UI的按钮区分逻辑。 - 缺点:语义不严谨,2D图形依然会携带
volumeFormula字段(哪怕存的是面积公式),违背单一职责原则;后续扩展新属性(比如2D的周长、3D的表面积)时,类会变得臃肿,维护难度上升。
方案2:使用继承拆分2D/3D图形
- 优点:语义最清晰,完全解决字段语义错误问题。抽象父类
ShapeData存放通用属性(描述、同义词),子类Shape2D专属areaFormula,Shape3D专属volumeFormula;后续扩展新属性时,只需在对应子类添加,符合开闭原则,长期维护成本最低。 - 缺点:需要对现有代码做中等程度的重构,但重构逻辑简单,收益长远。
方案3:使用可空字段区分
- 优点:改动最小,直接把
volumeFormula拆成areaFormula和volumeFormula,2D图形设volumeFormula = null,3D图形设areaFormula = null。 - 缺点:调用时必须频繁判断字段是否为null,极易引发空指针异常;类的职责模糊,所有图形属性堆在一个类里,后续扩展会导致字段冗余,代码可读性差。
最优方案推荐:继承方案
从长远维护和语义严谨性来看,继承方案是最优选择。以下是重构后的示例代码:
import java.util.ArrayList; import java.util.List; public class ShapeDatabase { // 抽象父类:存放所有图形的通用属性 public abstract static class ShapeData { public final String description; public final String[] synonyms; ShapeData(String description, String... synonyms) { this.description = description; this.synonyms = synonyms; } } // 2D图形子类:专属面积公式 public static class Shape2D extends ShapeData { public final String areaFormula; Shape2D(String description, String areaFormula, String... synonyms) { super(description, synonyms); this.areaFormula = areaFormula; } } // 3D图形子类:专属体积公式 public static class Shape3D extends ShapeData { public final String volumeFormula; Shape3D(String description, String volumeFormula, String... synonyms) { super(description, synonyms); this.volumeFormula = volumeFormula; } } private static final List<ShapeData> DATABASE = new ArrayList<>(); static { // 3D图形 DATABASE.add(new Shape3D("The cube...", "Volume = a^3", "CUBE")); // 2D图形 DATABASE.add(new Shape2D("The square...", "Area = a^2", "SQUARE")); } // UI层区分逻辑示例 public static void renderButton(ShapeData shape) { if (shape instanceof Shape2D) { System.out.println("显示「查看面积」按钮"); } else if (shape instanceof Shape3D) { System.out.println("显示「查看体积」按钮"); } } }
这样重构后,不仅彻底解决了字段语义错误的问题,还为后续功能扩展(比如给2D图形加周长公式、给3D图形加表面积公式)预留了清晰的扩展路径。
内容的提问来源于stack exchange,提问作者Loud
相关产品推荐
相关产品推荐

