web-dev-qa-db-ja.com

このシナリオでは、継承の方が優れていますか、それとも構成デザインパターンですか?

キャッシュレジスターの設計と実装:

アイテムの数を考えると、合計請求額を計算する必要があります。アイテムは、いくつかの異なる方法で課金されます。

  • 各アイテムの特定の価格。例:チェリオスの箱はそれぞれ$ 6.99です

  • 重量による特定の価格、例:リンゴは1ポンドあたり2.49ドルです

  • アイテムは、一括割引を受ける可能性のある場所で販売できます。 2つ買うと1つ無料で販売; 4つ買うと1つ無料

  • 合計金額がしきい値を超えた場合に、請求書からお金を引き出すためのクーポンを利用できます。 100ドル以上使うと5ドルオフ

私の答え:どれだけ正しいのか、どうすれば改善できるのかわかりません!

C#に基づいてデザインを添付しました。コードは、 https://github.com/mandanemedia/Cas​​hRegister で表示できます。

継承がより良いか、構成を理解するのを手伝っていただければ幸いです。与えられたシナリオに基づいて、答えには次の具体的なクラスが必要です。

  • ProductSellByQuantity.cs
  • ProductSellByQuantityInGroupSell.cs
  • ProductSellByWeight.cs

2つのオブジェクトShoppingCartとShoppingCartByCouponと同様に、またはShoppingCartオブジェクトのみである可能性があります。

私の目標は、OOデザインスキルとデザインパターンを改善することです。

それをクリックすると、大きなサイズで開きます。 ProductSellSectionShoppingCart

1
Danial

時期尚早のオーバーエンジニアリング

たとえば、これらのinterfacesは必要ないと断言します。後で必要な場合は、後で作成します。

interface(C#キーワードの種類)は、無関係のクラスに共通の動作を与えてから、オブジェクトを多態的に処理するためのものです。

より具体的なクラスを構成するものについて、より慎重に考えてください。ショッピングカートとは何かを考えてみてください。 「クーポンショッピングカート」はより具体的な種類のカートですか、それとも単にカートの属性ですか。

すべてを別個の別個のビットとして見るのとは対照的に、物事がどのように連携するかについてより慎重に考えてください。クーポンは、価格計算の論理的な部分です。 GetPriceは、単に製品クラスで必要な「grunt」メソッドです。

「グループセール」はボリュームディスカウントです。これはクーポンと同じ概念です。どちらも割引です。別の言い方をすれば、それらは単に価格の調整です。したがって、それらはコスト計算の不可欠な部分です。それらはクラスではありません。


interfaceが多すぎます

実装ではなくインターフェイスへのコードすべてを(C#キーワード)interfaceにすることを意味するわけではありません。任意のクラスのパブリックメソッドのセットISインターフェイス。

抽象クラスから継承する代わりにインターフェースを実装すると、多くの冗長な実装が可能になります。

これは、_Interface segregation_原則のグロテスクな(申し訳ありませんが)誤用です。 ISellがそれ自体を別個のinterfaceとして正当化する方法がわかりません。 ISell参照が渡されているのがわかりません。 GetPrice()は、自然にProductXXXオブジェクトに属しているように見えます。その意味は、機能クラス内でより明確になります。

ショッピングカートも同様です。


重量、抽象化された数量

抽象化すると、複数の_ProductSellBy..._クラスが1つに合体することを強く疑っています。

これらは単なる値です。そして、これらの値は同じ方法で計算に使用されます。つまり、GetPrice() * Quantity()quantityが可算名詞または重みを表すという事実は、別のプロパティで取得できます。これにはすでにenumがあります。そのタイプのプロパティを、Productクラスに作成してください。

この抽象化により、多くのインターフェイスやクラスの動機がなくなり、ダイアグラムが半分以上縮小すると思います。


冗長な方法を乾かす

abstractsのProductクラスを作成します。


_ShoppingCart coupon_

「クーポンによる」は、ショッピングカートのサブクラスとしては意味がありません。クーポンは単に価格計算の調整です。

上記のように、interfaceをサブクラス化する必要がある場合は、それらのabstractsを削除し、ShoppingCartクラスを作成します。

そして、あなたがそれについて考えるとき、クーポンは本当に特別な場合ではありません。コストはどのアイテムでも同じようにクーポン割引されると思います。そのため、価格計算に割引を組み込むことができます。これは、割引を表さないクーポンのデフォルト値に対応しています。

2
radarbob