Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 父工厂内有多个工厂_Java_Design Patterns_Abstract Factory - Fatal编程技术网

Java 父工厂内有多个工厂

Java 父工厂内有多个工厂,java,design-patterns,abstract-factory,Java,Design Patterns,Abstract Factory,如下图所示,我有一个在运行时创建实体的工厂模式。当我研究我的数据库时,我决定有一个学生和一个教授是“ISA”人,因为他们有一些共同的领域(比如名字和名字) 同样地,我认为“ISA”教授也有一些忠实的副教授 在运行时,用户选择“教授”、“学生”等实体,而不是个人。所以在这种情况下,我必须创建新的教授、学生等实体。同样,当用户选择Professor实体时,它必须决定要创建哪种类型的Professor 到目前为止,我创建的工厂的代码如下 public class EntityFactory { pro

如下图所示,我有一个在运行时创建实体的工厂模式。当我研究我的数据库时,我决定有一个学生和一个教授是“ISA”人,因为他们有一些共同的领域(比如名字和名字)

同样地,我认为“ISA”教授也有一些忠实的副教授

在运行时,用户选择“教授”、“学生”等实体,而不是个人。所以在这种情况下,我必须创建新的教授、学生等实体。同样,当用户选择Professor实体时,它必须决定要创建哪种类型的Professor

到目前为止,我创建的工厂的代码如下

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();
    }
    //...
}
}

我想知道:我如何“传递”个人和教授抽象实体来创建我想要的特定实体?这样行吗?或者我需要为我设置为抽象的实体创建不同的工厂吗?在这种情况下,我如何将这些工厂与“母”工厂联系起来?

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

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

我能想到的一件事是,通过使用
enum
而不是
String
来识别
entityType
,防止工厂的用户请求这些实体类型。此
enum
仅包含实际可以创建的内容,即不是
Person
Professor

第2部分:或者我需要为我设置为抽象的实体创建不同的工厂吗?在这种情况下,我如何将这些工厂与“母”工厂联系起来

从技术上讲,您不需要创建单独的工厂,这应该取决于这些对象的创建有多复杂。如果它是复杂的,那么你应该把它分开,如果它不能被概括

可以将其拆分为多个工厂(或类似的东西)的方法是使用策略模式(),该模式使用请求的
entityType
作为上下文来选择要使用的策略--该策略可以是该特定类型的专用工厂

如果您的
Person
Professor
类型在Java意义上是真正抽象的,那么您不能实例化它们,这意味着不可能有父工厂。我想您可能可以在
Person
的构造函数中实现所有内容,或者使用某种初始化方法

希望这能让你向前迈进一步:)

更新:第一步是在创建方法中使用带有枚举值的
开关
语句


当然,您需要将用户在某个位置进入用户界面的内容映射到枚举值,但这应该很容易实现,并且您可以使用一个不允许错误类型的适当UI组件(比如一个只包含允许的内容的组合框).

在我看来,你首先不需要在这里建工厂。可以将其视为基于给定前提条件的创建策略:必须存在一个级别(可能是您的UI),用户可以在该级别明确指定他或她想要什么。因此,您所需要的只是一个
()->Entity
函数的不同实现(C版本是
Entity Create(){}
)。解决这类问题有两种常见的方法:要么是
抽象工厂
——工厂工厂工厂、高阶工厂,要么是普通的
策略
模式(这也适用于
状态
模式,其中实际状态由用户选择)


不管怎样,最终您都会得到
()->实体
签名,即使它会在代码中明确定义。似乎
Func
Func
是最紧凑但可重用和可测试的类型。尽管如此,定制
IEnityBuilder
也可以使用。

这家工厂首先有什么意义?如果我想创建一个新学生,为什么我要调用类型unsafe
Student s=(Student)factory.create(“Student”)
,而不是简单地执行
Student s=new Student()
?因为我不知道用户在运行时将选择要创建的实体。这里有很多实体,不仅仅是那两个。@VassilisDe没有回答@JBNizet的问题。首先需要
人员
类型的位置/原因?为什么需要这种抽象?如果您在
Professor
Student
中只有公共字段,那么我最好将这些字段分组到可重用的值对象中(
Address
Name
,等等),而不是盲目地抓住这个机会创建基类。@guillaume31我不确定我是否完全理解您所说的IMO.@VassilisDe;)枚举可能对我有用。如果我很理解你的意思,我必须创建一个
enum={Student,Abiding,prof,prof}
。我必须承认,我对enum了解不多…我如何更改
creatEentity()
方法以使用enum?我已经更新了我的原始帖子,因为格式在评论中不起作用:)谢谢@permforast我真的很感激
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

            // ...
        }
    }
}