我正面临一个基本的课堂设计相关问题,我确信这很常见,但我没有一个令人信服的答案。所以这就是我的问题。我先把代码片段放在
上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);
}
}
}
所以当你看到我有一个界面&#34;价值&#34;它有两个变体,一个包含实际值,如&#34; IntValue&#34;和其他可以保持多个价值观的人。这些值可以是simpleValue或CompoundValue对象
我的问题是处理一个ComplexValue对象,我总是要检查它的实际类和相应的类型转换,以获得它们的功能,从设计的角度来看,它看起来不是一个不错的API设计。
如果有人能够指导我针对此问题的合适设计指南或此处使用的任何设计模式,我将非常感激。
感谢。
答案 0 :(得分:3)
这是一个小小的答案,但一般来说,这类事情的解决方案是使用多态。
您拥有这两种不同类型的Value,并且您拥有根据类型执行不同类型的代码逻辑。现在你正在做这个&#34;在外面&#34;通过决策:
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
}
...
}
和SimpleValue:
class SimpleValue implements PolyValue {
@Override
public void perform() {
// perform SimpleValue action
}
...
}
有许多设计模式可以解决这种情况。
仅举几例。这三个是同一个想法的变体,重点是摆脱决策逻辑。
答案 1 :(得分:0)
唯一的解决方案是在基值接口中提供泛型或共享方法,并以特定方式为每个具体类多态地处理对泛型方法的调用。如果无法完成,则必须在使用时执行强制转换。泛型在这里不会帮助你。
但是,我可能会建议采用不同的方法。为什么不是简单的特殊情况SimpleValue是一个大小为1的CompoundValue?然后你只需要一个值接口,你可以拥有一个实现Value的具体ComplexValue类,以及一个SimpleValue类,它扩展ComplexValue并填充方法,使得大小始终为1.
答案 2 :(得分:0)
为什么get / setValue方法在ComplexValue中不“有用”?让它们有用。
我不知道你的目标是什么,但从看起来的方式来看,你可以做到这一点
public Object getValue() {
return getValueAt(0);
}
然后你可以删除类型转换并只需调用 Value.getValue()