【问题标题】:Which design pattern to be used?使用哪种设计模式?
【发布时间】:2014-04-23 14:59:16
【问题描述】:

我正面临一个与课程设计相关的基本问题,我确信这很常见,但我没有令人信服的答案。所以这是我的问题。先放代码sn-p

public interface Value {
    void setValue(Object value);
    Object getValue();
}

public interface SimpleValue extends Value {
    void validate();
}

public interface CompoundValue extends Value{
    void setValueAt(int position, Value value);
    Value getValueAt(int position);
    void addValue(Value value);
    List<Value> getValues();
}

public class IntValue implements SimpleValue {
    @Override
    public void setValue(Object value) {
        // TODO Auto-generated method stub
    }
    @Override
    public Object getValue() {
        // TODO Auto-generated method stub
        return null;
    }
    @Override
    public void validate() {
        // TODO Auto-generated method stub
    }
}

public class ComplexValue implements CompoundValue {
    private List<Value>  values;
    @Override
    public void setValue(Object value) {
        //Not useful
    }
    @Override
    public Object getValue() {
        //not useful
        return null;
    }
    @Override
    public void setValueAt(int position, Value value) {
        values.set(position, value);
    }
    @Override
    public Value getValueAt(int position) {
        return values.get(position);
    }
    @Override
    public List<Value> getValues() {
        return values;
    }
    @Override
    public void addValue(Value value) {
        values.add(value);
    }
}

public class Main {
    public static void main(String[] args) {
        Value simpleValue = new IntValue();
        Value simpleValue2 = new IntValue();
        ComplexValue complexValue = new ComplexValue();
        Value simpleValue3 = new IntValue();
        complexValue.addValue(simpleValue3);
        ComplexValue complexValue2 = new ComplexValue();
        complexValue2.addValue(simpleValue);
        complexValue2.addValue(simpleValue2);
        complexValue2.addValue(complexValue);
        Value value = complexValue2.getValueAt(2);
        if (value instanceof ComplexValue) {
            ComplexValue compValue = (ComplexValue) value;
            Value finalValue = complexValue.getValueAt(0);
        }
    }
}

如您所见,我有一个接口“Value”,它有两种变体,一种包含实际值,如“IntValue”,另一种可以包含多个值。这些值可以是 simpleValue 或 CompoundValue 对象

我的问题是处理一个 ComplexValue 对象,我总是必须检查它的实际类并相应地进行类型转换以获得它们的功能,从设计的角度来看,这看起来不是一个体面的 API 设计。

如果有人能指导我针对此问题提供合适的设计指南或任何要在此处使用的设计模式,我将不胜感激。

谢谢。

【问题讨论】:

  • 如果我告诉您 SimpleValue 是大小为 1 的 ComplexValue 对您有帮助吗?

标签: java design-patterns


【解决方案1】:

这是一个简短的答案,但一般来说,解决这类问题的方法是使用多态性。

您有这两种不同类型的值,并且您的代码逻辑根据类型执行不同的操作。现在,您通过决策“在外部”执行此操作:

if(theValue instanceof CompoundValue) {
    // perform CompoundValue action
} else if(theValue instanceof SimpleValue) {
    // perform SimpleValue action
}

theValue 已经知道它是一种什么样的价值。所以通常处理这个问题的方法是在界面中包含这个动作,例如:

interface PolyValue extends Value {
    public void perform();
}

现在你有了 CompoundValue:

class CompoundValue implements PolyValue {
    @Override
    public void perform() {
        // perform CompoundValue action
    }
    ...
}

还有简单值:

class SimpleValue implements PolyValue {
    @Override
    public void perform() {
        // perform SimpleValue action
    }
    ...
}

有很多设计模式可以处理这种情况。

仅举几例。这三个是同一个想法的变体,关键是要摆脱决策逻辑。

【讨论】:

    【解决方案2】:

    唯一的解决方案是在基值接口中提供通用或共享方法,并以特定方式为每个具体类多态地处理对通用方法的调用。如果无法做到这一点,那么您必须在使用时执行强制转换。泛型在这里帮不了你。

    但是,我可能会建议一种不同的方法。为什么不简单地将特殊情况 SimpleValue 设为大小为 1 的 CompoundValue?那么你只需要一个值接口,你可以有一个具体的ComplexValue类实现Value,一个SimpleValue类扩展ComplexValue并填充方法,使大小始终为1。

    【讨论】:

      【解决方案3】:

      为什么 get/setValue 方法在 ComplexValue 中没有“用处”?让它们有用。 我不知道你的目标是什么,但从看起来的方式来看,你可以做到这一点 public Object getValue() { return getValueAt(0); }

      然后您可以删除类型转换并简单地调用 Value.getValue()

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多