如何封装仅适用于少数方法的私有字段

Ben*_*ack 4 c# oop encapsulation

我正在创建一个类中的业务域对象的建模,我想知道什么是正确封装仅适用于几个方法的私有字段的最佳方法.

当我开始时,我的代码最初看起来像这样:

public class DiscountEngine
{
    public Cart As Cart { get; set;}
    public Discount As Discount { get; set;}

    public void ApplySKUGroupDiscountToCart()
    {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

然而,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)
    {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

一方面,三个私有整数字段对于允许相关方法共享公共变量而不需要作为参数来回传递它们非常有用.但是,这些变量仅适用于这些相关方法,我可能添加的任何其他方法都不需要查看它们.

有没有办法封装私有字段及其相关方法,同时仍然是DiscountEngine类的一部分?有没有更好的方法来处理这个问题?

Chr*_*ter 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)
    {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

这使您可以更自由地将类的实例作为方法参数传递给代码.

您可以更进一步,并将任何作用于SKU数据的私有方法移动到嵌套类中.

  • 我想在这个优秀的答案中添加一个细节:不要为每个DiscountEngine创建一个SKUGroup实例; 不要创建作为SKUGroup的DiscountEngine的成员.相反,每次调用ApplySKUGroupDiscountToCart时都要创建一个新的SKUGroup,并且只在计算期间使用它.(这可能是每个人都在想的事情;只是以为我会把它拼出来.) (2认同)