OOP(有益使用)(OOP (beneficial usage))

2019-06-24 02:12发布

如何在一个有利的方式使用OOP的问题,我认为作为一个例子篮子到它的主人(汤姆)具有一定ADDRESS(纽约州)可以添加项目(自行车,汽车)。 最后一个法案是印刷方含所有这些信息。

我的问题是:如何处理收集所需信息(这里:主人,城市,量的项目),从几个对象? 因为我认为这是愚蠢的手动执行此操作按以下步骤进行(见图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.";
    }

}

Answer 1:

如果你告诉不要问 ,你的确会增加一个渲染方法对账单,你会传递BillRenderer的一个实例。 然后比尔会告诉BillRenderer如何呈现比尔。 这是按照InformationExpert和高内聚原则暗示的方法,使其与最多的信息来完成任务的对象。

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

然后BillRenderer(界面)会知道的输出格式,比如你写的纯文本或HTML或PDF渲染器的混凝土:

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

echo $bill->renderAs(new TxtBillRenderer);

如果你的账单中包含的其他对象,那些将实现renderAs方法为好。 然后,该法案将通过渲染到这些对象。



Answer 2:

这两个篮子以及法案能有一个关系到一个位置项目 - 代表零个或多个项目具有数量和价格的有序列表的对象。

作为这样的列表是它的一个对象自身很容易绕过:

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

但该法案的印刷应该由做BillPrinter ,因为它不是账单打印自己的工作:

$billPrinter = new BillPrinter($bill, $printerDevice);
$billPrinter->print();


Answer 3:

首先,在PHP5的构造是public function __construct() 你所使用还有就是PHP4的方式。 然后用你的代码疗法eare其他问题:

  • 而不是传递城市的名称到的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类,那么你可以其或者打印外或发送给他人。

此外,您可能会受益于看willowing演讲:

  • 继承,多态与测试
  • 不要认准的事!
  • 干净的代码我:参数


文章来源: OOP (beneficial usage)
标签: php oop