避免使用依赖于特定条件的对象创建的If-else代码气味

1d0*_*n30 5 java oop design-patterns instanceof java-6

是否有更好的方法来处理对象(Product)的实例化,这取决于另一个对象类型(Condition)而不是使用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();
    }
}
Run Code Online (Sandbox Code Playgroud)

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

我的目标是:尽量避免if-else 代码味道tryDoSomething().

我也想避免反思,因为它感觉像作弊,我认为它不是一个优雅,清洁和可读的解决方案.

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

Shl*_*oim 2

AbstractCondition需要了解产品的类型或如何构建产品。

因此添加以下函数之一AbstractCondition

Class<? extends AbstractProduct> getProductClass()

或者

AbstractProduct createProduct()