2012-04-30 14 views
5

"Tell, don't Ask"-principleに続いて、OOPでゲッタを使うべきではありません。OOP - GET/SETなし

しかし、どのように問題を解決するには(少なくとも私はそうだと思いますが)、実際にはオブジェクトから「内部情報」が必要ですか?では、create_bill()関数が各アイテムの価格をASKする必要がないように、次の例を変更する方法はありますか?

class chopping_cart { 

    private $itemlist = array(); 

    function item_add($name, $price) { 
     $his->itemlist[]=new item($name, $price); 
    } 
    private create_bill() { 

     foreach $this->itemlist AS $element; 
     $sum += $element->get_price(); 

    } 
} 


class item { 
    private $name; 
    private $price; 
    function __construcor($name,$price) {...} 
    function get_price() { 
     return $price; 
    } 
} 

使用法:あなたは、あなたが参照しているオブジェクトを変更することが要求されたデータ/状態を使用していない場合は

$sc = new shopping_cart() 
$sc->item_add("Bike", 1.00); 
$sc->item_add("Ship", 2.00); 
$sc->create_bill(); 
+0

ショッピングカートにアイテムのアリスが含まれている場合、ショッピングカートに各アイテムの価格の価値を知ることができないのはなぜですか? – user12345613

+1

「尋ねないでください」と述べられている通り、それは悪いと思われる。 – Tom

+0

「尋ねないでください」という原則はどこから聞こえましたか?そのようなことを聞​​いたのは初めてだ。 – xxpor

答えて

7

、私は全くゲッターを使用してに何か問題がないと思います。

このようなシナリオについて、原則として協議:

if ($item->get_price() < 5) { 
    $item->set_price(5); 
} 

$item->set_minimum_price(5)のようなものになってしなければなりません。

4

あなたはそのクマ精密検査を参照している「Tell, Don't Ask」の記事から二つの項目があります。

  1. [...]決断を、それらの状態について[オブジェクト]質問をしていないが、その後、何をすべきかを教えてください。
    具体例では、chopping_cartはオブジェクト&を照会するだけで決定します。重要なのは、何をすべきかを教えてくれるわけではありません。
  2. Contract by Designによると、メソッド(クエリとコマンド)を自由に混在させることができ、そうすることでクラスの不変性に違反する方法がない限り、あなたは大丈夫です。しかし、あなたはクラス不変を維持している間に、あなたはあなたが暴露した状態の程度に応じて、呼び出し元と呼び出し先の間の結合を劇的に増加させるかもしれません。
    ゲッターコールは一般に自由に混在することができるので、クラス不変条件を維持する必要性に起因するカップリングはありません。

こうして、getterは "tell、do not ask"の原則が回避すると考えられる問題を引き起こさない。

2

この場合、Visitor design patternを使用できます。 ProductクラスでメソッドaddToBillを実装し、引数として、請求書インターフェイスを実装するインスタンスIBillを渡します。 IBillは、項目内で利用可能なすべての必要な情報を受け入れる方法addToTotalをサポートします。あなたの場合、これは価格です。たとえば、

ただし、常に不安定な地面に巻き込まれます。上記には、addToTotalのようなメソッドが必要です。不変式(合計は広告申込情報の価格と数量の積の合計と一致している必要があります)を導入する必要があります。 addToTotal: なしで実行することができます* Billで離れる; ShoppingCartは合計を記録します。製品番号&に加えて、addItemに価格を渡します。 addItemが合計を更新します。これは、あなたが多くのためにLineItemまたはProductを使用していないので、クラスを持つ目的を幾分打ち消します。これはまた、渡された価格と製品が作成されたときに与えられた価格が一致しなければならないという不変性を追加しますが、そうでなければ問題を引き起こすべきではありません。 * addItemProductLineItemをインスタンス化します。 addItemが合計を更新します。以前に追加されたアイテムを追加するときは、渡された$priceが以前の呼び出しで渡された金額と一致する必要があります。 *すべてのアイテムを一掃してください。 ShoppingCartには製品IDと数量が格納されます。 addItemを呼び出すと、合計が更新されます。 createBillはすでに計算された合計を使用します。他のものよりも、separate concernsを結んでいます。

他にも潜在的な設計がありますが、いずれも懸念の分離、不変量の導入、複雑さの追加などの問題があります。総計を計算するメソッド内で広告申込情報の合計金額に直接アクセスすることは、最も簡単ではあるが、最もクリーンで、エラーを生成する可能性は低いです。