私は割引 (10% ディスク) と非割引 (0%) の 2 種類の製品を持っています。これらはそれぞれ LocalProduct / ExportableProduct のいずれかであり、輸出品には 15% の消費税がかかります。
このシナリオをモデル化する最良の方法は何ですか。私は S/W 設計の初心者であり、非常に限られたアイデアしかありません。
上記のオプションまたは他のオプションを使用して、これを効果的にモデル化する方法を提案してください。
私は割引 (10% ディスク) と非割引 (0%) の 2 種類の製品を持っています。これらはそれぞれ LocalProduct / ExportableProduct のいずれかであり、輸出品には 15% の消費税がかかります。
このシナリオをモデル化する最良の方法は何ですか。私は S/W 設計の初心者であり、非常に限られたアイデアしかありません。
上記のオプションまたは他のオプションを使用して、これを効果的にモデル化する方法を提案してください。
物事を単純にするために、割引が本当にサブタイプである必要があるかどうか、または「NonDiscounted」がゼロパーセントの割引を持っている製品のプロパティである可能性があるかどうかを自問してください。
私はこれを行います:
名前、説明、タイプなど、製品の基本的なプロパティを持つ「Product」というクラスがあります。
基本の「Product」クラスには、「DiscountRate」というプロパティを含めることができます。割引されていない場合は0、割引されている場合は任意の値にすることができます。これは、同じ式が常に適用されるため、計算を簡素化するのに役立ちます。1つのケースでは、割引は0です。
次に、「ExportableProduct」と「LocalProduct」の2つのクラスを作成できます。これらは、どちらも「Product」クラスから継承されます。
おそらくDiscounted/NonDiscountedはまったく種類の製品であってはならないことをお勧めします。代わりに、2つのサブタイプと、親製品の「割引」プロパティ/フィールドがあります。その後、各製品は効果的に割引を受けることができます。これにより、10%に固定されていない割引も可能になります。
これだけのために、継承(つまり、サブタイピング)を避けたいと思います。
代わりに、Discounted / NonDiscounted および Local / ExportableProduct の列挙を定義します。各製品クラスは、そのタイプを示すこれらのそれぞれのプロパティを持つだけです。
次に、PricingCalculator などの別のクラスで、製品のインスタンスを受け入れる Calculate メソッド (静的な場合もある) を定義します。このメソッドは、列挙型のプロパティを調べて、必要なパーセンテージ値を計算に適用するだけです。
これにより、価格の計算が製品自体から完全に分離され、場合によっては複雑な価格計算を 1 つの場所に保持できるようになります。料金体系は時間の経過とともに変化するため、このアプローチは簡単に保守およびテストできます。
私はすべてを避けて、2 つのプロパティだけを持ちますdiscount
。local
変化するのは 1 つ (価格) だけなので、その場で計算できます (割引 => price * .9
、輸出 => price * .85
- または両方 => 輸出 & 割引 => price * .9 * .85
) 。
継承は、型によって複数のものが異なる場合に特に役立ちます。
たとえば、商品の種類によって割引、税金、配送方法がすべて異なる場合は、継承とサブクラス化を検討する時期です (「このサブタイプの商品には、この税金とこの割引があり、この配送」)。
一方、型によって変化するものが 1 つだけの場合、複数の型 (つまり、サブクラスを持つ基本型) を持つ価値があるかどうか、またはその分散を単一の型としてより単純にモデル化できるかどうかはあまり明白ではありません。プロパティ値を持っています (例: "discount_percentage" という名前)。
クラスは一連の動作を区別します。それでは、これらの用語であなたの部門を見てみましょう。
割引あり/割引なしは動作のバリエーションであるという議論を行うことができますが、これを 1 つの動作に減らすのは簡単です: すべての製品には割引がありますが、割引されていない製品の割引額はたまたま 0% です。 . これは商品の単なる属性 (discount_amount) であり、別個のクラスではありません。
ローカル/エクスポート可能には、異なる動作がある場合とない場合があります。唯一の違いが製品の国際出荷が許可されているかどうかである場合、単純なブール値フラグでこの区別を十分に処理する必要があります。一方、輸出可能な製品がローカル製品でサポートされていない動作を必要とする場合 (税関要件と手続きの記録など)、ExportableProduct を LocalProduct のサブクラスにすることが適切です (輸出可能な製品の動作がローカル製品のスーパーセットである場合)。または、LocalProduct および ExportableProduct サブクラスを使用して抽象 Product クラスを作成します (ローカル製品にもエクスポート可能な製品でサポートされていない動作がある場合)。
必要な動作がこれだけの場合は、製品に 2 つのブール値を設定し、それらをオンにすることが最善の解決策です。ヤグニ。
しかし、それは大きな問題のほんの一部に過ぎないのではないかと心配しています。そして、あなたは自問しなければなりません: 何が製品を製品にするのか (単一の責任)。課税可能性と割引可能性はおそらく 2 つの異なる問題であるため、製品には 2 つの戦略があります。