Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/371.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 将DTO转换为实体子类_Java_Inheritance_Design Patterns - Fatal编程技术网

Java 将DTO转换为实体子类

Java 将DTO转换为实体子类,java,inheritance,design-patterns,Java,Inheritance,Design Patterns,我目前的情况是,我有一个抽象的模型,其中许多其他模型都继承自它。API使用一个“DTO”对象,它本质上是一个大对象,包含每个子类的所有可能字段,这是因为客户端调用了服务。我已经为它创建了一个解决方案,但感觉它有一些难闻的“气味”。以下是一个设置示例: public abstract class Person { public Long id; public Long name; } public class Employee extends Person { publi

我目前的情况是,我有一个
抽象的
模型,其中许多其他模型都继承自它。API使用一个“DTO”对象,它本质上是一个大对象,包含每个子类的所有可能字段,这是因为客户端调用了服务。我已经为它创建了一个解决方案,但感觉它有一些难闻的“气味”。以下是一个设置示例:

public abstract class Person {
    public Long id;
    public Long name;
}

public class Employee extends Person {
    public Date startDate;
}

public class Student extends Person {
    public Double gpa;
}

public class PersonDTO {
    public Long id;
    public String name;
    public Date startDate;
    public Double gpa;
    public String type;
}
我想通过初始化将DTO转换为它的具体子类。通过在每个子类中创建工厂并重写方法,我已经解决了这个问题:

public class PersonFactory {

    public Person getInstance(String type) {
        if (type.equals("Student")) {
            return new Student();
        } else if (type.equals("Employee")) {
            return new Employee();
        }

        return null;
    }
}

public class Student extends Person {

    public Double gpa;

    /**
     * Initializes the additional fields in the subclass
     * from the PersonDTO.
     */
    @Override
    public void initialize(PersonDTO dto) {
        this.gpa = dto.gpa;
    }
}
因此,调用类将执行以下操作:

public Person createPerson(PersonDTO dto) {
    Person person = new PersonFactory().getInstance(dto.type);
    person.name = dto.name;
    person.id = dto.id;
    person.initialize(dto);
}
为了进一步说明这一点,模型超类(在本例中,
Person
)大约有15个字段,子类最多可以有5个或6个字段,这使得使用构造函数很麻烦。我觉得使用
initialize
方法是一种不好的做法,它将Person类与DTO类耦合(这也违反了规范)

理想情况下,我希望创建一个
Mapper
Translator
类,将DTO转换为具体的子类,但在初始化公共字段时,我一直遇到以下问题:

public class PersonMapper implements Mapper<PersonDTO, Person> {

    public Person map(PersonDTO dto) {
        if (dto.type.equals("Student")) {
            Student person = new Student();
            setupCommonFields(person, dto);   // required to call this method
            person.gpa = dto.gpa;             // inside of every block
            return person;
        } else if (dto.type.equals("Employee")) {
            Employee person = new Employee();
            setupCommonFields(person, dto);
            person.startDate = dto.startDate;
            return person;
        }
    }

    private void setupCommonFields(Person person, PersonDTO dto) {
        person.id = dto.id;
        person.name = dto.name;
    }
}
公共类PersonMapper实现映射器{
公众人物地图(PersonDTO dto){
如果(数据类型等于(“学生”)){
学生人数=新学生();
setupCommonFields(person,dto);//调用此方法需要
person.gpa=dto.gpa;//每个块的内部
返回人;
}else if(dto.type.equals(“员工”)){
员工人数=新员工();
设置公共字段(个人、dto);
person.startDate=dto.startDate;
返回人;
}
}
私有无效设置公共字段(个人、个人到dto){
person.id=dto.id;
person.name=dto.name;
}
}
这似乎是一个很容易解决的问题,但我似乎找不到最完美的解决方案。有更好的解决方案吗?

公共类PersonMapper实现了Mapper{
public class PersonMapper implements Mapper<PersonDTO, Person> {

    public Person map(PersonDTO dto) {
        Person person = createPerson(dto);
        setupCommonFields(person, dto);
        return person;
    }

    private Person createPerson(PersonDTO dto) {
        if (person.type.equals("Student")) {
            Student person = new Student();
            person.gpa = dto.gpa;
            return person;
        } else if (person.type.equals("Employee")) {
            Employee person = new Employee();
            person.startDate = dto.startDate;
            return person;
        }
    }

    private void setupCommonFields(Person person, PersonDTO dto) {
        person.id = dto.id;
        person.name = dto.name;
    }
}
公众人物地图(PersonDTO dto){ 人员=创建人员(dto); 设置公共字段(个人、dto); 返回人; } 私人createPerson(PersonDTO dto){ if(person.type.equals(“学生”)){ 学生人数=新学生(); person.gpa=dto.gpa; 返回人; }else if(person.type.equals(“Employee”)){ 员工人数=新员工(); person.startDate=dto.startDate; 返回人; } } 私有无效设置公共字段(个人、个人到dto){ person.id=dto.id; person.name=dto.name; } }
1)在您的
PersonFactory
中,您
返回未知类型的new Person()
。而
Person
是一个抽象类。这不会编译2)您可以调用
setupCommonFields(person,dto)method。你不需要在每个街区都调用它。在这种情况下,您必须消除每个块中的返回,这没关系。@NikhilPatil最后我不能调用
setupCommonFields
,因为
person
将超出范围。如果我将
person
声明移动到方法的顶部,我将不得不将其声明为
person
,从而避免设置子类上的字段,例如,
person.startDate=dto.startDate
@NikhilPatil我意识到在
map
方法的末尾有一个额外的
return person
方法是无效的,这可能促使了你的建议。Casey,看看这个临时生成的映射器实现。虽然,我不得不说我不明白你从哪里得到了
person.type.equals(“学生”)
中的
person
,但我在范围内没有看到任何这样的变量。嘿,Dragan,我注意到你在映射方面帮助了一些人。你能看看这个吗?我不知道如何解决这个问题: