C# はマルチパラダイム言語です。インターフェイスとクラスをネストすることで、オブジェクトの構成を取得できます。このようにして、特定の問題をいくつかの単純な問題に分解し、各コンポーネントに解決すべき独自のパズルのピースを与えることができます。同じトリックを少し異なる方法で行うことができます。それぞれが独自の小さなタスクを解決する責任を負う機能の構成を作成し、すべてを組み合わせて相互接続して主要な問題への答えを与えることができます。
SOLID の原則に従うと、インターフェースの 95% が do-something という名前のメソッドを 1 つだけ実行し、そのインターフェースの名前が something-doer であるという状況に陥りました。このようなインターフェイスを実装するクラスは、そのメソッドが行うべきことを実行するために必要ないくつかのコンポーネントで DI されます。このようなアプローチは、基本的には関数を手作業でクロージャを作成することです。もしそうなら、それを自然に無料で行うデリゲートを使用しないのはなぜですか (入力は不要です)。単一のメソッド インターフェイスをデリゲートに完全に変換すると、コードからそれらの 95% が削除され、関数型言語で書かれたように見えます。しかし、インターフェイスに固執する大胆な理由がない限り、これは正しいことのように思えます。ある?
アップデート:
@Fendy、少し議論させてください。あなたは言った
「BLL からデリゲート ロジックを制御することはできません」 . デリゲートは、必ずしも呼び出し側でなくてもどこでも定義できます。これを完全に行うことができます:
public namespace Bbl
{
public static class TestableUtils {
public static Func<A, B> CreateA2B() {
Func<A, B> a2b = a => new B(a);
return a2b;
}
public static Func<B, C> CreateB2C() {
Func<B, C> b2c = b => new C(b);
return b2c;
}
public static Func<A, C> CreateA2C(Func<A, B> a2b, Func<B, C> b2c)
{
Func<A, C> a2c = a => b2c(a2b(a));
return a2c;
}
}
}
public namespace Caller
{
using Bbl;
public class Demo()
{
public void RunMe()
{
var a = new A();
var a2b = TestableUtils.CreateA2B();
var b2c = TestableUtils.CreateB2C();
var a2c = TestableUtils.CreateA2C(a2b, b2c);
var c = a2c(a);
}
}
}
「気をつけないとどこでもコード重複」そうですね、怠け者で気をつけて、同じ作業を何度もしないようにしましょう。同じ問題がクラスでも簡単に発生する可能性があります。したがって、デリゲートも例外ではありません。
「コンストラクターが注入され、可変エンティティを使用している場合、ステートフルなインターフェイスにつながる可能性があります」申し訳ありませんが、あなたの例に問題はありません。つまり、プログラムしたことを正確に実行します。エンティティを変異させた場合、これは当然のことですよね? Name がコンストラクタの外で設定されないようにするだけで安全です。それを行うと、あなたの例の状況は不可能になります。
基本的に、レイアウトした4つのポイントのうち、インターフェイス/クラスで同じことを行う場合と比較して、デリゲートを使用することでより多くの問題が発生することとは何の関係もありません。または、私はそれを取得しませんでした。