2012-02-23 2 views
1

OOPデザインパターンについての質問はありません。これはオーバーアーキテクチャーですが、私は判断ではなく、推薦が必要です。 「ビジネス要件」によって指定されたクラス階層があるとします。したがって、Pizza : FreightFlowers : Freight、およびTonOfBricks : Freightの深いバージョンがあり、IDispatchService<F> where F : FreightIDeliveryService<F> where F : Freightが得られました。将来のAPIから切り離す - 依存関係注入の必要性を最初に発見する

異なるIDeliveryServiceの実装では、貨物に関するさまざまな情報が必要であるとします。彼らが望むものはあなたのクラス階層と平行しておらず、どの種類の小包について1か月にどの配送サービス(すなわちAPI)を使用するのか分からない。さらに、1本のピザを真空管で送るのに十分な情報があるかもしれませんが、次のものではないかもしれません。

これで、あなたはピザをローラーブレードで手渡す人を雇うこともできることに気づきましたが、この方法で配送されるすべての物の重心を指定する必要があります。そうしないと、保険があなたを殺します。 IDeliveryService<Pizza>として実装していますか?新しいインターフェイスIHasCenterOfMassを追加していて、おそらくIDeliveryService<IHasCenterOfMass>として実装していますか?もしそうなら、ディスパッチャーはどのようにそれを気に入っていますか?重心のデータベースに関係を追加していますか?

答えて

1

トリックは、同じ基本クラス/インタフェースを共有している限り、派生するすべてのものが別の派生クラスで変更可能でなければならないことを示す置換原則に違反するものではありません。したがって、私のお勧めは、あなたのサービスがその必要なサービスの特定の情報を含むXXXServiceInformationインスタンスを受け入れ、ソースから潜在的にそれを読む方法を知ることです。例:

interface IDeliveryService<F> where F : Freight 
{ 
    void Deliver(); 
} 

class RollerBladesDeliveryService<F> : IDeliveryService<F> where F: Freight 
{ 
    public RollerBladesDeliveryService(RollerBladesDeliveryInformation<F> information){ ... } 

    void Deliver() { ... } 
} 

class RollerBladesDeliveryInformation<F> where F: Freight 
{ 
    public RollerBladesDeliveryInformation(F freight, double centerOfMass) { ... } 
} 
+0

ありがとうございます - それは私がどこに向かうのかですが、XXXDeliveryInformationのインスタンスはどこに置くのですか? –

+1

@ nik.shornikov - 私はあなたの質問を理解している場合は、論理的にあなたが運命のサービスに情報のインスタンスを保存するかわからない。情報インスタンスを作成する場所は、根本的な問題がある場所です。各サービスは情報オブジェクトを必要とするため、抽象的な方法でそれらのサービスを作成する必要がある時点まで問題が発生します。この場合、各貨物のcenterOfMassを決定するのに十分なほどスマートな工場が必要です。それは難しいことがあります。 – Polity

+0

ありがとうございます。あなたは、私が求めていたもの、つまりコンストラクターのコンテキスト(つまり、どこから来ている "deliveryinfo"引数があるか)について答えました。 –

3

あなたが知っていることを計画すると、ウサギの穴があなたが決して使用しないコードだけを作成するなら、何をすべきかを計画します。 IDeliveryServiceを実装できる3つのデリバリサービスが分かっていない場合は、汎用インターフェイスを作成できるかもしれませんが、将来的に必要なものに収まらない可能性があります。

+0

局留めルーチンは次のようになります。私は、型なしの "サービス情報"インスタンスをデータベースにシリアライズすることを考え始めたとき、私は "ウサギの穴"が当てはまることを認識しましたが、とにかく私は尋ねました。いくつかの良い応答。 –

1

は、あなたが「ビジネス要件」によって決定されるクラス階層があるとします。貨物、花::貨物とTonOfBricks:だから、あなたはピザの深いバージョンを持っている貨物を、あなたはIDispatchServiceを持ってここで、F:貨物とIDeliveryService F:貨物

停止権利のことを。それは正しいOOPではありません。ピザや花は貨物ではありません。彼らは貨物の中身です。この区別は、単一の責任でよりクリーンなコードを生成するため、非常に重要です。

は今、各IPizzaDeliveryService実装は同じ種類の情報を必要とするさまざまなIDeliveryService実装が貨物

ない限り問題に関するさまざまな情報を必要とします。私は同意することはできません

foreach (var freight in queue) 
{ 
    var service = GetServiceFor(freight.ContentType); 
    service.Dispatch(freight); 
} 

更新

public interface IFreight 
{ 
    IFreightContent Content{get;} 
    Type ContentType { get { return Content.GetType() }} 
    PostalAddress DeliveryAddress {get;} 
} 


public interface IFreightContent 
{ 
} 

// we don't just deliver the pizza, do we? ;) 
public class PizzaBox : IFreightContent 
{ 
} 
+0

最初の点は私に尋ねることから私を救っていないだろうが、配送ルーチンを想像する方法は私にとって非常に役に立ちます。 ContentTypeはTypeプロパティかenumだけですか?もしあなたがそれを開梱すれば、私は感謝しています。 –

+0

更新を読む。 – jgauffin

関連する問題