多态推导派生类型

时间:2018-12-17 05:39:04

标签: java design-patterns polymorphism clean-architecture

对于以下情况,推荐的设计方法是什么/替代方法:

BaseCalculator:
BaseType prepareData()
useData(BaseType)

派生计算器使用派生类型来覆盖基本功能-

DerivedCalculator1:
BaseType prepareData(){ return DerivedType1}
useData(BaseType t1){ DerivedType1 t=(DerivedType1)t1 //typecast  down and proceed....}

DerivedCalculator2
BaseType prepareData(){ return DerivedType2}
useData(BaseType t1){ DerivedType2 t=(DerivedType2)t1 //typecast down and proceed....}

是否有一种设计方法来避免派生类进行类型转换-因为它总是为运行时的事故打开大门?

1 个答案:

答案 0 :(得分:0)

一种选择是将多态行为移至BaseType的实现中,而不是BaseCalculator的实现中。例如:

public interface BaseType {
    public void process(Calculator calc);
}

public class DerivedType1 implements BaseType {

    @Override
    public void process(Calculator calc) {
        // Do something specific to derived type 1
    }
}

public class DerivedType2 implements BaseType {

    @Override
    public void process(Calculator calc) {
        // Do something specific to derived type 2
    }
}

public class Calculator {

    public void doSomething(BaseType bt) {
        bt.process(this);
    }
}

如果该类型的解决方案不足,则更复杂的解决方案是Visitor Pattern。访客模式允许任意任意BaseType使用double-dispatch处理任意BaseCalculator对象。问题在于,所有BaseCalculator实现都必须有一个方法来处理每个BaseType实现。例如:

public interface BaseType {
    public void process(Calculator calc);
}

public class DerivedType1 implements BaseType {

    @Override
    public void process(Calculator calc) {
        // Do something specific to derived type 1
    }
}

public class DerivedType2 implements BaseType {

    @Override
    public void process(Calculator calc) {
        // Do something specific to derived type 2
    }
}

public interface BaseCalculator {
    public void handle(DerivedType1 dt);
    public void handle(DerivedType2 dt);
}

public class DerviedCalculator1 implements BaseCalculator {

    @Override
    public void handle(DerivedType1 dt) {
        dt.process(this);
    }

    @Override
    public void handle(DerivedType2 dt) {
        dt.process(this);
    }
}

public class DerviedCalculator2 implements BaseCalculator {

    @Override
    public void handle(DerivedType1 dt) {
        dt.process(this);
    }

    @Override
    public void handle(DerivedType2 dt) {
        dt.process(this);
    }
}