2012-05-23 51 views
0

我應該開始說我是一個業餘愛好程序員。我練習(主要是)PHP,當我從休養生藥開始練習時,嘗試在一段時間內增強自己的知識,同時希望爲一路上的人們解決一些問題。這個施工估算工程應該考慮哪些設計模式?

最近,我一直在爲家庭家裝業務開發一個應用程序。該項目建立在codeigniter和mongodb上,雖然它工作,但我知道它並不漂亮。我花了一些時間閱讀設計模式,並且很難確定哪個適合這個項目的'估算'部分。

下面是它如何工作的:

用戶輸入一系列具體確定價格的方法測量。有時候,這些測量是特定於某種產品的 - 例如水槽。其他時候,測量與所做工作的關係比產品更密切 - 例如,使用乙烯基塑料覆蓋外部塑身罩。

所有這一切就是說,每個具體的估算方法需要不同的類型的測量。繼續上面的兩個例子...

要估計排水溝,我們必須知道,鍵入(小,大,屏幕)和線性腳。知道每種類型都有自己的價格是很重要的。

爲了估計拱腹,我們必須只知道線性腳。

估算方程相當簡單 - 數量x價格=估算 - 但數量可以是件數,腳數或平方英尺數。

我想知道是否讓這個過程比需要更復雜,但我想把我的技能提升到一個新的水平,並學會設計好的,面向對象的代碼。該項目的下一步是採取這些措施,並制定工作所需的材料清單 - 由於有大量可用產品,這是一項更爲複雜的工作。

我應該考慮哪些設計模式?到目前爲止,我主要看到Abstract FactoryBuilder應該在我的名單上嗎?還有什麼?

回答

1

難道你不只是創建一個「Estimator」接口,讓它需要一個名爲Estimate()的方法,然後用一組類來擴展接口,每個接口完成不同的估計。他們都會有一個構造函數,它接受輸入參數(估計所需的所有信息),並且它們都會影響估計函數,從而輸出總成本。

現在我知道你理解這種模式,因爲你列出了與它非常相似的模式。我只是想告訴你我是如何編碼的,所以你可以看看它是如何工作的。有時甚至當這聽起來像是一個糟糕的主意時,事情變得非常好,而且你無法想象它。

喜歡的東西:

interface Estimator 
{ 
    public function Estimate(); 
    public function BuildInfo(); 
} 

class Estimate_gutter implements Estimator 
{ 
    private $totalLength, $gutterType; 
    function __construct ($totalLength, $gutterType) 
    { 
     $this->totalLength = $totalLength; 
     $this->gutterType = $gutterType; 
    } 

    function Estimate() 
    { 
     return $this->totalLength * .45; // 45 cents a foot, consider a binary math library here though 
    } 

    function BuildInfo() 
    { 
     return "Gutter Type: {$this->gutterType}, Length: {$this->totalLength}"; //to keep different classes from having to output different values, thus breaking the idea of abstraction we are trying to achieve; we'll just output a string that will be printed to the job list. 
    } 
} 
class Estimate_sidewall implements Estimator 
{ 
    private $width, $height, $type; 
    function __construct ($drywallType, $width, $height) 
    { 
     $this->width = $width; 
     $this->height = $height; 
     $this->type = $drywallType; 
    } 

    function Estimate() 
    { 
     return $this->width * $this->height * 1.12; // 1.12 a square foot, again consider a binary math library 
    } 

    function BuildInfo() 
    { 
     return "SideWall type '{$this->type}' {$this->width}ft x {$this->height}ft = ". ($this->width * $this->height) ."sqft."; 
    } 
} 

$gutter = new Estimate_gutter(100, "Type to gutter"); //pass this to the view 

$gutter->Estimate(); //this would be run in the view, or be assigned in the controller to a variable for the view. This must exist, because it is implementing the Estimator class. The reason for this is so that you don't need to know what class type it is in the view, you just need to call the same function, no matter what. 

/* 
    This would print out all the information needed to retrieve 
    the needed product. It is important this function always returns 
    the *exact* same data type every time for every class, otherwise 
    the abstraction will break. (because if you output an array for one, 
    and a string for another, how do you know when to deal with an array, 
    and when to deal with a string? You'd need to know what type of estimate 
    you're making, and you're attempting to eliminate needing to know that 
    using this design pattern). 
*/ 
echo $gutter->BuildInfo(); 

雖然我很樂意看到其他的模式和解決這個問題,它不是唯一的,但是一個很好的解決方案可能是難以制定。

+0

這是一個很好的例子@mazzzzz。謝謝。我認爲這個項目的這部分工作會很好。 後續問題:該項目的另一部分將建立一個「材料清單」,告訴工作人員完成工作所需的材料。作爲一個例子,特定工作所需的乙烯基彎曲數量來自多個不同的測量(並且它們在估計上表現爲單獨的測量值)。我的問題是這樣的...如果我在'interface'中定義了一個類,我可以稍後使用該類中的函數來向builder提供信息嗎? – Ryan

+0

我沒有足夠的信息來真正制定對後續問題的反應(我不安靜地理解你想達到的目標)。如果你願意,你可以在界面中創建另一個函數(可能稱之爲BuilderInfo或其他),然後在每個類中實現該函數,讓它們生成信息(平方英尺,長度,具體名稱等) 。我會更新我的示例以包含該內容。 – Ben

相關問題