如下图所示我有一个工厂模式,可以在运行时创建实体。当我在研究我的数据库时,我认为有一个学生和一个教授是“ISA”的人,因为他们有一些共同的领域(比如姓名和名字)。
同样,我决定有“ISA”教授的持久和副教授。在运行时,用户选择“教授”,“学生”等实体,而不是人。所以在这种情况下,我必须创建新的教授,学生等实体。同样,当用户选择教授实体时,它必须决定教授想要创建哪种类型。
到目前为止我创建的工厂的代码就像
public class EntityFactory {
protected String entityType;
public EntityFactory(String personType){
this.entityType = entityType;
}
public Entity createEntity(){
if(entityType.equalsIgnoreCase("Student")){
return new Student();
}
else if(entityType.equalsIgnoreCase("Professor")){
return new Professor();
}
//...
}
}
我想知道:我怎样才能“传递”Person和Professor抽象实体来创建我想要的特定实体?那可行吗?或者我是否需要为我设置为抽象的实体创建不同的工厂?我如何将这些工厂与“父母”工厂联系起来呢?
答案 0 :(得分:1)
说实话,我不确定我是否正确理解你的问题。
第1部分:您希望“传递”创建Person
或Professor
实体,因为它们是抽象的,即它们实际上并不存在于数据库中,只是用于实现基类。
我能想到的一件事是阻止工厂用户请求这些实体类型,方法是使用enum
代替String
来识别entityType
。此enum
只会包含实际可以创建的内容,即不是Person
或Professor
。
第2部分:或者我是否需要为我设置为抽象的实体创建不同的工厂?我如何将这些工厂与“父”工厂联系起来呢?
您在技术上不需要创建单独的工厂,它应该取决于这些对象的创建有多复杂。如果它很复杂,那么如果它不能被推广,你应该把它拆开。
您可以将其拆分为多个工厂(或类似的工具)的方法是使用策略模式(http://en.wikipedia.org/wiki/Strategy_pattern),该模式使用请求的entityType
作为上下文来选择要使用的策略 - - 该策略可以是针对该特定类型的专业工厂。
如果您的Person
和Professor
类型在Java意义上确实是抽象,那么您无法实例化它们,这意味着它不可能拥有父工厂。我猜你可以在Person
的构造函数中实现所有内容,或者使用某种初始化方法。
希望这可能会让你向前迈进一步:)
更新:第一步是在创建方法中使用带有枚举值的switch
语句
public enum EntityType {
STUDENT,
ABIDING_PROF,
DEPUTY_PROF
// ...
}
public class EntityFactory {
private final EntityType entityType;
public EntityFactory(EntityType entityType) {
this.entityType = entityType;
}
public Entity createEntity() {
switch (entityType) {
case STUDENT:
return new Student(); // or some more sophisticated construction logic
case DEPUTY_PROF:
return new DeputyProfessor(); // .. or something else
// ...
}
}
}
当然,您需要将用户在某个位置输入到用户界面的内容映射到枚举值,但这应该很容易实现,您可以使用不允许错误类型的适当UI组件(比方说组合框一样)只包含允许的内容。)
答案 1 :(得分:0)
对我来说,就像您不需要一样,这里首先需要工厂。根据给定的先决条件,将其视为创建策略:必须存在一个级别(可能是您的UI),在该级别中用户明确指定他或她想要的内容。因此,您所需要的只是() -> Entity
函数的不同实现(C#版本为Entity Create() {}
)。解决此问题的方法有两种,一种是AbstractFactory
-一个工厂工厂,一个高阶工厂,或者是老式的Strategy
模式(也可以与State
模式配合使用,实际状态是由用户选择的)。
无论如何,即使您在代码中明确定义了() -> Entity
签名,也最终还是可以得到。似乎Func<Entity>
或Func<Task<Entity>>
是最紧凑但可重用和可测试的类型。不过,自定义IEnitityBuilder
也可以使用。