OO设计,在私有方法或访问成员变量之间传递参数
本文关键字:变量 成员 之间 参数 访问 设计 有方法 OO | 更新日期: 2023-09-27 18:37:00
假设我有以下类:
class MyClass
{
private int memberVar;
public MyClass(int passedInVar)
{
memberVar = passedInVar;
}
}
在构造函数中,传入一个 int 并将其分配给私有成员变量。
我的问题是,在类的私有方法之间传递该 int 变量更好,还是不将 int 变量作为参数传递,而是让每个私有方法直接访问私有成员var?
即这是(示例 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 不是在私有方法之间传递的。但是,代码感觉更"副作用",因为方法正在作用于哪些私有成员变量并不总是很明显。
感谢您对哪种方法的看法,您认为哪种方法最好。
与其告诉你哪个更好,我更愿意给你一些提示:
- 切勿直接访问类字段。它们应使用属性封装。 实例方法,因为它们
- 是某个特定类实例的一部分,不应该接受参数,除非在执行某些方法期间所需的值需要比对象本身中包含的信息更多的信息,或者如果数据不应该由类保存,因为它们不表示整个类的实际属性(即数据与类无关)。
- 您不应该仅仅为了使用类字段而创建私有方法,因为您应该已经使用属性封装了它们。
- 应
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
的论据,对吗?;) - 您需要提供矩形边的长度。
投票支持第二个解决方案。您正在使用当前上下文,这是一个正常的 - 使用上下文部分。它适合生活,适合代码。例如,您使用策略 1 的映像。如果您的某个私有方法(一次调用 2 或更多)需要更改签名,则需要在 2 个或更多位置更改代码。否则,当您使用上下文时,不需要它。
真正的问题不是"哪种方式更好",而是您的成员变量是否真的应该是类的成员。如果只是一个成员变量来清理某些操作的参数列表......这不是向类添加成员的好理由。它不仅会破坏您的模型并使您的代码更难理解,还会分散依赖项,这从来都不是一件好事。如果可以通过传入其依赖项使方法静态,那么这样做可能是件好事。
如果成员是类的合法成员,则可能根本不需要单独的方法。然后,将成员从一个方法传递到下一个方法就没有意义了,因为该成员始终可以通过任何方法访问,
在这个具体场景中,我会选择第一种方法,因为函数声明清楚地表明了它的执行依赖于什么。
在第二种情况下,您有"隐藏"变量,该变量在类型实例的整个生存期内保存状态。
有许多优点和缺点,这在很大程度上取决于所有程序架构,您的设计目标和个人测试。
考虑到我上面所说的一切,仍然,对函数进行清晰简洁的定义,同时清楚地显示其执行依赖关系(就像在你的第一选择中一样)是我发现很难争论的巨大好处。
接受的答案错过了几个方面。这是我的两分钱。
切勿直接访问类字段。
应始终直接访问类字段,除非需要属性 setter 的行为!在引擎盖下,属性是方法。访问属性类似于调用方法。优化程序可能更难摆脱额外的方法调用。更不用说属性设置者将触发代价高昂的事件的常见情况(例如 INotifyPropertyChanged
)。您也有属性virtual
的情况,这意味着额外的副作用。
实例方法/.../不应接受参数
基本正确。但是,如果您有私有实例方法,则只需几步即可使其static
- 为实际方法调用节省一些 CPU 周期(无需vtable
查找)。
您不应该仅仅为了使用类进行操作而创建私有方法 领域
当多个方法需要执行完全相同的工作作为其职责的一部分时,您应该创建私有方法。 例如:
private void OnSizeChanged()
{
this.area = CalcArea(); // Here...
this.perimeter = CalcPerimeter();
}
public float GetPhysicalArea(float unit)
{
return CalcArea() * unit; // ... and here!
}