1

我们有一个Transaction负载很重的类;如此加载,以至于我最初最终将近 20 个参数传递给ctor. 提取了几个值对象后,还剩下12个参数,我觉得还是太多了。

我将如何避免这种情况?我认为将参数传递给构造函数是合理的,因为它们都是必需的,我想明确说明。我也喜欢如果我添加一个属性,我可以将它添加到ctor并让我的编译器找到它破坏的地方,而不必依赖测试本身。我不认为对象初始化器或构建器对这个问题有任何好处。在接下来的几天里,哪些论点属于同一类,并且可以组合起来,可能会变得更加明显。

public class MyEntity() 
{
    public MyEntity(ValueType prop2, ValueType prop3, ...) 
    {
        Id = Guid.NewGuid();
        Prop2 = prop2;
        Prop3 = prop3;
        ...
    }

    public Guid Id { get; private set; }

    public ValueType Prop2 { get; private set; }

    public ValueType Prop3 { get; private set; }

    public ...
}
4

4 回答 4

2

您确定所有参数都是必需的吗?“必需”这个词具有欺骗性,例如,编译器可能会强制我提供一个字符串参数,但它不能强制我提供一个非 null 或空的值。

真正强制提供有效数据的唯一方法是在使用时对其进行验证。有时这必须在构造函数中,例如一个类,它包装了一些只有在初始化时才有意义的东西,比如一个 I/O 对象。但是,通常允许调用代码以任何旧方式设置属性,然后在需要它们的方法调用中验证它们的值就足够了。

我有点啰嗦。我的观点是,不要将构造函数参数作为向类提供初始化数据的唯一方法。除了简单的属性之外,它们几乎没有提供额外的编译器保护。

于 2013-01-15T20:09:45.110 回答
1

当您在用户或系统界面中输出完整的交易详细信息时,您将需要所有部分。这不太可能帮助您找到拆分。

但是,看看您的内部处理 - 是否存在您只使用事务中的一部分字段的情况?是否存在您在交易中传递但仅使用其中 4 个字段的地方?如果您确实总是使用所有字段,那么请将它们保存在一个对象中。

在银行交易的情况下,我会考虑按照以下方式进行拆分:-

  • 钱从哪里来
  • 钱去哪儿了
  • 资金是如何转移的——使用了哪种支付工具或设施
  • 资金被转移的原因 - 参考编号等
  • 金额和币种
  • 日期
  • 交易状态

(显然这取决于您的确切域)。

于 2013-01-16T00:49:43.313 回答
1

将参数封装在结构体中,然后将结构体传递进去怎么样?

public struct ParamsStruct
{
    Type1 param1;
    Type2 param2;
    ...
}

public void Method(ParamsStruct p)
{
    ...
}

public void Main(String[] args)
{
    ParamsStruct p;
    p.param1 = ...
    p.param2 = ...
    Method(p);
}
于 2013-01-15T20:12:50.440 回答
0
public class MyEntity() 
{
    public ValueType Prop1 { get; set; }

    public ValueType Prop2 { get; set; }

    // And so on...

    public MyEntity() 
    {
        Id = Guid.NewGuid();
    }
}

然后:

MyEntity entity = new MyEntity();
entity.Prop1 = prop1;
entity.Prop2 = prop2;
// And so on...

您最终可以考虑两种不同的设计方法:

于 2013-01-15T20:35:38.517 回答