代表的封装问题?

时间:2013-03-23 12:24:13

标签: c# oop encapsulation

我想知道为什么会这样吗?

例如,我有一些执行者类,如下所示:

public class Executor
{
    public void Execute(Action action)
    {
        action();
    }
}

现在我有一些需要被执行的类,如下所示:

public class NeedToBeExecuted
{
    public void Invoke()
    {
        Executor executor = new Executor();
        executor.Execute(DoSomething);
    }

    private void DoSomething()
    {
        // do stuff private
    }
}

我的问题是为什么这是工作我将私有方法传递给其他类

这不是封装问题吗?

6 个答案:

答案 0 :(得分:6)

不,这不违反封装。

首先:类本身决定将委托分发给其私有方法之一!该类可以访问其私有方法,如果它选择将一个引用传递给该方法的可访问域之外的代码,则完全在其权限范围内。

第二:方法的可访问性域不限制方法可以的位置。 它限制了可以按名称查找方法的位置。类Executor永远不会使用名称 DoSomething来调用私有方法。它使用名称action

答案 1 :(得分:3)

让我试一试。

不,我们没有封装问题。您正在定义一个负责Execute某事的类。 Executer知道没有关于实际执行的内容。它只知道它应该执行DoSomethingDoSomething在负责执行某些操作的类中指定了什么。

正如我评论的那样,它与你对Thread所做的非常相似。您定义了一个需要在不同的Thread上执行的方法。这就是为什么类有一个Thread,并定义应该在该Thread上运行哪个方法。线程仍然对它所扮演角色的类一无所知。

关系是Class =>线。不是相反。

在您的示例中,关系为NeedToBeExecuted => Executer。不是相反。

这个概念对你来说可能很棘手,但你没有做错任何事。

答案 2 :(得分:1)

与使用反射一样,这只是一个封装问题。使用反射可以非常轻松地从外部类访问私有方法和变量。你不应该认为这是一件坏事,因为它只会使语言变得更加强大。

该类是放弃委托方法的类,所以在某种程度上类正在启用行为,所以它根本不应该是封装问题。

答案 3 :(得分:1)

考虑一下:NeedToBeExecuted没有公开DoSomething()方法,因为它可以被任意调用 - 而是将它作为委托传递给另一个函数。它可以很容易地传递() => DoSomething() - 结果是一样的。最终访问修饰符是为了防止使用您的方法的不同的类,您仍然可以随意使用它。如果你选择将它传递给另一个类,这是一个有效的用途。

答案 4 :(得分:1)

您在方法DoSomething中传递了Invoke(),并且可以在上下文中访问它。没有封装问题。

但是,当您在代码中看到评论时,DoSomething无法访问EitherNeedToBeExecuted

public class Executor {
    public void Execute(Action action) {
        action();
    }
}

public class NeedToBeExecuted {
    public virtual void Invoke() {
        Executor executor=new Executor();
        executor.Execute(this.DoSomething);
    }

    private void DoSomething() {
        Console.WriteLine("I'M DOING IT MYSELF!!");
    }

    protected Executor m_Executor=new Executor();
}

public class EitherNeedToBeExecuted: NeedToBeExecuted {
    public override void Invoke() {
        // 'NeedToBeExecuted.DoSomething()' is inaccessible due to its protection level
        m_Executor.Execute(base.DoSomething);
    }
}

答案 5 :(得分:1)

封装意味着能够在不更改外部代码的情况下更改某些模块的内部。这仍然是这种情况。因此没有发生封装破坏。