java - 通过创建依赖于特定条件的对象来避免 If-else 代码异味

标签 java oop design-patterns instanceof java-6

有没有比使用 if-else 和 instanceof 如下代码所示?

import java.util.ArrayList;
import java.util.List;

abstract class AbstractProduct {
    private AbstractCondition condition;
    public AbstractProduct(AbstractCondition condition) {
        this.condition = condition;
    }
    public abstract void doSomething();
}

class ProductA extends AbstractProduct {
    AbstractCondition condition;
    public ProductA(AbstractCondition condition) {
        super(condition);
    }

    @Override
    public void doSomething() {
        System.out.println("I'm Product A");
    }
}

class ProductB extends AbstractProduct {    
    public ProductB(AbstractCondition condition) {
        super(condition);
    }   

    @Override
    public void doSomething() {
        System.out.println("I'm Product B");
    }
}

class AbstractCondition { }

class ConditionA extends AbstractCondition { }

class ConditionB extends AbstractCondition { }

public class Try {
    public static void main(String[] args) {
        List<AbstractCondition> conditions = new ArrayList<AbstractCondition>();
        List<AbstractProduct> products = new ArrayList<AbstractProduct>();

        conditions.add(new ConditionA());               
        conditions.add(new ConditionB());               
        conditions.add(new ConditionB());               
        conditions.add(new ConditionA());

        for (AbstractCondition c : conditions) {
            tryDoSomething(c);
        }
    }

    public static void tryDoSomething(AbstractCondition condition) {
        AbstractProduct product = null;
        if (condition instanceof ConditionA) {
            product = new ProductA(condition);
        } else if (condition instanceof ConditionB) {
            product = new ProductB(condition);
        }
        product.doSomething();
    }
}

我的真实代码与上述代码的区别是:我没有直接控制AbstractCondition及其子类型(因为它们是在库中),但是 AbstractProduct 的具体子类型的创建取决于具体条件。

我的目标是:尽量避免 tryDoSomething() 中的 if-else code smell

我也想避免反射,因为它感觉像是作弊,我确实认为它不是一个优雅、干净和可读的解决方案。

换句话说,我想用良好的 OOP 原则(例如,利用多态性)和 pheraps 一些设计模式(显然我不知道在这种特定情况下)来解决这个问题。

最佳答案

由于无法编辑原始对象,因此需要创建从条件类型到产品类型的静态映射:

private static HashMap< Class<? extends AbstractCondition>, 
                        Class<? extends AbstractProduct>
                      > conditionToProduct;`

用 Condition,Product 对在静态初始化中填充它:

static { 
  conditionToProduct.put(ConditionA.class, ProductA.class); 
  ... 
} 

在运行时只查询 map :

Class<? extends AbstractProduct> productClass = conditionToProduct.get(condition.getClass());
productClass.newInstance();

关于java - 通过创建依赖于特定条件的对象来避免 If-else 代码异味,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40281279/

相关文章:

java - Java.lang.Cloneable 接口(interface)指南的问题

java - JTable 多标题行

使用 BufferedInputStream 读取大文件时 Java 文件 IO 被截断

python - 在Python中,无需重写父类即可更改继承行为

android - 为什么 WhatsApp 这样的应用程序的下载和上传速度不同?

javascript - ES6 将对象映射到装饰器

java - 基于可观察列表动态创建菜单项

python - 动态创建类python的实例

python - 向 Python 线程发送参数会阻塞其他线程

java - 如果在验证规则中使用类型代码,如何进行重构以消除类型代码?