工厂模式中又分为简单工厂模式
工厂方法模式和抽象工厂模式
这里给大家介绍的简单工厂模式是其中最简单的一种
如果大家支持的话我会继续贴出工厂方法模式和抽象工厂模式等后续篇
要看大家的反应程度哦!
学习设计模式要对面向对象的程序设计有一定的理解特别是多态性 如果能看懂下面的例子就没问题了呵呵!
//水果类它是一个抽象产品
TFruit = Class(TObject)
end;
//苹果类水果类的具体化
TApple = class(TFruit)
end;
function Factory(): TFruit;
var
f:TFruit;
begin
//精髓就是这条语句了明明创建了TApple对象
//却将他赋值给TFruit类型的变量
//其实这样做好处大大的后面就体会到了
f:=TAppleCreate();
result:=f;
end
在例程中我用到了接口 不明白得可以把它当成一个比抽象类还抽象的抽象类说白了把它当成一个类就没错 下面开始吧
这是说明
//我们用一个小果园来说明什么是简单工厂
//这个果园里有葡萄苹果和草莓三种水果
//所有的水果都有生长耕作和收获三个步骤
//果园的任务就是让我们得到葡萄苹果和草莓这三种水果对象
//我们利用得到的对象可以完成水果生长耕作和收获三个步骤
//果园就是我们所说的简单工厂(Factory)
//而葡萄苹果和草莓这三种水果就是工厂里的产品 (Pruduct)
//完成产品的过程称之为外部使用者(Produce)
//使用简单工厂的好处是
//充分利用了多态性
//不管你种什么果园返回的对象并不是具体的葡萄苹果或者草莓
//而是返回一个他们的抽象对象 水果(IFruit)
//充分利用了封装性
//内部产品发生变化时外部使用者不会受到影响
//他的缺点是
//如果增加了新的产品就必须得修改工厂(Factory)
这是定义简单工厂的单元文件源代码
//SimpleFactorypas 定义简单工厂的单元文件
//代码如下==========
unit SimpleFactory;
interface
uses
SysUtils;
type
//水果类它是一个抽象产品
//仅仅声明了所有对象共有的接口并不实现他们
IFruit = interface(IInterface)
function Grow: string; //生长
function Harvest: string; //收获
function Plant: string;//耕作
end;
//葡萄类水果类的具体化
TGrape = class(TInterfacedObject IFruit)
function Grow: string;
function Harvest: string;
function Plant: string;
end;
//苹果类水果类的具体化
TApple = class(TInterfacedObject IFruit)
function Grow: string;
function Harvest: string;
function Plant: string;
end;
//草莓类水果类的具体化
TStrawberry = class(TInterfacedObject IFruit)
function Grow: string;
function Harvest: string;
function Plant: string;
end;
//果园类它就是工厂类负责给出三种水果的实例
TFruitGardener = class(TObject)
public
//注意 class 关键字它定义工厂方法 Factory 是一个静态函数可以直接使用
//注意返回值他返回的是最抽象的产品 IFruit 水果类
//注意他有一个参数来告诉工厂创建哪一种水果
class function Factory(whichFruit:string): IFruit;
end;
//声明一个异常这不是重点
NoThisFruitException = class(Exception)
end;
implementation
{ ********** TGrape ********** }
function TGrapeGrow: string;
begin
result:=葡萄正在生长;
end;
function TGrapeHarvest: string;
begin
result:=葡萄可以收获了;
end;
function TGrapePlant: string;
begin
result:=葡萄已经种好了;
end;
{ ********** TApple ********** }
function TAppleGrow: string;
begin
result:=苹果正在生长;
end;
function TAppleHarvest: string;
begin
result:=苹果可以收获了;
end;
function TApplePlant: string;
begin
result:=苹果已经种好了;
end;
{ ********** TStrawberry ********** }
function TStrawberryGrow: string;
begin
result:=草莓正在生长;
end;
function TStrawberryHarvest: string;
begin
result:=草莓可以收获了;
end;
function TStrawberryPlant: string;
begin
result:=草莓已经种好了;
end;
{ ********** TFruitGardener ********** }
class function TFruitGardenerFactory(whichFruit:string): IFruit;
begin
//精髓就是这条语句了 result:= TAppleCreate()
//不明白赶紧去复习复习什么是多态性
if(LowerCase(whichFruit)=apple)then result:=TAppleCreate()
else if(LowerCase(whichFruit)=grape)then result:=TGrapeCreate()
else if(LowerCase(whichFruit)=strawberry)then result:=TStrawberryCreate()
else Raise NoThisFruitExceptionCreate(这种水果还没有被种植!);
end;
end
窗体界面
//MainFormpas 窗体文件这里说明怎样使用简单工厂
unit MainForm;
interface
uses
Windows Messages SysUtils Variants Classes Graphics Controls Forms
DialogsSimpleFactory StdCtrls;
type
TForm = class(TForm)
RadioButton: TRadioButton;
RadioButton: TRadioButton;
RadioButton: TRadioButton;
RadioButton: TRadioButton;
procedure RadioButtonClick(Sender: TObject);
procedure RadioButtonClick(Sender: TObject);
procedure RadioButtonClick(Sender: TObject);
procedure RadioButtonClick(Sender: TObject);
public
procedure Produce(fruitName:string);
end;
var
Form: TForm;
implementation
{ ********** TForm ********** }
//这就是生产过程
//IFruit 类型的临时变量 f 自己知道种的是哪种水果有趣吧
//想要什么尽管来种果园大丰收啦!
procedure TFormProduce(fruitName:string);
var
f: IFruit;
begin
try
f:=TFruitGardenerFactory(fruitName);
ShowMessage(fPlant());
ShowMessage(fGrow());
ShowMessage(fHarvest());
except
on e:NoThisFruitException do Messagedlg(eMessagemtInformation[mbOK]);
end;
end;
{$R *dfm}
procedure TFormRadioButtonClick(Sender: TObject);
begin
Produce(apple);
end;
procedure TFormRadioButtonClick(Sender: TObject);
begin
Produce(grape);
end;
procedure TFormRadioButtonClick(Sender: TObject);
begin
Produce(strawberry);
end;
procedure TFormRadioButtonClick(Sender: TObject);
begin
Produce(other);
end;
end
工厂模式的目的就是把创建对象的责任和使用对象的责任分开工厂负责统一创建具体产品(苹果葡萄和草莓)然后再把这些产品转化为他们的抽象产品(水果)返回给外部使用者作为使用者关心的仅仅是抽象产品预留的接口而不关心他们是怎么创建的这样即使因为某些原因导致创建产品的过程发生变化也不会影响到外部使用者在一定程度上保证了程序的可维护性
如果把具体产品类(TAppleTFrabeTStrawberry)暴露到外部如果内部的代码发生了变动外部也会受到影响工厂就失去了他的意义