我有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
中提取来进行计算并返回结果。
注意我可能需要执行其他结果计算集,因此可能会创建InputParameter
,AResult
,BResult
等多个对象。只是想传达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 对于给定的情况是否有用?还是其他选择更好?
答案 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);
)
}
如果不同的计算需要相同的参数,那么您应该在工厂和类名中使用描述性名称。例如:
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);
}