给定场景的类/接口设计方法

时间:2014-01-20 10:56:40

标签: java oop design-patterns class-design

我有10-15种不同类型的结果来计算说AResult,BResult等。所有结果计算返回单一类型的值(考虑integer值)。 为了计算这些,我需要输入参数,这些参数最常见,但有些需要不同的输入参数如下:

Input parameters example:
    AResult needs  int x, int y, int a[], int b[]
    BResult needs  int x, int y, int a[], boolean c
    CResult needs  int x, int y, int a[], boolean c, boolean d
    DResult needs  int x, int y, int p[], boolean e
    .....

注意在某些情况下,一次计算的结果也用于其他结果计算,但这只是在少数情况下而不是全部。

我这样做的方法是通过 Approach1 ,如下所示:

方法1:

我正在定义一个接口,该接口具有单个方法来计算取InputParameter obj的结果。在实现类中,我将从InputParameter obj中提取出适用于该特定类型结果的值。以下是我的示例代码的片段:

public interface Result {
    int calculate(InputParameter obj);
}

public class AResult implements Result {
    public int calculate(InputParameter obj){
      // code
     }

}

public class BResult implements Result {
    public int calculate(InputParameter obj)){
      // code
     }


}

public class InputParameter {
    int x;
    int y;
    int z;
    int a[];
    int b[];
    int p[];
    boolean c;
    boolean d;
    boolean e;
    ....
    // Getters and Setters
}

例如,假设我创建了一个InputParameter对象并设置了所有字段的值。我将此对象传递给aResultObject.calculate(InputParameter obj),dResultObject.calculate(InputParameter obj)等等。

AResult需要int x, int y, int a[], int b[]我从InputParameter obj中提取并进行了计算并返回结果。

DResult需要int x, int y, int p[], boolean e我从同一个InputParameter obj中提取来进行计算并返回结果。

注意我可能需要执行其他结果计算集,因此可能会创建InputParameterAResultBResult等多个对象。只是想传达InputParameter不必是单身。


Approach2:

使用calculate()方法,不带任何参数,并在各个Result类构造函数中设置这些值。

正如@Duncan指出 Approach1 的一个缺点是,在这里我可能会错过在InputParameter对象中设置所需字段以进行给定的结果计算。当我实际尝试从InputParameter方法中提取calculation(InputParameter obj)对象的值时,我发现它没有设置。

public interface Result {
   int calculate();
}

public class AResult implements Result {
   public AResult(int x, int y, int a[], int b[]) {
      //set input params
   }
   public int calculate() {
      //calculate and return AResult
   }
}

Approach3:

为Result创建单个类(或者可能只有2-3个类),然后只有单独的方法来计算不同的结果。

我也在考虑这种方法,因为在某些情况下,一次计算的结果也用于其他结果计算(但这只是在少数情况下而不是全部)。

public class Result {
   // various fields...

   int calculateResultA(){...}
   int calculateResultB(){...}
   int calculateResultC(){...}
}

上面提到的 Approach1 对于给定的情况是否有用?还是其他选择更好?

2 个答案:

答案 0 :(得分:1)

在我看来,使用构造函数并定义接口Result以使方法public int calculate()不带参数。

免责声明从这一点开始,是对一些好原则的个人解释。评估他们,如果你不同意就批评他们,不要因为既定事实而接受他们(原则非常好,你的案例中的解释可能不那么好)。

我将尽量避免使用具有低内聚力的对象,其中凝聚力在书Growing object oriented software guided by tests中定义为

  

元素的凝聚力衡量其责任是否构成一个有意义的单位。例如,解析日期和URL的类不一致,因为它们是不相关的概念。想想一台洗衣服和餐具的机器 - 它不太可能做得很好.2另一方面,只解析URL中标点符号的类不太可能是连贯的,因为它不代表一个完整的概念。要完成任何工作,程序员必须找到协议,主机,资源等的其他解析器。具有“高”一致性的特征更易于维护。

在你的情况下,我相信InputParameter有责任为不同的类保存参数,所以在我看来它的责任不是一个有意义的单位(即使它基本上是一个价值对象,通过一些扩展它违反了Single Responsibility Principle

答案 1 :(得分:1)

我建议用工厂进行方法2。 模式是(可能) 命令

工厂方法

package blammy.result;

public interface Result
{
    int calculate();
}

package blammy.result.impl;

public class AResult
implements Result;
{
    /*
     * Protected constructor to hinder naughty construction.
    */
    protected AResult(
        int x,
        int y,
        int a[],
        int b[])
    {
        ... blah;
    }

    public int calculate()
    {
        int returnValue;
        returnValue = ... blah.
        return returnValue;
    }
}
public class BResult
implements Result;
{
    /*
     * Protected constructor to hinder naughty construction.
    */
    protected BResult(
        int x,
        int y,
        boolean c)
    {
        ... blah;
    }

    public int calculate()
    {
        int returnValue;
        returnValue = ... blah.
        return returnValue;
    }
}

public static class ResultFactory
{
    public static Result createResult(
        int x,
        int y,
        int a[],
        int b[])
    {
        return new AResult(x, y, a, b);
    }

    public static Result createResult(
        int x,
        int y,
        boolean c)
    {
        return new BResult(x, y, c);
    )
}

编辑1

如果不同的计算需要相同的参数,那么您应该在工厂和类名中使用描述性名称。例如:

public static class ResultFactory

    public static Result createBlammy(
        int x,
        int y,
        int a[],
        int b[])
    {
        return new ResultBlammy(x, y, a, b);
    }

    public static Result createHooty(
        int x,
        int y,
        int a[],
        int b[])
    {
        return new ResultHooty(x, y, a, b);
    }