我破坏了封装性吗?

7
class Program
{
    static void Main(string[] args)
    {
        B b = new B();
        b.Run();
        Console.Read();
    }
}

class A
{
    public event Action onChanged;

    public void Raise()
    {
        if (onChanged != null)
            onChanged();
    }
}

class B
{
    public void Run()
    {
        A a = new A();
        a.onChanged += a_onChanged;
        a.Raise();
    }

    private void a_onChanged()
    {
        Console.WriteLine("Wow! Invoked");
    }       

}

我不知道有哪些有效的观点可以证明我打破了封装,或者可能是其他原因。根据我的理解,我正在打破封装,因为一个私有方法被另一个类调用了,这是否足以证明我违反了面向对象编程的法则。需要收集更多内部概念和代码描述。


提醒:您的 event Action onChanged 应该被命名为 ChangedOnXxx 通常用于虚方法,以触发 Xxx 事件。 - Jonathon Reinhart
没有出错。您已经将私有方法包装在委托类中,该类具有公共的“Invoke”方法。您的事件调用委托的公共“Invoke”方法,该方法调用在初始化时传递给委托的方法。 - Atomosk
“哦,抱歉...我破坏了你的封装?” - (以塞缪尔·杰克逊的声音朗读) - sehe
3个回答

2
这实际取决于类A中的Raise方法的作用。如果它仅用于访问私有成员,则答案是:是的,您的封装性已经被破坏。onChanged事件应该在某些内容发生变化时才会触发,而不是由外部类决定何时触发。
然而,如果这只是一个简单的快照来说明问题,并且Raise事件是作为执行操作的副作用而触发事件的方法(例如更改Textbox中的文本,然后触发onTextChanged),那么您的封装仍然完好无损。
注意:
引用自Wikipedia
“我正在打破封装性,因为另一个类正在调用一个私有方法。”
封装用于将结构化数据对象的值或状态隐藏在类内部,防止未经授权的方直接访问它们。通常在类中提供公共可访问的方法(称为getter和setter)来访问这些值,其他客户端类调用这些方法来检索和修改对象内的值。
私有方法从公共方法中调用是可以的。否则,它怎么能被调用呢?作为程序员,你需要确保自己的方法逻辑正确,并确保它们调用适当的方法。

2
如果它仅用于启用对私有成员的访问,那么答案是肯定的,你的封装已经被破坏了。封装用于确保对象本身可以控制其行为和状态的有效性。允许外部方触发状态会移除该控制,并且可能导致对象表现出未定义的行为。 - jgauffin
@Avi - 不太明白你在这里想表达什么意思 - "然而,如果这只是一个简单的快照,用于说明一点,并且Raise事件是触发事件作为采取行动的副作用的方法(类似于更改文本框中的文本,然后触发onTextChanged),那么你的封装仍然是完整的。" - Bose_geek
1
@Bose_geek 我的意思是,如果这不是你实际引发事件的代码,而真正的代码更像“TextChanged”的示例,那么你的封装仍然完好无损。如果还不清楚,请告诉我,我会发布演示。 - Avi Turner
@Avi - 我明白你的意思。如果您能演示一下(只是为了让图片更加清晰),那将非常好,可以展示在这种情况下封装仍然保持完整。 - Bose_geek
@Bose_geek 我发布了一份示例代码。如果需要进一步的澄清,请留下评论... - Avi Turner
@Bose_geek 如果任何答案对您有帮助,请考虑将其标记为已接受的答案。 - Avi Turner

1
你没有破坏类B的封装性,因为类B的实例只会修改它们自己,但是你确实破坏了类A的封装性。任何持有对A实例的引用的对象都可以触发onChanged事件。

2
事件只能被订阅,没有所谓的“修改”。事件被设计成这样工作,并且在需要时可以公开访问。我认为仅当外部类可以引发事件时,才会破坏事件的封装性。无论onChanged字段是否可以“修改”,在这种情况下都是如此。 - Xenolightning

0

不,你没有破坏封装性,在这种情况下,“从另一个类调用私有方法”是不正确的。类 B 创建了自己的 A 并调用它的 Raise 方法,该方法引发了一个 onChanged 事件。
你从 B 注册了这个事件,因此完全没问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接