你能不能只创建一个“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 ();
虽然我很想看到这个问题的其他模式和解决方案,但它并不是独一无二的,但一个好的解决方案可能很难制定。