我正在阅读Nick Hodges的书“ Delphi 中的依赖注入”。“注册工厂”一章考虑了这个例子:还有一个接口:
ICoffeeMaker = interface
['{73436E03-EF65-44F5-9606-F706156CBEB5}']
procedure MakeCoffee;
end;
...以及实现它的类:
type
TCoffeeMaker = class(TInterfacedObject, ICoffeeMaker)
private
FCoffeeBrand: string;
FBrewingMinutes: integer;
public
constructor Create(const aCoffeeBrand: string; const aBrewingMinutes: integer);
procedure MakeCoffee;
end;
constructor TCoffeeMaker.Create(const aCoffeeBrand: string; const aBrewingMinutes: integer);
begin
inherited Create;
FCoffeeBrand := aCoffeeBrand;
FBrewingMinutes := aBrewingMinutes;
end;
procedure TCoffeeMaker.MakeCoffee;
begin
WriteLn('Pour hot water over the ', FCoffeeBrand, ' so that it brews for ', FBrewingMinutes, ' minutes.');
end;
接下来,声明一个工厂函数以创建ICoffeeMaker的示例:
{$M+}
TCoffeeMakerFactory = reference to function(const aCoffeeBrand: string; const aBrewingMinutes: integer): ICoffeeMaker;
{$M-}
......整个过程都记录在容器中:
procedure RegisterStuff(aContainer: TContainer);
begin
aContainer.RegisterType<ICoffeeMaker, TCoffeeMaker>.AsDefault;
aContainer.RegisterFactory<TCoffeeMakerFactory>;
aContainer.Build;
end;
然后给出了主程序的代码:
var
CoffeeName: string;
BrewingMinutes: integer;
CoffeeMakerFactory: TCoffeeMakerFactory;
CoffeeMaker: ICoffeeMaker;
begin
Write('What kind of coffee do you want to make? ');
ReadLn(CoffeeName);
Write('How many minutes? ');
ReadLn(BrewingMinutes);
CoffeeMakerFactory := Container.Resolve<TCoffeeMakerFactory>();
CoffeeMaker := CoffeeMakerFactory(CoffeeName, BrewingMinutes);
CoffeeMaker.MakeCoffee;
end;
作者写道,没有必要在容器中注册TCoffeeMaker。但是突然我们会有一些TKitchen类,该类将ICoffeeMaker作为依赖项。问题是:如果真的有一个TKitchen类实现了IKitchen接口,该接口在构造函数中将ICOfeeMaker作为参数,那该怎么办呢?我将在容器中注册它:
begin
//...
aContainer.RegisterType<IKitchen, TKitchen>;
//...
end;
...然后在主程序中创建:
begin
//...
Kitchen := Container.Resolve<IKitchen>();
//...
end;
在这种情况下,如何选择所需的实现并配置创建的ICoffeeMaker示例?
1条答案
按热度按时间dsf9zpds1#
老实说,这个代码示例有点糟糕。
你不需要为不同的品牌或冲泡时间创建新的咖啡机。这些是不同的事情。品牌和冲泡时间应该是
MakeCoffee
方法的参数。如果咖啡机有一些内部部件,比如研磨咖啡豆的研磨机或类似的东西,那么它可以是一个ctor参数。如果你像这样修改代码,你的问题就消失了,因为你不需要创建新的咖啡机,只是为了用不同的冲泡时间冲泡不同品牌的咖啡。
当然,你可以有一个不同的模型,这些东西确实传递到ctor,但然后你有一个咖啡机与固定的品牌和酿造时间,你简单的“按下按钮”得到一杯咖啡,它为你做。
现在,如果你有一个厨房,有一个咖啡机,你不会创建一个新的厨房,一个新的咖啡机只是为了得到一个不同的品牌或酿造时间,你呢?是的,我比较真实的世界与软件在这里,但它表明,有些东西是不正确的与这个软件模型。