我会从视图(检查打印的方式)分离领域模型(支票,银行等)开始。这是MVC模式背后的基本思想,其目标之一是允许以不同方式显示相同的域模型(这似乎是您的情况)。所以,我会首先创建域类,类似:
class Cheque
{
protected $bank;
protected $money;
...
}
class Bank {...}
注意,这些类是MVC三层的“M”和实现域模型的逻辑,而不是行为相关的渲染过程。下一步将是实现用于呈现支票的View类。采用哪种方法在很大程度上取决于渲染的复杂程度,但我首先需要一个ChequeView
类来呈现公共部分,并将其委托给其他子视图中可以更改的特定部分(在本例中为日期):
abstract class ChequeView
{
protected $cheque;
protected $dateView;
public function __construct($cheque)
{
$this->cheque = $cheque;
$this->dateView = //Whatever process you use to decide if the payment date is shown or not
}
public function render()
{
$this->coreRender();
$this->dateView->render();
}
abstract protected function coreRender();
}
class BankACheckView extends ChequeView
{
protected function coreRender() {...}
}
class BankBCheckView extends ChequeView
{
protected function coreRender() {...}
}
abstract class DateView
{
abstract function render()
}
class ShowDateView extends DateView
{
function render() {...}
}
class NullDateView extends DateView
{
function render() {...}
}
而且,如果有代码跨子类重用,你可以将它们在ChequeView
,使coreRender()
当然因素给他们打电话。
如果您的渲染过于复杂,这种设计可能无法扩展。在这种情况下,我会把你的视图分解成有意义的子部分(例如HeaderView
,AmountView
等),以便渲染一张支票变得基本上呈现其不同的子部分。在这种情况下,ChequeView
可能会基本上以Composite的形式工作。最后,如果您遇到这种情况,并且设置ChequeView
事实证明是一项复杂的任务,您可能需要使用Builder。基于在OP
编辑点评
构建器主要用于当最终对象的实例化是一个复杂的过程(例如,有很多事情,为了得到一个子部分之间同步一致的整体)。通常有一个构建器类和不同的客户端,它们发送消息(可能以不同的顺序和不同的参数)来创建各种最终对象。所以,虽然没有被禁止,但每个要构建的对象类型都有一个构建器并不常见。
如果您正在寻找表示创建特定实例的类,则可能需要检查Factory模式族(可能Abstract Factory与您的想法非常相似)。
HTH
如果它们都具有相同的坐标不同的组件,可以考虑在同一个对象中使用不同的构造函数。 – Dukeling 2013-02-19 05:31:46
可能是部分使用http://en.wikipedia.org/wiki/Visitor_pattern进行打印? – 2013-02-19 06:19:35