【问题标题】:Does the delegate pattern break encapsulation?委托模式会破坏封装吗?
【发布时间】:2014-10-09 20:56:41
【问题描述】:
假设我有一个接受委托的类:
public class DelegateContainer
{
private IDelegate delegate;
public DelegateContainer(IDelegate delegate)
{
this.delegate = delegate;
}
public void doSomething()
{
delegate.doSomethingOnlyForThisPurpose();
}
{
如您所见,委托的 doSomethingOnlyForThisPurpose() 方法只存在于由委托类调用。但是,要求此方法是公共的,并且可以由任何东西执行。如果它绝对不应该由它所附加的委托类以外的任何东西执行(特别是如果委托类传递了依赖项),那么这不会破坏封装吗?我想解决这个问题的唯一方法是设计一个只能由传递给每个调用方法的委托类(内部类)实例化的对象。但是,这非常复杂,而且无论如何都不是无懈可击的。有什么办法可以解决这个问题还是病态的?
注意:我想坚持这种组合方法,所以我宁愿不求助于继承。
【问题讨论】:
标签:
oop
delegates
encapsulation
composition
information-hiding
【解决方案1】:
它不应该破坏封装。您对 IDelegate 的实现发布了一些行为,任何引用 this 实例的人都可以调用这些行为,因此它应该像任何其他公共行为一样使用所需的抽象来实现。如果您希望任何人拥有一个实例,您可以公开您的构造函数。如果你不这样做,那么你就像你所做的那样(使用私有或受保护的构造函数)。
IDelegate.doSomethingOnlyForThisPurpose 实现的目的应该是做它所做的事情,无论是否被DelegateContainer 调用。我的意思是,如果这种方法被“错误的人”调用是危险的,那么它与DelegateContainer 紧密耦合。在这种情况下,破坏封装的不是委托模式。
只是一个简短的说明:
我不知道你使用的是什么语言。在C# 中,您可以显式实现IDelegate.doSomethingOnlyForThisPurpose 以供对此接口特别感兴趣的人使用:
class MyClass: IDelegate
{
void IDelegate.doSomethingOnlyForThisPurpose() {
// This method is only visible by
// who is representing your object as IDelegate.
// It's not visible by who is representing it as MyClass.
}
}
结论:如果“OnlyForThisPurpose”意味着随时调用它是不安全的(你已经知道这一点),你不应该有一个名为 doSomethingOnlyForThisPurpose 的非私有方法,并且你不应该想要你的如果您“害羞”地发布它(这是坏消息),则在您的课程之外调用方法(由DelegateContainer)。这是一个设计问题,但不是委托模式的问题。