【发布时间】:2010-10-13 21:50:21
【问题描述】:
例如,您是在方法定义中使用访问器和修改器还是直接访问数据?有时、一直或何时在罗马?
【问题讨论】:
-
那个帖子好像是在讲一个与外界交流的类,我不是。
标签: oop class encapsulation
例如,您是在方法定义中使用访问器和修改器还是直接访问数据?有时、一直或何时在罗马?
【问题讨论】:
标签: oop class encapsulation
访问器的设计使您可以添加特定于属性的逻辑。比如
int Degrees
{
set
{
_degrees = value % 360;
}
}
因此,您总是希望通过 getter 和 setter 访问该字段,这样您就可以始终确定该值永远不会大于 360。
如 Andrew 所说,如果您需要跳过验证,那么很有可能是函数设计或验证设计存在缺陷。
Accessors 和 Mutators 旨在确保您的数据的一致性,因此即使在您的类中,您也应始终努力确保无法将未经验证的数据注入这些字段。
编辑
也请参阅此问题: OO Design: Do you use public properties or private fields internally?
【讨论】:
我通常会从私有自动属性开始,然后在必要时进行重构。我将重构为具有支持字段的属性,然后将支持字段替换为“真实”存储,例如 ASP.NET 应用程序的 Session 或 ViewState。
发件人:
private int[] Property { get; set; }
到
private int[] _property;
private int[] Property
{
get { return _property; }
set { _property = value; }
}
到
private int[] _property;
private int[] Property
{
get
{
if (_property == null)
{
_property = new int[8];
}
return _property;
}
set { _property = value; }
}
到
private int[] Property
{
get
{
if (ViewState["PropertyKey"] == null)
{
ViewState["PropertyKey"] = new int[8];
}
return (int[]) ViewState["PropertyKey"];
}
set { ViewState["PropertyKey"] = value; }
}
当然,我使用的是 ReSharper,所以这比发帖花费的时间更少。
【讨论】:
我不倾向于与外界分享我的类的“内部”,因此我对数据的内部需求(私有方法的东西)往往不会像我的公共接口那样做,通常.
我会编写一个私有方法将调用的访问器/修改器是很罕见的,但我怀疑我在这里是少数。也许我应该做更多这样的事情,但我不倾向于这样做。
无论如何,那是我的 [铜绿覆盖] 两美分。
【讨论】:
始终尝试使用访问器,即使在类内部也是如此。唯一需要直接而不是通过公共接口访问状态的情况是,如果出于某种原因需要绕过访问器方法中包含的验证或其他逻辑。
现在,如果您发现自己处于确实需要绕过该逻辑的情况,您应该退后一步,问问自己这种需要是否暴露了您的设计中的缺陷。
编辑:阅读 Eric Lippert 的 Automatic vs Explicit Properties,他在其中深入研究了这个问题并非常清楚地解释了事情。它专门针对 C#,但 OOP 理论是通用且可靠的。
摘录如下:
如果动机的原因 从自动实施更改 明确实现的属性 属性是改变语义 那么你应该 评估是否需要语义 当从 类内相同或 与期望的语义不同 当从 课外。
如果该调查的结果是 “在课堂上,想要的 访问此属性的语义 与想要的不同 访问属性的语义 从外部”,那么您的编辑有 引入了一个错误。你应该修复 漏洞。如果它们相同,那么您的 编辑没有引入错误;保持 实现方式相同。
【讨论】:
一般来说,我更喜欢访问器/修改器。这样,我可以更改一个类的内部实现,而该类以相同的方式对外部用户(或我不想破坏的现有代码)起作用。
【讨论】: