基于SOLID原则,Java中面向对象地仅对特定Result子类执行操作的方法
基于SOLID原则的Java面向对象实现方案
你当前的代码通过instanceof判断子类类型来执行保存操作,违反了开闭原则(新增需要保存的子类时必须修改判断逻辑)和单一职责原则(WorkerMethod同时承担业务处理、类型判断、保存调用多个职责)。以下是几种符合SOLID的优化方案:
方案一:多态内聚职责(推荐,可修改Result类时使用)
将是否保存、获取保存数据的逻辑交给各个Result子类自己负责,父类定义统一抽象方法:
- 定义抽象Result类:
public abstract class Result { // 其他公共业务方法 public abstract boolean shouldSave(); public abstract String getDataToSave(); }
- 子类实现抽象方法:
// 需要保存的子类 public class ModelResult extends Result { @Override public boolean shouldSave() { return true; } @Override public String getDataToSave() { return this.getModelSpecificData(); // 返回当前子类的待保存数据 } private String getModelSpecificData() { // 子类自身的数据逻辑 return "model_result_data"; } } // 不需要保存的子类 public class OtherResult extends Result { @Override public boolean shouldSave() { return false; } @Override public String getDataToSave() { return null; // 或抛出UnsupportedOperationException,根据业务选择 } }
- 简化WorkerMethod:
public void WorkerMethod(Result result) { // 业务处理代码 // ... if (result.shouldSave()) { databaseClient.saveStringData(result.getDataToSave()); } }
这种方式完全符合开闭原则:新增需要保存的子类时,只需实现shouldSave()返回true,无需修改WorkerMethod;同时每个子类管理自身的保存相关逻辑,符合单一职责。
方案二:访问者模式(保存逻辑与Result解耦时使用)
如果保存逻辑依赖外部服务(如databaseClient),不想让Result子类耦合这些外部依赖,可使用访问者模式分离职责:
- 定义访问者接口:
public interface ResultVisitor { void visit(ModelResult result); void visit(DataResult result); void visit(OtherResult result); // 覆盖所有Result子类 }
- 修改Result抽象类添加accept方法:
public abstract class Result { // 其他公共方法 public abstract void accept(ResultVisitor visitor); }
- 子类实现accept方法:
public class ModelResult extends Result { @Override public void accept(ResultVisitor visitor) { visitor.visit(this); } // 子类自身的数据方法 public String getModelData() { return "model_data"; } }
- 实现保存逻辑的访问者:
public class SaveResultVisitor implements ResultVisitor { private DatabaseClient databaseClient; public SaveResultVisitor(DatabaseClient databaseClient) { this.databaseClient = databaseClient; } @Override public void visit(ModelResult result) { databaseClient.saveStringData(result.getModelData()); } @Override public void visit(DataResult result) { databaseClient.saveStringData(result.getData()); } @Override public void visit(OtherResult result) { // 不需要保存,空实现 } }
- WorkerMethod调用:
public void WorkerMethod(Result result) { // 业务处理代码 // ... ResultVisitor saveVisitor = new SaveResultVisitor(databaseClient); result.accept(saveVisitor); }
该方案将保存逻辑集中在SaveResultVisitor中,Result子类无需关注保存细节,符合单一职责;新增子类时只需扩展访问者接口和实现,对原有业务代码侵入较小。
方案三:策略模式(无法修改Result类时使用)
如果不能修改Result父类,可通过策略模式将类型判断和保存逻辑分离到独立策略类中:
- 定义保存策略接口:
public interface ResultSaveStrategy { boolean supports(Result result); void save(Result result, DatabaseClient client); }
- 实现具体策略类:
public class ModelResultSaveStrategy implements ResultSaveStrategy { @Override public boolean supports(Result result) { return result instanceof ModelResult; } @Override public void save(Result result, DatabaseClient client) { ModelResult modelResult = (ModelResult) result; client.saveStringData(modelResult.getModelData()); } } public class DataResultSaveStrategy implements ResultSaveStrategy { @Override public boolean supports(Result result) { return result instanceof DataResult; } @Override public void save(Result result, DatabaseClient client) { DataResult dataResult = (DataResult) result; client.saveStringData(dataResult.getData()); } }
- 创建策略管理器:
public class ResultSaveManager { private final List<ResultSaveStrategy> strategies; public ResultSaveManager() { this.strategies = Arrays.asList( new ModelResultSaveStrategy(), new DataResultSaveStrategy() ); } public void saveIfSupported(Result result, DatabaseClient client) { for (ResultSaveStrategy strategy : strategies) { if (strategy.supports(result)) { strategy.save(result, client); break; } } } }
- WorkerMethod调用:
public void WorkerMethod(Result result) { // 业务处理代码 // ... ResultSaveManager saveManager = new ResultSaveManager(); saveManager.saveIfSupported(result, databaseClient); }
该方案避免了在WorkerMethod中硬编码instanceof判断,新增需要保存的子类时只需添加新的策略类并注册到管理器,符合开闭原则。
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

