1

私は、Configuratorその仕事をするためにContext、インターフェースを介してオブジェクトを受け取る必要があるクラスを持っています:

public class Configurator : IContextAware
{
    private IContext _context;

    //property setter defined by the IContextAware interface
    public IContext Context { set { _context = value; } }

    //  use _context object in other methods here ...
}

私は、フィールドを同じ方法でConfigurator初期化する必要がある多くの型を書く予定です。_context私が最初に考えたのは、「インターネット上のすべてのプログラマーを怒らせて、継承を使用してみませんか?」ということでした。

public class ContextInitializer: IContextAware
{
    // field to hold the injected context
    protected IContext _context;

    //property setter defined by the IContextAware interface
    public IContext Context { set { _context = value; } }
}

public class Configurator : ContextInitializer
{
    //  use _context object here ...
}

このように、Context オブジェクトを必要とする私が作成した他のクラスは、ContextInitializer から継承するだけで、Context オブジェクトをすぐに使用できます。

長所: 一貫した初期化が保証され、気を散らさず、すべてのクラスで初期化コードが重複していない

短所: 実装の継承は悪です!..ええと、Configurator は他のどのクラスからも継承できません..??

いずれにせよ、Configurator はIContextAwareインターフェイスを実装する必要があることを明確にする必要があります。また、クラスにはデフォルト/引数なしのコンストラクターが必要であるため、コンストラクター依存性注入はここではオプションではありません。

同じ利点を達成するために合成を使用する方法を誰かが提案できますが、より柔軟な設計で、および/または上記の継承ソリューションの実際の欠点を説明できますか? ありがとう!

PS これは、Spring.Net CodeConfig から採用されたものです。

4

1 に答える 1

1

.NET Base Class Library は、このような質問に答える良い標準だと思います。継承の使用は、API のユーザーを API 内部に公開するため、BCL に入れられることはありません。セマンティックな意味を持たない基底クラスが存在するようになりました。コードを保存するためだけに存在します。すべてのパブリック API 要素には、目的とセマンティックな意味が必要です。

API の設計に関しては、BCL の作成者は明らかに非常に厳格です。これほど膨大でありながら原始的なタイプのコレクションを見たことがありません。

とはいえ、そのレベルの API クリーン度が必要ない場合は、同じ標準に従う必要はありません。すべての API が何百万人もの開発者に公開されているわけではありません。多くのコードを節約し、冗長性とエラーの可能性を排除するために、API の純粋性を少し犠牲にすることは正当なトレードオフです。

私の選択:内部コードにあなたのアプローチを使用します。パブリック API (Codeplex ライブラリなどを考えてください) については、冗長なものを複製して、パブリック API の表面をきれいに保ちたいと思います。

于 2013-08-28T16:17:32.537 に答える