封装是否荒谬?

y2k*_*y2k 11 c# c++ encapsulation yagni

对于我的软件开发编程类,我们应该为RSS feed创建一个"Feed Manager"类型的程序.以下是我处理FeedItems实现的方法.

好又简单:

struct FeedItem {
    string title;
    string description;
    string url;
}
Run Code Online (Sandbox Code Playgroud)

我得到了标记,"正确"的示例答案如下:

class FeedItem
{
public:
    FeedItem(string title, string description, string url);

    inline string getTitle() const { return this->title; }
    inline string getDescription() const { return this->description; }
    inline string getURL() const { return this->url; }

    inline void setTitle(string title) { this->title = title; }
    inline void setDescription(string description){ this->description = description; }
    inline void setURL(string url) { this->url = url; }

private:
    string title;
    string description;
    string url;
};
Run Code Online (Sandbox Code Playgroud)

现在对我来说,这似乎很愚蠢.老实说,我不敢相信我被标记了下来,当这与我的做法完全相同时会产生更多的开销.


它让我想起C#中的人总是这样做:

public class Example
{
    private int _myint;

    public int MyInt
    {
        get
        {
            return this._myint;
        }
        set
        {
            this._myint = value;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我的意思是我GET他们为什么这样做,也许以后他们想要验证数据的setter或吸气加一.但是,为什么人们不这样做,直到出现这种情况?

public class Example
{
    public int MyInt;
}
Run Code Online (Sandbox Code Playgroud)

对不起,这是一种咆哮,而不是一个真正的问题,但冗余让我很难过.为什么吸气者和制定者在不需要的时候如此受到爱戴?

Chr*_*son 14

这是"最佳实践"和风格的问题.

  • 您永远不想直接公开您的数据成员.您总是希望能够控制它们的访问方式.我同意,在这种情况下,它似乎有点荒谬,但它旨在教你这种风格,所以你习惯了它.
  • 它有助于为类定义一致的接口.你总是知道怎么做 - >调用它的get方法.

然后还有可重用性问题.比如说,当你有人访问数据成员时,你需要改变发生的事情.您可以在不强制客户端重新编译代码的情况下执行此操作.您只需更改类中的方法并确保使用新逻辑.

  • @ StackedCrooked:确定所有代码都是你的.但是使用您的界面的13000应用程序会发生什么.你是否会改变其他人的代码?即使你可以反对其他团体,因为代码处于锁定状态或需要大量的测试发布周期(出于法律或其他原因). (8认同)
  • 不,C#示例*中的接口不会保持不变.您要将字段更改为属性.所有客户都需要重新编译.这在C++中可能不是一个问题,其中代码通常被编译并链接到一个二进制文件中,但在.NET环境中,程序集在运行时被"链接",这非常重要. (2认同)

Chs*_*y76 13

这是一个关于这个主题的长篇SO讨论:为什么要使用getter和setter.

你想问自己的问题是"从现在开始3个月后会发生什么事情,当你意识到FeedItem.url 确实需要验证但它已经直接从287个其他类中引用了?"


Ree*_*sey 7

在需要之前执行此操作的主要原因是版本控制.

字段的行为与属性不同,尤其是在将它们用作左值时(通常不允许使用它们,尤其是在C#中).此外,如果您需要稍后添加属性获取/设置例程,您将破坏您的API - 您的类的用户将需要重写他们的代码以使用新版本.

预先做这件事要安全得多.

C#3,顺便说一句,让这更容易:

public class Example
{
    public int MyInt { get; set; }
}
Run Code Online (Sandbox Code Playgroud)


wil*_*ell 5

我绝对同意你的看法。但是在生活中,您可能应该做正确的事情:在学校里,就是取得好成绩。在您的工作场所,它是为了满足规范。如果您想要固执,那很好,但是请解释一下您自己——在评论中涵盖您的基础,以尽量减少您可能受到的伤害。

在上面的特定示例中,我可以看到您可能想要验证 URL。也许你甚至想要清理标题和描述,但无论哪种方式,我认为这是你可以在类设计早期告诉的那种事情。在评论中说明您的意图和理由。如果您不需要验证,那么您就不需要 getter 和 setter,这是绝对正确的。

简单值得,这是一个有价值的功能。永远不要虔诚地做任何事。