Constructor Controlled Inheritance
工场模式是比较常用的创建性模式,这个东西的出现是为了避免switch到处飞的局面,把switch集中放到一个地方创建对象,虽然还是需要switch,不过至少好维护多了.
Axapta里的Constructor Controlled Inheritance这个是工厂模式的一种实现,只不过创建的工作有父类来完成罢了,这个用法在Axapta中随处可见.比如负责销售订单打印的父类SalesFormLetter,由于销售订单有多个状态,每个状态都会有不同类来实现打印,这样就有了SalesForlLetter_Invoice等几个子类,Axapta如何创建这些子类的那?代码如下:
static SalesFormLetter construct(DocumentStatus document,
boolean getParmId = true)
{
switch(document)
{
case DocumentStatus::Quotation : return new SalesFormLetter_Quotation (getParmId);
case DocumentStatus::Confirmation : return new SalesFormLetter_Confirm (getParmId);
case DocumentStatus::PickingList : return SalesFormletter_PickingList::construct(getParmId);
case DocumentStatus::PackingSlip : return new SalesFormLetter_PackingSlip (getParmId);
case DocumentStatus::ProjectPackingSlip : return new SalesFormLetter_PackingSlipProject(getParmId);
case DocumentStatus::Invoice : return new SalesFormLetter_Invoice (getParmId);
case DocumentStatus::ProjectInvoice : return new SalesFormLetter_InvoiceProject (getParmId);
default : throw error(strFmt("@SYS19306",funcName()));
}
throw error(strFmt("@SYS19306",funcName()));
}
boolean getParmId = true)
{
switch(document)
{
case DocumentStatus::Quotation : return new SalesFormLetter_Quotation (getParmId);
case DocumentStatus::Confirmation : return new SalesFormLetter_Confirm (getParmId);
case DocumentStatus::PickingList : return SalesFormletter_PickingList::construct(getParmId);
case DocumentStatus::PackingSlip : return new SalesFormLetter_PackingSlip (getParmId);
case DocumentStatus::ProjectPackingSlip : return new SalesFormLetter_PackingSlipProject(getParmId);
case DocumentStatus::Invoice : return new SalesFormLetter_Invoice (getParmId);
case DocumentStatus::ProjectInvoice : return new SalesFormLetter_InvoiceProject (getParmId);
default : throw error(strFmt("@SYS19306",funcName()));
}
throw error(strFmt("@SYS19306",funcName()));
}
父类根据不同的文档状态来创建不同的子类来实现各自的打印功能.
通过MenuItem调用的时候,EnumTypeParameter的DocumentStatus,EnumParameter对应相应的值,调用对象为SalesFormLetter.
在写父类的时候并不知道会有多少个子类,或者说将来新加了子类岂不是要改写父类?我觉得这很正常,即使是工厂模式,在增加了需要创建的类的时候,不也是要改写工厂类吗,只不过这里改的是父类的代码,如此而已.