我想弄清楚如何在XE2中编写通用工厂。让我说我有这个:
Locale locale = new Locale(AppConfig.Language);
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = "ar";
getBaseContext().getResources().updateConfiguration(config,
getBaseContext().getResources().getDisplayMetrics());
setContentView(R.layout.activity_main);
类:
type
TObjectTypes = (otLogger, otEmail);
type
TLoggerTypes = (lFile, lConsole, lDatabase);
type
TEmailTypes = (etPOP3, etSMTP);
等
现在我这样做是为了遍历所有TObjectTypes:
TSMTPEmail = class(TInterfacedObject, IEmail); // Supports emailing only
TPOP3Email = class(TInterfacedObject, IEmail); // Supports emailing only
TFileLogger = class(TInterfacedObject, ILogger); // Supports logging only
所以,我需要一个通用工厂,并且能够通过所有TObjectTypes循环,但是通过所有TLoggerTypes或通过所有TEmailTypes循环,并跳过创建一些例如l来自TLoggerTypes的数据库或来自TEmailTypes的etPOP3。
工厂应该生产各种类。
答案 0 :(得分:4)
在Delphi中,由于元类(类引用),制作工厂非常简单,其简单示例为TClass
:
TClass = class of TObject
在大多数情况下,您应该为所有工厂成员和元类定义自己的抽象类:
TMyFactoryObject = class (TObject)
public
constructor FactoryCreate(aConfiguration: TConfiguration); virtual; abstract;
end;
TMyFactoryClass = class of TMyFactoryObject;
在这个抽象类中,你可以为所有后代添加一些常用的方法,在我的例子中,我们有构造函数,它将配置作为参数。如何应对它将在后代中确定。
然后你声明后代类:
TMyLogger = class (TMyFactoryObject, ILogger)
private
...
public
constructor FactoryCreate(aConfiguration: TConfiguration); override;
... //implementation of ILogger interface etc
end;
TMyEmail = class (TMyFactoryObject, IEmail)
private
...
public
constructor FactoryCreate(aConfiguration: TConfiguration); override;
... //implementation of IEmail interface etc
end;
现在你声明了可能的后代类数组:
var
MyFactory: array [otLogger..otEmail] of TMyFactoryClass;
并在初始化部分或其他地方填充此数组:
MyFactory[otLogger]:=TMyLogger;
MyFactory[orEmail]:=TMyEmail;
最后,您问题的TTheFactory.Make(_ObjectType, _Configuration);
可以替换为:
MyFactory[_ObjectType].FactoryCreate(_Configuration);
并且您将获得所需的对象作为MyFactoryObject类型的实例。
有关详细信息,请参阅http://docwiki.embarcadero.com/RADStudio/Seattle/en/Class_References。