类定义中的封装

时间:2009-03-17 17:48:58

标签: oop class encapsulation

例如,您是在方法定义中使用访问器和更改器还是直接访问数据?有时候,在罗马的所有时间或地点?

5 个答案:

答案 0 :(得分:2)

总是尝试使用访问器,即使在课堂内也是如此。您希望直接访问状态而不是通过公共接口访问状态的唯一情况是,由于某种原因,您需要绕过访问器方法中包含的验证或其他逻辑。

现在,如果你发现自己处于需要绕过这种逻辑的情况,那么你应该退后一步,问问自己这种需求是否会背叛你的设计中的缺陷。

编辑:阅读Eric Lippert的Automatic vs Explicit Properties,他深入研究了这个问题并非常清楚地解释了这一点。它具体是关于C#,但OOP理论具有普遍性和可靠性。

以下是摘录:

  

如果是有动机的原因   从自动实施改变   要明确实现的属性   属性是改变语义   然后你应该的财产   评估是否需要语义   从访问该物业时   在课堂上与或相同   与所需的语义不同   从访问该物业时   课外。

     

如果调查的结果是   “从课堂内,所需的   访问此属性的语义   与期望的不同   访问该属性的语义   从外面“,然后你的编辑有   介绍了一个bug。你应该修复   错误。如果它们是相同的,那么你的   编辑没有引入错误;保持   实施相同。

答案 1 :(得分:1)

一般来说,我更喜欢访问者/变异者。这样,我可以改变类的内部实现,而类的功能与外部用户相同(或者我不想破坏的预先存在的代码)。

答案 2 :(得分:1)

访问器的设计使您可以添加特定于属性的逻辑。如

int Degrees
{
    set
    {
        _degrees = value % 360;
    }
}

因此,您总是希望通过getter和setter访问该字段,这样您就可以始终确保该值永远不会超过360.

如果像Andrew提到的那样,你需要跳过验证,那么很可能在函数设计或验证设计中存在缺陷。

Accessors和Mutators旨在确保您的数据的一致性,因此即使在您的课程中,您也应该始终努力确保没有可能的方法将未经验证的数据注入这些字段。

编辑

也可以看到这个问题: OO Design: Do you use public properties or private fields internally?

答案 3 :(得分:0)

我不倾向于与外界分享我的课程的“内部”,因此我对数据的内部需求(私有方法的东西)往往不会做我公共接口所做的那样的事情,通常

我会编写一个私有方法会调用的访问者/变种器,这是非常罕见的,但我怀疑我在这里是少数。也许我做更多这方面,但我不倾向于。

无论如何,那是我的[铜绿]两美分。

答案 4 :(得分:0)

我经常会从私有自动属性开始,然后在必要时进行重构。我将重构一个带有支持字段的属性,然后用“真实”存储替换支持字段,例如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,所以这比花在帖子上的时间要少。