4

なぜこれが機能するのだろうか?

たとえば、次のようなエグゼキュータ クラスがあります。

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
    }
}

私の質問は、プライベート メソッド他のクラスに渡す理由です。

これはカプセル化の問題ではありませんか?

4

6 に答える 6

6

いいえ、これはカプセル化の違反ではありません。

まず、クラス自体が、そのプライベート メソッドの 1 つにデリゲートを渡すことを決定したものです。クラスはそのプライベート メソッドにアクセスでき、そのメソッドのアクセシビリティ ドメイン外のコードへの参照を渡すことを選択した場合、それは完全にその権利の範囲内です。

2 つ目: メソッドのアクセシビリティ ドメインは、メソッドを呼び出すことができる場所を制限しません。 メソッドを名前で検索できる場所を制限します。クラスExecutor名前 DoSomethingを使用してプライベート メソッドを呼び出すことはありません。という名前を使用していますaction

于 2013-03-23T14:27:23.733 に答える
3

それでは試してみましょう。

いいえ、カプセル化の問題はありません。Executeあなたは何かに責任があるクラスを定義しています。は実際に何が実行されるかについては何Executer知りません。実行する必要があることだけを知っています。何かを実行する責任があるクラスで何が指定されていますか。DoSomethingDoSomething

私がコメントしたように、それはあなたがで行うことと非常に似ていますThread。別のスレッドで実行する必要があるメソッドを定義します。そのため、クラスにはスレッドがあり、そのスレッドで実行するメソッドを定義します。スレッドは、それがで役割を果たすクラスについてまだ何も知りません。

関係はClass=>Threadです。その逆ではありません。

あなたの例では、関係はNeedToBeExecuted=>Executerです。その逆ではありません。

概念はあなたの心にトリッキーかもしれませんが、あなたは何も悪いことをしていません。

于 2013-03-23T12:41:42.683 に答える
1

リフレクションを使用するのと同じくらい、カプセル化の問題です。リフレクションを使用すると、外部クラスからプライベートメソッドと変数に非常に簡単にアクセスできます。これは必ずしも言語をはるかに強力にするだけなので、必ずしも悪いことだと考えるべきではありません。

クラスはとにかくデリゲートメソッドを放棄するクラスなので、ある意味でクラスは動作を有効にしているので、カプセル化の問題にはなりません。

于 2013-03-23T12:42:46.480 に答える
1

これを考慮してください:任意に呼び出すことができるような方法でメソッドをNeedToBeExecuted公開していません-代わりに、デリゲートとして別の関数に渡しています。DoSomething()同じように簡単に合格することもできます() => DoSomething()- 結果は同じです。最終的にアクセス修飾子は、のクラスがメソッドを使用するのを防ぐためにありますが、好きなように自由に使用できます。それを別のクラスに渡すことを選択した場合、それは有効な使用法です。

于 2013-03-23T12:51:09.227 に答える
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);
    }
}
于 2013-03-23T12:55:04.247 に答える
1

カプセル化とは、外部コードを変更せずにモジュールの内部を変更できることを意味します。これはまだここにあります。したがって、カプセル化違反は発生していません。

于 2013-03-23T12:55:31.853 に答える