1

有益な方法で OOP を使用する方法に関する私の質問では、特定のアドレス (NY) を持つ所有者 (Tom) が ARTICLES (自転車、車) を追加できる BASKET を例として想定します。最後に、これらすべての情報を含む請求書が印刷されます。

私の問題は次のとおりです:複数のオブジェクトから必要な情報(ここでは所有者、都市、アイテムの量)を収集する方法は? 以下のように手動で行うのはばかげていると思うので(4.を参照)、そうではありませんか?(現実は情報量が増えるのでなおさら)

では、請求書を作成したり、この例で必要な情報を収集したりするための「クリーンな方法」は何ですか?

<?php
$a = new basket('Tom','NY');
$a->add_item("Bike",1.99);
$a->add_item("Car",2.99);

$b = new bill( $a );
$b->do_print();

1.

class basket {

    private $owner = "";
    private $addr = "";
    private $articles = array();

    function basket( $name, $city ) {
        // Constructor
        $this->owner = $name;
        $this->addr = new addresse( $city );

    }

    function add_item( $name, $price ) {
        $this->articles[] = new article( $name, $price );
    }

    function item_count() {
        return count($this->articles);
    }

    function get_owner() {
        return $this->owner;
    }

    function get_addr() {
        return $this->addr;
    }

}

2.

class addresse {

    private $city;

    function addresse( $city ) {
        // Constructor
        $this->city = $city;
    }

    function get_city() {
        return $this->city;
    }

}

3.

class article {

    private $name = "";
    private $price = "";

    function article( $n, $p ) {
        // Constructor
        $this->name = $n;
        $this->price = $p;
    }   

}

4.

class bill {

    private $recipient = "";
    private $city = "";
    private $amount = "";

    function bill( $basket_object ) {

        $this->recipient = $basket_object->get_owner();
        $this->city = $basket_object->get_addr()->get_city();
        $this->amount = $basket_object->item_count();

    }

    function do_print () {
        echo "Bill for " . $this->recipient . " living in " . $this->city . " for a total of " . $this->amount . " Items.";
    }

}
4

3 に答える 3

2

Tell Dont Askを実行すると、BillRenderer のインスタンスを渡す 請求書に render メソッドが追加されます。その後、Bill は BillRenderer に Bill のレンダリング方法を指示します。これは、InformationExpert と High Cohesion の原則に従っており、タスクを実行するための情報が最も多いオブジェクトにメソッドを配置することを提案しています。

class Bill
{
    …
    public function renderAs(BillRenderer $billRenderer)
    {
        $billRenderer->setRecipient($this->owner);
        $billRenderer->setAddress($this->address);
        …
        return $billRenderer->render();
    }
}

次に、BillRenderer (インターフェース) は出力形式を認識します。たとえば、PlainText、HTML、または PDF の具体的なレンダラーを作成します。

class TxtBillRenderer implements BillRenderer
{
    …
    public function render()
    {
        return sprintf('Invoice for %s, %s', $this->name, $this->address);
    }
}

echo $bill->renderAs(new TxtBillRenderer);

Bill に他のオブジェクトが含まれている場合、それらも renderAs メソッドを実装します。その後、法案はレンダラーをこれらのオブジェクトに渡します。

于 2012-04-30T18:28:27.393 に答える
1

バスケットと請求書の両方が、位置アイテム (カウントと価格を持つ 0 個以上のアイテムの順序付けられたリストを表すオブジェクト) と関係を持つことができます。

このようなリストはそれ自体のオブジェクトであるため、簡単に渡すことができます。

$bill = new Bill($buyer, $address, $basket->getPositions());

ただし、請求BillPrinter書自体を印刷するのは請求書の仕事ではないため、請求書の印刷は で行う必要があります。

$billPrinter = new BillPrinter($bill, $printerDevice);
$billPrinter->print();
于 2012-04-30T17:38:17.883 に答える
1

まず、PHP5 ではコンストラクター it public function __construct(). そこで使用しているのはPHP4の方法です。そして、あなたのコードには他の問題があります:

  • 都市の名前Basketを(ということCartですか?)に渡す代わりに、住所オブジェクトのインスタンスを作成して渡す必要があります。
  • 名前や金額に基づいてアイテムをバスケットに追加するのではなく、アイテムのインスタンス全体を追加しないでください。そうしないと、サイトの言語や通貨を切り替えるときに多くの問題が発生します。
  • Articles(ということですItemsか?) は、名前ではなく ID に基づいて作成する必要があります。その理由は上記と同じですが、一意性の問題が発生します。また、組み合わせてご購入いただくと、お安くなる商品もございます。それらを安全に識別する方法が必要です。

そこでのコードのクリーンアップに関しては:

  • コンストラクターで指定されたパラメーターからインスタンスを作成するのをやめるべきです。それは必ずしも悪いことではありませんが、あなたの場合、あなたはそこを混乱させています。
  • Bill印刷自体には責任を負いません。

何かのようなもの :

class Basket
{
    // -- other code 

    public function handleInvoice( Bill $invoice )
    {
        $invoice->chargeFor( $this->items );
        $invoice->chargeTo( $this->account );
        return $invoice->process();
    }
}

..それを次のように使用します

$cart = new Basket(..);
// some operation with it

$invoice = new Bill;
$cart->handleInvoice($invoice);

$printer = new PDFPrinter;
// OR new JpegPrinter; OR new FakePrinter OR anything else
$printer->print( $invoice );

これにより、クラス外のインスタンスが得られ、Billそれを印刷したり、誰かに送信したりできます。

また、意欲的な講義を視聴することも有益です。

于 2012-05-01T05:02:24.390 に答える