我应该为这个建筑评估项目考虑哪些设计模式?

时间:2012-05-23 01:35:01

标签: php codeigniter design-patterns

我应该首先说我是一个业余爱好程序员。我练习(主要)PHP,当我从练习医学休息时,并试图建立我的知识随着时间的推移,同时希望在整个过程中为人们解决一些问题。

最近,我一直在为我家的家装业务申请。该项目建立在codeigniter和mongodb上,虽然它有效,但我知道它并不漂亮。我花了一些时间阅读设计模式,并且很难决定哪一个适合这个项目的“估算者”部分。

以下是它的工作原理:

用户输入特定于确定价格的方法的一系列测量。有时,这些测量特定于某种产品 - 例如排水沟。其他时候,测量与正在进行的工作关系比产品更密切 - 覆盖外部拱腹与乙烯基和&例如,铝。

所有这些都表明每种特定的估算方法都需要不同的类型测量值。继续上面的两个例子......

要估算我们必须知道的排水沟,键入(小,大,屏幕)和线性脚。重要的是要知道每种类型都有与之相关的价格。

为了估算下腹部,我们必须只知道线性尺。

估算方程式相当简单 - 数量x价格=估计 - 但数量可以是件数,英尺数或平方英尺数。

我想知道我是否让它变得比它需要的更复杂,但我想把我的技能提升到一个新的水平并学习设计好的,面向对象的代码。该项目的下一步是采取这些测量并制定一份工作所需材料清单 - 由于有大量可用产品,这项工作要复杂得多。

我应该考虑哪些设计模式?到目前为止,我主要关注Abstract FactoryBuilder应该列在我的名单上吗?还有什么?

1 个答案:

答案 0 :(得分: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 ();

虽然我很想看到这个问题的其他模式和解决方案,但它并不是唯一的,但很难制定出一个好的解决方案。