4

これは、「分析による麻痺」が定着しているように見えるシナリオの 1 つです。アドバイスをお願いします。

プロジェクト

部品の参照、どの車両に適合するかなどの詳細を含む、自動車製品のかなり単純なリスト。

フロント エンドは、asp.net MVC アプリケーションです。

バックエンドは SQL で、Subsonic を使用して製品をドメイン オブジェクトに投影します。

機能性

私たちの画面の 1 つは、製品の詳細画面です。ASP.NET MVC コントローラーは、製品リポジトリを呼び出して製品の詳細を取得し、これらの詳細を (viewModel への自動マッピングを介して) ビューに返します。

ここで重要なのは、Web サイトに 2 つまたは 3 つのチャネルがあることです。チャネルに応じて、ユーザーは異なる部品番号を確認する必要があります。

たとえば、小売チャネルの場合、部品番号はデータベースにあるとおりですが、ユーザーが貿易チャネルを通じてサイトにアクセスした場合、部品参照の先頭は別の番号に置き換えられます。

たとえば、0900876 は、Trade チャネルを介して表示された場合、1700876 になります。

私が苦労しているのは、パーツ参照 (および変更される可能性のあるその他の詳細) に関する「チャネル規則」をカプセル化する場所を決定することです。

これらの代替案を検討しました。

ロジックをドメイン オブジェクトに直接書き込む

Productクラスでは、翻訳されたパーツ参照を取得するためのメソッド/プロパティを持つことができます。

public string TranslatedPartRef()
    {
        if (this.Channel == "Trade")
        {
            return PartRef.Replace("0900", "1700");
        }
        else
        {
            return PartRef;
        }
    }      

このシナリオでは、 Product インスタンスはチャネルについて知っている必要がありますが、これは私には間違っているようです。

ロジックを別のオブジェクトにカプセル化する

このパーツ参照の変換を処理するクラスを作成するか、このロジックを含むChannelクラスを作成することができます。

私が理解していないのは、2つのクラスを調整する方法です。

コントローラがリポジトリを呼び出して製品を取得する場合、使用されたチャネルを特定して部品参照を変換する必要がありますか? その場合、翻訳された部品参照を含む製品をビューに戻すにはどうすればよいですか?

また、この部品参照は検索結果や他のシナリオにも表示される必要があることも注目に値します。そのため、ドメイン内のどこかにきちんと含まれている必要があると思います。

4

5 に答える 5

2

自分自身に問いかける必要がある最初の質問は、チャネルの概念がドメインの概念であるかどうかです。あなたの質問はそうではないことを示しているようですが、一方で、それはアプリケーション固有のようにも聞こえないと思います。

あなたが尋ねることができる追加の質問は、将来、このドメインモデルの上に別のアプリケーションを構築する必要がある場合(たとえば、Webサービスまたはリッチクライアント)、チャネルの概念に対処する必要がありますか?

私の推測では、答えはイエスかもしれません。

私があなたの質問を理解している限り、チャンネルは何らかの形でリクエストコンテキストに関連しています。おそらく、それは実際にはユーザーの属性です。または、おそらく、アプリケーション構成自体の属性です。

いずれにせよ、結局のところ、それが本当にドメインの概念ではないかどうかについては、私は一生懸命考えます。もしそうなら、それはドメインオブジェクトにうまく属することができます。

そうでない場合、ptomliによって提案されたデコレータの実装は良いアプローチのように聞こえます。

于 2009-09-15T08:09:53.083 に答える
2

私は C# の専門家ではありませんが、Java のデコレータでこれを攻撃すると思います。

Product のインターフェースがあると仮定すると、部品番号の問題を管理する Decorator を作成できます。

class Product implements IProduct {
    public String getProductCode();
    // etc
}

class ProductChannelDecorator implements IProduct
{
    // constructor, like this in C#?
    public ProductChannelDecorator(IProduct product, Channel channel) { 
        this.product = product;
        this.channel = channel;
    }
    public String getProductCode() {
        switch (this.channel) {
            case Channel.RETAIL:
                return this.decorated.getProductCode();
            case Channel.TRADE:
                return retailToTradeTransformer(this.product.getProductCode());
            // etc
        }
    }
    // etc
}
于 2009-09-15T07:58:29.287 に答える
0

部品番号のマッピングが変更される可能性がある場合はどうなりますか?現在、変更されるプレフィックスですが、他の種類の変更に対応する必要がありますか?多分あなたはこれを必要としないでしょう、しかし:

ビジネスレベルでは、チャネルに応じて製品の部品番号が異なる可能性があると言っています(これは結局のところ基本的なビジネスコンセプトです)。つまり、データベースレベルでは、ProductId、ChannelId、およびPartNumber列を持つPartNumberテーブルがどこかに存在する可能性があることを示しています。これは確かに、時間の経過とともにより多くのチャネルが表示される場合をカバーします(今日は小売または貿易、明日はWeb、メールオーダーなどを追加する可能性があります。これらはすべて異なる部品番号が必要になる可能性があります)。

オブジェクトレベルでは、これは、を指定して適切なパーツ番号を取得するために使用できるProductaを持つインスタンスにマップされます。Dictionary<Channel, PartNumber>Channel

于 2009-09-15T08:20:20.170 に答える
0

部品番号のさまざまなバリエーションがいくつありますか。Trade v Retailだけの場合は、Productオブジェクトに両方の番号を入れて、どちらを表示するかをUIに決定させたいと思うでしょう。製品を操作する場合、IDは「type {Trade、Retail}、number」にすることができます。

柔軟なモードの場合、それはあなたのチャンネルのアイデアでいいと思います。しかし、小売業と貿易をマッピングするという双方向の責任があれば、これはうまくいくように思われます。Channelオブジェクトは、他の変換や拡張が可能なアダプターと見なされます。

実装として、チャネルごとに個別のChannelオブジェクトを作成し、caseステートメントやelseelseロジックを回避しようとします。Retailの場合、ChannelオブジェクトはTradeのNOOPオブジェクトである可能性があり、マッピングを実行できます。ファクトリは、approporayeChannelオブジェクトを作成できます。

于 2009-09-15T08:01:28.017 に答える