4

我正在帮助开发的程序应该输出几个动态生成的问题供用户回答。这些问题有不同的类型,并有一个相应的类Constraint,它们用用户给定的信息填充。我的问题是如何为不同的约束创建统一的行为。

                    ---->Constraint<--------------------
                    |                  |               |
                  FConstraint        PConstraint    TConstraint
                  |         |
            UConstraint AConstraint

基类Constraint是空的,TConstraint 也是如此。

UConstraintPConstraintAConstraint共享三个变量。但是,UConstraint还有AConstraint一个PConstraint没有的附加变量。

我觉得我正试图用一些钳子锤穿一堵砖墙。我的一个想法是为带有签名的约束提供一种抽象方法:

// All answers are of type string.
abstract void setValue(string variable, string answer);

每个Constraint子类都实现了这些。但是,传递一个字符串来确定要设置哪个变量似乎很容易出错,而且代码味道也很糟糕。

第二个选项是将三个相似的变量向上移动到约束中,但这仍然留下UConstraint, AConstraint了我可能需要设置的额外信息。TConstraint不需要任何这些都无济于事。

我目前的蛮力“搞砸了这个设计”。解决方案是一个instanceof汤,我在其中检查并填写缺少的特定于约束的信息。

Object constraint = item.getConstraint();

if (constraint instanceof AConstraint) {
    AConstraint constraint = (AConstraint) constraint;

    if (constraint.getValue() == null) {
        constraint.setValue(string);
    } else if (constraint.getKey() == null) {
        constraint.setKey(string);
    } // More of the same.
} else if (constraint instanceof PConstraint) {
    // As the above if() group.
} // etc.

这个设计有比抽象函数更好的解决方案吗?

4

5 回答 5

3

使用这个原则

在接口中编程,将不断变化的行为封装在抽象类或接口中。

例如:对于您上面给出的示例

接口 - 约束

抽象类 - FConstraint

具体类 - PConstraint, TConstraint, UConstraint, AConstraint

于 2012-05-23T18:33:44.230 回答
3

您的问题没有足够的信息来说明您在每种情况下需要做的实际工作,但通常是这样的代码:

Object constraint = item.getConstraint();

if (constraint instanceof AConstraint) {
    // Work
} else if (constraint instanceof PConstraint) {
    // Work
} // etc.

使用多态性并重构为这样的东西是一种强烈的气味:

Constraint constraint = item.getConstraint();
constraint.doWork(...);

其中特定的类看起来像这样:

public class AConstraint {
  public ... doWork(...) {
    if (getValue() == null) {
      setValue(string);
    } else if (getKey() == null) {
      setKey(string);
    } // More of the same.      
  }
}
于 2012-05-23T18:34:37.880 回答
2

你可以这样做:

public interface Constraint{}

public abstract class VariableConstraint implements Constraint 
{ 
  /* hold 3 shared variables here */
}

public class UConstraint extends VariableConstraint{}
public class PConstraint extends VariableConstraint{}
public class AConstraint extends VariableConstraint{}

public abstract class EmptyConstraint implements Constraint {}

public class TConstraint extends EmptyConstraint {}
于 2012-05-23T18:19:28.107 回答
1

在中指定通用功能Constraint:您希望能够对Constraint对象(实际上可能是其中一种子类型的对象)执行的任何操作,您都有一个用于该功能的方法Constraint,您可以在子类中覆盖。

您可以对那些功能没有意义的父类进行简单的(例如空的)实现。

这样你就不需要关心对象的具体类,只需使用超类提供的设施

于 2012-05-23T18:19:15.377 回答
1

Constraint一个接口。定义一个扩展 this 的抽象类,Constraint并且 this 应该具有共享变量。UConstraintAConstraint应该扩展这个具有共享变量的抽象类。其余类可以直接实现Constraint接口。代码实例应更改为

Constraint constraint = item.getConstraint();
constraint.doWork(..);

更好的设计总是针对接口编写代码

于 2012-05-23T18:26:24.840 回答