OOP(有益用法) [英] OOP (beneficial usage)

查看:80
本文介绍了OOP(有益用法)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

关于如何以一种有益的方式使用OOP 的问题,我以一个篮子为例,其拥有一定地址(NY)的所有者(Tom)可以在其中添加文章(自行车,汽车).最终打印出包含所有这些信息的账单.

for my question on how to use OOP in a beneficial way I assume as an example a BASKET to which its owner (Tom) having a certain ADDRESS (NY) can add ARTICLES (Bike, Car). Finally a BILL is printed containg all these information.

我的问题是:如何处理从多个对象收集所需的信息(在这里:所有者,城市,物品数量)?因为我认为手动执行以下操作(见4.)很愚蠢,不是吗? (甚至更多,因为实际上信息量在增加)

My problem is: How to handle collecting the information desired (here: owner, city, amount of items) from several objects? Because I think it is stupid to do this manually as done below (see 4.), isn't it? (even more since the amount of information increases in reality)

那么在此示例中创建账单/收集所需信息的干净方法"是什么?

So what is the "clean way" for creating the bill / collecting the information needed in this example?

<?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.";
    }

}

推荐答案

如果您这样做告诉不要询问,您确实可以在Bill上添加一个render方法,并向其传递BillRenderer实例.然后,Bill会告诉BillRenderer如何呈现该法案.这符合 InformationExpert和高凝聚力原则,建议在信息量最大的对象上执行任务的方法.

If you do Tell Dont Ask, you would indeed add a render method to the bill to which you would pass an instance of BillRenderer. Bill would then tell BillRenderer how to render the Bill. This is in accordance with InformationExpert and High Cohesion principles that suggest methods to be on the objects with the most information to fulfill the task.

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

然后

BillRenderer(接口)将知道输出格式,例如您将为PlainText或HTML或PDF编写具体的渲染器:

BillRenderer (an interface) would then know the output format, e.g. you'd write concrete renderers for PlainText or HTML or 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方法.然后,条例草案会将渲染器向下传递到这些对象.

If your Bill contains other objects, those would implement a renderAs method as well. The Bill would then pass the renderer down to these objects.

这篇关于OOP(有益用法)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆