函数参数是否违反封装?

Do function arguments violate encapsulation?

这个问题与一般的 OOP 实践有关。 假设我们有一个 class 和一个 public 函数接受从对象外部传入的参数。这本身不违反封装吗?另一方面,为什么这种做法被如此广泛地使用?毕竟 class 的构造函数和成员变量在调用函数时是一种 "by-passed" 。作为 OOP 的一个相对较新的程序员和我对封装的理解,我的函数参数通过 setter 传递到对象中,因此我只使用传入的成员变量来保留我的所有函数而没有任何参数。 我知道某些参数可以通过构造函数传入(顺便说一句,我使用依赖注入),但是如果这些参数在对象被实例化后发生变化怎么办?必须有一种方法可以在创建对象后更改这些值。到目前为止,除了使用 setter 来完成这项任务,我没有找到其他选择,但是在程序员之间长期以来一直在讨论 getter 和 setter 是 "evil" 或者至少被认为不是好的编程习惯。 谁能告诉我我错过了什么以及如何以干净的方式解决这个难题? 非常感谢您的支持。

这是一个使用 C# 的非常简单的具体示例:

我们在 windows 表单项目中有一个表单,其中包含 3 个文本框,分别命名为 textBox1、textBox2 和 textBox3。

任务是添加 textBox1 和 textBox2 的值,并使用 class 每当 textBox1 或 textBox2 的值发生变化时由事件处理程序实例化的 AddTextboxValues 将结果返回给 textBox3:

我经常看到的方式问是否违反封装:

public class AddTextBoxValues
{
    public double TextBoxValueSum(double textBox1value, double textBox2Value)
    {
       return textBox1value + textBox2Value;
    }
}

根据我对封装的理解,目前我是这样使用的:

public class AddTextBoxValues
{
    private double textBox1Value;
    private double textBoxValue2;
    private double textBoxValue3;

    public double TextBox1Value
    {
        set { textBox1Value = value; }
    }

    public double TextBoxValue2
    {
        set { textBoxValue2 = value; }
    }

    public double TextBoxValue3
    {
        get { return textBoxValue3; }
    }


    public void TextBoxValueSum()
    {
        textBoxValue3= textBox1Value + textBoxValue2;
    }

}

这还有一个好处,就是可以将其注入到表单构造函数中。

非常感谢任何评论。

非常感谢 Jon Skeet,你是​​一位真正的专业人士。 您准确地诊断了我的问题,并因缺乏理解和找到解决我自己问题的知识而睁开了眼睛。确实是对封装和 "object state" 的更深入理解构建了我的拼图中缺失的一块。 现在对我来说一切似乎都合乎逻辑且清晰,我希望将来也能对其他人有所帮助。

这两个例子都不是面向对象编程。它们是过程式编程的例子。

首先 "class" 实际上只是一个 命名空间 包装 TextBoxValueSum 函数。 第二个 "class" 只是一个 结构 和 public 字段(getters-setter 和 public 字段之间没有区别)。

如果你想使用真正的面向对象编程,你应该想到对象,它们是 事物 的表示。 在你的情况下,我会写 class Sum 这是一个真实的东西,代表 一个具体的总和 :

class Sum {
  private double a, b;
  public Sum (double a, double b) { this.a = a; this.b = b; }
  public double value() { return this.a + this.b; }
}