工厂模式
作者 陈省
创建模式
对于OOP开发来说,创建对象,使用对象是最常见的工作了。那么创建模式就是讨论创建对象过程中需要使用的模式。通常来说,在Delphi中创建一个对象,只要简单的调用被创建对象的构造函数就可以了,大致如下:
AObj=TxxxObj.Create();
但是很多时候,我们需要的对象在不同的应用场景需要配置不同的属性值,比如对于常见的按钮组件来说,对于一个项目来说,为了使界面保证具有一致的风格,可能就需要一些固定大小的按钮,有些需要一些大尺寸的按钮,而在另外一些界面中需要小尺寸的按钮。那么可以将创建不同属性的组件的任务由抽象出来的创建类来完成。
那么凡是创建组件的模式就统称为创建模式。
工厂模式
工厂模式就是一个被人们反复使用的设计模式,所谓的工厂模式可以想像成一个工厂类,工厂类能够大批量的重复的生产相对固定的几种产品,比如调用类的CreateBigBtn可以生产大尺寸的按钮,调用类的CreateSmallBtn可以生产小尺寸的按钮。
使用工厂类的方法来创建具体产品类的好处就是,Button是一个需要大量使用的组件,而Button的样式对于一个特定的程序又是比较固定的。而工厂类的模式正好比较适合生产不同尺寸的Button这样的产品。好处就是当项目不同时,需要的Button尺寸可能不同,如果不使用工厂类的方法,则当尺寸修改时,就要硬编码上百个Button的尺寸,如果项目中频繁的变更按钮尺寸的话,会造成极大的混乱。而使用工厂类的方法,只要修改创建按钮的工厂类的方法的内部实现对尺寸进行全局范围的修改,这样对项目的变动就从几百处减少到了几处,极大的减少了工作量和出错的几率。
下面就是一个示意性的创建按钮的类工厂:
TButtonFactory=class(TObject)
public
class function CreateBigBtn():TButton;
class function CreateSmallBtn():TButton;
end;
class function TButtonFactory.CreateBigBtn: TButton;
begin
result:=TButton.Create(nil);
Result.Height:=40;
Result.Width:=40;
end;
class function TButtonFactory.CreateSmallBtn: TButton;
begin
result:=TButton.Create(nil);
Result.Height:=20;
Result.Width:=20;
end;
抽象工厂模型
上面提到的是简单工厂模型,这种模型适用于单个项目的需求,考虑到对于不同项目有不同的界面风格,比如为A单位做的程序客户要求大按钮的尺寸是40X40,而为B单位做的程序又要求大按钮的尺寸为36X36,为了系统能够灵活地适应属性变化,而无须大的改动的话。那么可以考虑采用抽象工厂模型。下面就是抽象工厂模型的示意图:

首先定义一个抽象工厂类TAbstractButtonFactory,它定义了两个虚方法CreateBigBtn()和CreateSmallBtn(),然后针对不同的单位需求,定义了两个派生类TButtonFactoryForA和TButtonFactoryForB,并且分别使用不同尺寸创建按钮。这样针对不同的需要,只要使用不同的工厂类就可以实现按钮风格的变换。下面是示意性代码:
TAbstractButtonFactory=class(TObject)
public
class function CreateBigBtn():TButton;virtual;abstract;
class function CreateSmallBtn():TButton;virtual;abstract;
end;
TButtonFactoryForA=class(TAbstractButtonFactory)
public
class function CreateBigBtn():TButton;override;
class function CreateSmallBtn():TButton;override;
end;
TButtonFactoryForB=class(TAbstractButtonFactory)
public
class function CreateBigBtn():TButton;override;
class function CreateSmallBtn():TButton;override;
end;
{ TButtonFactoryForA }
class function TButtonFactoryForA.CreateBigBtn: TButton;
begin
Result:=TButton.Create(nil);
Result.Height:=40;
Result.Width:=40;
end;
class function TButtonFactoryForA.CreateSmallBtn: TButton;
begin
Result:=TButton.Create(nil);
Result.Height:=20;
Result.Width:=20;
end;
{ TButtonFactoryForB }
class function TButtonFactoryForB.CreateBigBtn: TButton;
begin
Result:=TButton.Create(nil);
Result.Height:=36;
Result.Width:=36;
end;
class function TButtonFactoryForB.CreateSmallBtn: TButton;
begin
Result:=TButton.Create(nil);
Result.Height:=16;
Result.Width:=16;
end;