2016-02-28 50 views
0

我做了一些修改,所以希望有更清楚什麼要問

我工作的一個PHP項目,我在那裏我需要計算總計算總價格的發票基於單個項目的總數。
根據我們的要求,我們要創建一個包含類對象的實例變量,然後使用一個方法遍歷數組並計算總數。

這是我到目前爲止有:
InvoiceItem使用特定的陣列值

class InvoiceItem { 
    private $itemId; 
    private $itemQty; 
    private $itemPrice; 
    private $itemDescription; 
    private $total; 

    public function __get($attr) { 
     return $this->$attr; 
    } 
    public function __set($attr, $val) { 
     $this->$attr = $val; 
    } 

    public function calculateItemTotal() { 
     // This method will calculate the total by multiplying the quantity times the price. 
     $this->total = $this->__get("itemQty") * $this->__get("itemPrice"); 
    }  
    public function display() { 
     // This method will generate a String that contains a one-line value for this object. 
     // It should include all the instance variables and the total for this item. 
     $display_format = "ID: %s, Quantity: %s, Price: %s, Description: %s, Total: %s<br />"; 

     return sprintf($display_format,$this->__get("itemId"),$this->__get("itemQty"), 
     $this->__get("itemPrice"),$this->__get("itemDescription"), $this->__get("total")); 
    } 
} 

這是我(到目前爲止)在課堂上,我試圖做計算Invoice

class Invoice { 
    private $items; 
    private $invoice_total; 

    public function __construct() { 
     $this->items = array(new InvoiceItem()); 
    } 

    // Magic Method Getters/Setters 
    public function __get($attr) { 
     return $this->$attr; 
    } 
    public function __set($attr, $val) { 
     $this->$attr = $val; 
    } 

    public function calculateInvoice() { 
     // it's supposed to loop through my array and calculate the invoice total here 
    } 
    public function displayInvoice() { 
     // this is supposed to call the parent 'display()' method to list each InvoiceItem 
     // call calculateInvoice() and print the $invoice_total 
    } 
} 

讀出在最後應該是這樣的:
ID:1,數量:3,價格:5,描述:Foo,總數:15
ID:2,Quanti TY:6,價格:3,說明:酒吧,共有18條
發票總額:33

我知道,有些事情就不是最有效的(蝙蝠),但我想學習先執行它然後再重構。

+0

首先,一個InvoiceItem將「有一個」發票,並且一個發票將「有很多」InvoiceItems,但它們不一定是鏈接的,不應該繼承或擴展 –

+0

@RobbieAverill,我知道一個通​​常不會,以這種方式繼承。我主要是想弄清楚如何達到目前的要求。我打算重做/學習一次,我可以先學習 – kmancusi

+0

Hi @kmancusi - 如果您堅持使用當前結構,那麼您至少應該更改它,以便InvoiceItem擴展發票而不是其他方式。 –

回答

0

整體結構看起來相當不錯。你用這個組合來代替繼承,這很好。

有幾個簡單的變化,你可以進一步簡化它。

  • 你可以稍微改變Invoice的構造函數接收InvoiceItem對象的列表。這將使您的Invoice類從實例化的那一刻開始有效。

    public function __construct(array $invoiceItems) { 
        $this->loadInvoiceItems($invoiceItems); 
    } 
    
    private function loadInvoiceItems(array $invoiceItems){ 
        $this->items = array_map(function(InvoiceItem $item){ 
         return $item; 
        }, $invoiceItems); 
    } 
    

    這使你的API到這個樣子,這是我要說的卻是更清晰,更方便:

    $myInvoice = new Invoice([ 
        new InvoiceItem(1, 2, 2, "4"), 
        new InvoiceItem(2, 1, 3, "3"), 
        new InvoiceItem(2, 3, 5, "15"), 
    ]); 
    
  • 以同樣的價格,你還可以修改InvoiceItem的構造。你不需要在總傳球,因爲你可以從數量和單價推斷它(除非是否有阻止這是真實的特殊規則):

    public function __construct($id, $qty, $price, $description = "") { 
        $this->itemId = $id; 
        $this->itemQty = $qty; 
        $this->itemPrice = $price; 
        $this->itemDescription = $description; 
        $this->calculateItemTotal(); 
    } 
    
  • 要計算你displayInvoice方法,你只能通過你的項目需要循環和積累的響應:

    public function displayInvoice() { 
        $displayItems = $this->fetchAllDisplayItems(); 
        $displayItems[] = $this->displayInvoiceTotal(); 
    
        return implode(PHP_EOL, $displayItems); 
    } 
    
    private function fetchAllDisplayItems(){ 
        return array_map(function(InvoiceItem $item){ 
         return $item->display(); 
        }, $this->items); 
    } 
    
    private function displayInvoiceTotal(){ 
        return "Invoice Total: ". $this->calculateTotalInvoice(); 
    } 
    
    private function calculateTotalInvoice(){ 
        return array_sum(array_map(function(InvoiceItem $item){ 
         return $item->getTotal(); 
        }, $this->items)); 
    } 
    
  • 另一件事我強烈建議你這樣做,將消除對getter和setter的魔術方法。想想你的對象需要處於一個有效的狀態並通過它的構造函數傳遞它。這應該擺脫大部分制定者。就獲得者而言,確定哪些是實際需要的,並擺脫其餘的。

+0

感謝您的反饋 - 誠然,這絕對超出了我目前的理解水平,但這對未來的工作將有所幫助 – kmancusi

+0

對不起,我的回覆可能看起來有點緊張。確保你慢慢地逐步閱讀它。如果您希望我澄清某些事情或進一步解釋,請告訴我。 – hasumedic

0

想通了什麼,我做錯了:這是主要的如何一個誤區,實現我的數組

class Invoice { 
    private $items = array(); 
    private $invoice_total; 

    // Magic Method Getters/Setters 
    public function __get($attr) { 
     return $this->$attr; 
    } 
    public function __set($attr, $val) { 
     $this->$attr = $val; 
    } 

    public function calculateInvoice() { 
     foreach ($this->__get("items") as $item) { 
     $this->invoice_total += $item->itemTotal; 
     } 
    } 
    public function displayInvoice() { 
     foreach ($this->__get("items") as $item) { 
      $item->calculateItemTotal();  
      echo $item->display(); 
     } 
     $this->calculateInvoice(); 
     $total_output = "<label for='invoice_total'>" . "Invoice Total: $%s" . "</label>"; 
     echo "<br />"; 
     echo sprintf($total_output, $this->__get("invoice_total")); 

    } 
} 

這次演習是爲了專注於使用了硬編碼,價值觀,所以這或多或少是我在考慮和定義InvoiceItem屬性並將其正確存儲到數組中的問題,而我最初在創建時混淆了