例如,您是在方法定义中使用访问器和修改器还是直接访问数据?有时,一直或何时在罗马?
5 回答
始终尝试使用访问器,即使在类内部也是如此。您唯一希望直接访问状态而不是通过公共接口访问状态的情况是,如果出于某种原因需要绕过访问器方法中包含的验证或其他逻辑。
现在,如果您发现自己确实需要绕过该逻辑,您应该退后一步,问问自己这种需要是否暴露了您的设计中的缺陷。
编辑:阅读Eric Lippert 的Automatic vs Explicit Properties,他在其中深入研究了这个问题并非常清楚地解释了事情。它专门针对 C#,但 OOP 理论是普遍且可靠的。
这是一段摘录:
如果促使从自动实现的属性更改为显式实现的属性的原因是改变属性的语义,那么您应该评估从类中访问属性时所需的语义是否与访问时所需的语义相同或不同课外的财产。
如果该调查的结果是“从类内部访问此属性的所需语义与从外部访问该属性的所需语义不同”,那么您的编辑引入了一个错误。你应该修复这个错误。如果它们相同,那么您的编辑没有引入错误;保持执行相同。
一般来说,我更喜欢访问器/修改器。这样,我可以更改类的内部实现,而类以相同的方式对外部用户(或我不想破坏的现有代码)起作用。
访问器的设计使您可以添加特定于属性的逻辑。如
int Degrees
{
set
{
_degrees = value % 360;
}
}
因此,您总是希望通过 getter 和 setter 访问该字段,这样您就可以始终确定该值永远不会大于 360。
如果像 Andrew 提到的那样,您需要跳过验证,那么很可能是功能设计或验证设计存在缺陷。
Accessors 和 Mutators 旨在确保数据的一致性,因此即使在您的类中,您也应该始终努力确保无法将未经验证的数据注入这些字段。
编辑
另请参阅此问题: OO 设计:您在内部使用公共属性还是私有字段?
我不倾向于与外界分享我的类的“内部结构”,因此我对数据的内部需求(私有方法的东西)通常不会像我的公共接口那样做同样的事情。
我会编写一个私有方法将调用的访问器/修改器是很罕见的,但我怀疑我在这里是少数。也许我应该做更多这样的事情,但我不倾向于这样做。
无论如何,那是我的 [铜绿覆盖] 两美分。
我通常会从私有自动属性开始,然后在必要时进行重构。我将重构为具有支持字段的属性,然后将支持字段替换为“真实”存储,例如 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,所以这比发帖花费的时间更少。