【问题标题】:OO Design, pass parameters between private methods or access member variable? [closed]OO设计,私有方法之间传递参数还是访问成员变量? [关闭]
【发布时间】:2016-03-02 14:30:09
【问题描述】:

假设我有以下课程:

class MyClass
{
    private int memberVar;

    public MyClass(int passedInVar)
    {
        memberVar = passedInVar;       
    }
}

在构造函数中传入一个 int 并将其分配给私有成员变量。

我的问题是,最好在类的私有方法之间传递该 int 变量,还是不将 int 变量作为参数传递,而是让每个私有方法直接访问私有成员变量?

即这是(示例 A):

class MyClass
{
    private int memberVar;

    public MyClass(int passedInVar)
    {
        memberVar = passedInVar;       
    }

    public MyPublicMethod()
    {
        MyPrivateMethod(memberVar);
    }

    public MyPrivateMethod(int variable)
    {
        // Do something with passed in variable...
    }
}

比这更好(示例 B):

class MyClass
{
    private int memberVar;

    public MyClass(int passedInVar)
    {
        memberVar = passedInVar;       
    }

    public MyPublicMethod()
    {
        MyPrivateMethod();
    }

    public MyPrivateMethod()
    {
        // Do something with memberVar...
    }
}

我问的原因是我发现自己在两种风格之间切换。

我发现示例 A 的样式显示了代码的更多意图。您可以看到私有方法之间传递的内容,从而更清楚地了解该方法所影响的内容。

而示例 B 更简洁,因为 memberVar 没有在私有方法之间传递。然而,代码感觉更“副作用”,因为方法作用于哪些私有成员变量并不总是很明显。

感谢您对您认为最好的方法提出意见。

【问题讨论】:

  • 如果你不在课堂上全局使用这个私有变量,为什么还要使用它?
  • @Richard Moore 我会选择第二种方法,因为所有方法都可以访问memberVar 的声明,因此传递变量将毫无意义。
  • 我会说这取决于场景,也许私有方法可以对提供的值执行操作,这将使该方法更加灵活,因为您不必每次都设置一个字段您想使用该方法。我想说,只要你在整个应用程序中保持代码标准一致,我认为任何一种方法都不会比另一种更好,除非在某些情况下说。
  • 私有属性和方法的构造方式完全取决于您,因为它们被封装在类中。话虽如此,考虑到您始终处于同一范围内,选项 B 对我来说似乎是最明智的。
  • 在大多数情况下,我更喜欢第一种方法。我觉得它是一个适当的函数(输入和输出),并且不依赖于私有变量。数学中的函数有输入有输出。

标签: c# oop


【解决方案1】:

真正的问题不是“哪种方式更好”,而是您的成员变量是否真的应该是您的类的成员。如果它只是一个成员变量来清理某些操作的参数列表......那不是向类添加成员的好理由。它不仅污染了你的模型,让你的代码更难理解,它还分散了依赖关系,这从来都不是一件好事。如果您可以通过传递其依赖项来使您的方法成为静态方法,那么这样做可能会很好。

如果该成员是您班级的合法成员,您可能根本不需要单独的方法。然后将成员从一种方法传递到下一种方法是没有意义的,因为该成员总是可以通过任何方法访问,

【讨论】:

    【解决方案2】:

    与其告诉你哪个更好,我更愿意给你一些提示:

    • 不应直接访问类字段。应该使用 properties 封装它们。
    • 实例方法,因为它们是某些特定类实例的一部分,因此不应接受参数,除非在执行某些方法期间所需的值需要比对象本身包含的信息更多的信息,或者如果数据不应该由类持有,因为它们不代表整个类的实际属性(即数据与类无关)。
    • 你不应该创建一个私有方法来操作类字段,因为你应该已经使用属性封装了它们。
    • 仅在构建期间设置的类字段应为readonly,以避免在整个对象的生命周期内设置它的人为错误。至少,您应该设置一个其 setter 为私有的属性(即public string Name { get; private set; })。

    扩展何时使用输入参数

    例如,计算矩形的面积如下所示:

    public class Rectangle
    {
         public int Area { get; private set; }
    
         public void CalcArea(int a, int b) 
         {
              Area = a * b;
         }
    }
    
    • Area 是一个类属性。您不会将该区域作为CalcArea 的参数传递,对吗? ;)
    • 您需要提供矩形边的长度。

    【讨论】:

    • 我为我的无知道歉,但是class field 和class property 有什么区别?
    • @gen 类字段是存储,属性是字段的访问器(以及其他一些东西,如计算属性......)。属性封装了对字段的访问,因此可以定义某些数据是只读的、只写的、读写的,甚至是所有与可见性修饰符的组合(私有、受保护、内部、公共)
    【解决方案3】:

    投票支持第二次解决。您正在使用当前上下文,这是正常的 - 使用上下文部分。它适用于生活,适用于代码。 例如,您使用策略 1 的映像。如果您的私有方法之一(调用 2 或更多一次)需要更改签名,那么您需要在 2 个或更多位置更改代码。否则,当您使用上下文时,它是不需要的。

    【讨论】:

      【解决方案4】:

      我会在这个具体场景中选择第一种方法,因为函数声明清楚地表明了它的执行依赖于什么。

      在第二种情况下,您拥有在类型实例的整个生命周期内保存状态的“隐藏”变量。

      有 pros 和 cons 之分,这在很大程度上取决于所有程序架构、您的设计目标和个人测试。

      考虑到我上面所说的所有内容,同时清楚地显示其执行依赖关系的函数的清晰简洁定义(就像在您的第一选择中一样)是一个巨大的好处,我觉得很难争论。

      【讨论】:

        【解决方案5】:

        接受的答案遗漏了几个方面。这是我的两分钱。

        永远不要直接访问类字段。

        类字段应该始终直接访问,除非需要属性设置器的行为!在引擎盖下,属性就是方法。访问一个属性就像调用一个方法。优化器可能更难摆脱额外的方法调用。更不用说属性设置器会触发代价高昂的事件的常见情况(例如INotifyPropertyChanged)。您也有属性为virtual 的情况,这意味着额外的副作用。

        实例方法/.../不应接受参数

        大部分是正确的。不过,如果您有一个私有 instance 方法,那么您离实现它还有几步之遥static - 为实际的方法调用节省了一些 CPU 周期(没有vtable 查找)。

        您不应该创建私有方法只是为了使用类进行操作 字段

        当多个方法需要执行完全相同的工作作为其职责的一部分时,您应该创建私有方法。例如:

        private void OnSizeChanged()
        {
            this.area = CalcArea();   // Here...
            this.perimeter = CalcPerimeter();
        }
        
        public float GetPhysicalArea(float unit)
        {
            return CalcArea() * unit; // ... and here!
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-04-14
          • 2013-02-01
          • 2019-07-12
          • 2014-12-12
          • 1970-01-01
          • 2013-02-14
          • 2016-06-06
          • 1970-01-01
          相关资源
          最近更新 更多