我正在为类中的业务域对象建模,并且想知道正确封装仅适用于少数方法的私有字段的最佳方法是什么。
当我开始时,我的代码最初看起来像这样:
public class DiscountEngine
{
public Cart As Cart { get; set;}
public Discount As Discount { get; set;}
public void ApplySKUGroupDiscountToCart()
{
...
}
}
然而,ApplySKUGroupDiscountToCart()
开始变得难看,所以我决定将代码重构为从ApplySKUGroupDiscountToCart()
调用的较小的私有方法。我首先将大量局部变量传递给辅助方法,但随后决定提取两个例程共有的变量并使它们成为私有模块变量。新代码如下所示:
public class DiscountEngine
{
public Cart As Cart { get; set;}
public Discount As Discount { get; set;}
private int _SKUGroupItemDiscountsApplied = 0
private int _SKUGroupTotalDiscounts = 0
private int _SKUGroupID = 0
public void ApplySKUGroupDiscountToCart()
{
...
}
private void ApplyDiscountToSingleCartItem(ref CartItem cartI,
ref DiscountItem discountI)
{
...
}
}
一方面,三个私有整数字段对于允许相关方法共享公共变量而不需要作为参数来回传递它们非常有用。但是,这些变量仅适用于这些相关方法,我可能添加的任何其他方法都不需要查看它们。
有没有办法封装私有字段及其相关方法,同时仍然是DiscountEngine
类的一部分?有没有更好的方法来处理这个问题?
答案 0 :(得分:6)
通常,将类字段设为私有意味着“我有足够的纪律来确保此字段仅在此类中以适当的方式使用”。如果你的课程太大而无法自信地说出来,那么也许课程会尝试做太多不同的事情,并且应该分开(参见SRP)。
无论如何,足够的理论:-)。如果你想坚持使用一个类,那么你总是可以将这三个字段封装到一个私有的嵌套类中,例如。
public class DiscountEngine
{
public Cart As Cart { get; set;}
public Discount As Discount { get; set;}
private class SKUGroup
{
public int ItemDiscountsApplied = 0
public int TotalDiscounts = 0
public int ID = 0
}
public void ApplySKUGroupDiscountToCart()
{
...
}
private void ApplyDiscountToSingleCartItem(ref CartItem cartI,
ref DiscountItem discountI)
{
...
}
}
这使您可以更自由地将代码类的实例作为方法参数传递。
您可以更进一步,并将 上的任何私有方法也移动到嵌套类中。
答案 1 :(得分:2)
首先,您很可能不需要将参数作为ApplyDiscountToSingleCartItem
传递给ref
。简短版本:除非您实际上为您希望对调用代码显示的变量赋值,否则您不需要ref
。修改它们上的变量和属性值对于调用代码是可见的,而不将它们作为ref
传递。
其次,没有办法在实例和本地之间调整变量的范围,这就是你所要求的。实现此目的的唯一方法是将此功能重构为另一个类(可能是嵌套的private
类)。
答案 2 :(得分:1)
我想说我能想到的另一种处理方法是将与它们相关的所有方法和私有变量提取到一个单独的类中。这样你就可以保留所有封装的内容。但不确定在域对象的上下文中是否有意义。
答案 3 :(得分:1)
您始终可以创建一个嵌套(内部)类,将具有共同用途的参数捆绑在一起。通过这种方式,您仍然可以将它们传递给您的私有方法,而无需传递l.ots参数 - 您只需传递私有类型的实例。
答案 4 :(得分:0)
“这些变量仅适用于这些相关方法,我可能添加的任何其他方法都不需要查看它们。”
首先,请记住,面向对象开发的第一个规则是构建客户想要的东西然后应用OO设计,如基本的OO规则和模式。你的报价接近说你要为未知的人做计划。小心未知是“更多相同”而非新要求。否则,这个课程最终会成为God Object.
如果您发现许多成员未被这些方法使用,那么就分而治之。