父工厂内的多个工厂

时间:2014-07-06 11:00:14

标签: java design-patterns abstract-factory

如下图所示entity factory class diagram我有一个工厂模式,可以在运行时创建实体。当我在研究我的数据库时,我认为有一个学生和一个教授是“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抽象实体来创建我想要的特定实体?那可行吗?或者我是否需要为我设置为抽象的实体创建不同的工厂?我如何将这些工厂与“父母”工厂联系起来呢?

2 个答案:

答案 0 :(得分:1)

说实话,我不确定我是否正确理解你的问题。

第1部分:您希望“传递”创建PersonProfessor实体,因为它们是抽象的,即它们实际上并不存在于数据库中,只是用于实现基类。

我能想到的一件事是阻止工厂用户请求这些实体类型,方法是使用enum代替String来识别entityType。此enum只会包含实际可以创建的内容,即不是PersonProfessor

第2部分:或者我是否需要为我设置为抽象的实体创建不同的工厂?我如何将这些工厂与“父”工厂联系起来呢?

您在技术上不需要创建单独的工厂,它应该取决于这些对象的创建有多复杂。如果它很复杂,那么如果它不能被推广,你应该把它拆开。

您可以将其拆分为多个工厂(或类似的工具)的方法是使用策略模式(http://en.wikipedia.org/wiki/Strategy_pattern),该模式使用请求的entityType作为上下文来选择要使用的策略 - - 该策略可以是针对该特定类型的专业工厂。

如果您的PersonProfessor类型在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也可以使用。