我应该如何填充我的对象?

时间:2015-12-13 16:10:41

标签: java oop object paradigms

我有一个想要填充信息的对象。我从许多不同的服务中检索信息。我创建了一个有一个公共方法的辅助类,然后有许多私有方法来完成调用服务的工作。我写的工作得很好但是我不确定这是否是正确的方式。

您可能想知道为什么我需要一个包含所有这些信息的对象。我需要在一个对象中使用它,因为我从这个java对象创建一个json对象并将其传递给javascript层。

我的方法有什么问题,我应该遵循这样的编程范式来做这样的事情吗?

示例:

人物对象,包含firstName,lastName,年龄,身高,体重,喜爱食物列表,收藏国家列表,评论列表的getter和setter。

  • 服务1给出firstName,lastName,年龄,身高和体重
  • 服务2 列出最喜欢的国家和最喜欢的食物清单
  • 服务 3列出了该人的评论

我有一个personH​​elper类,看起来像这样:

public class PersonHelper{

public Person getPerson(userDetails){
    Person person = new Person();
    this.setPersonDetails(person, userDetails);
    this.setFavourites(person, userDetails);
    this.setComments(person, userDetails);

    return person;
}

private Person setPersonalDetails(Person person, UserDetails userDetails){

    returnedObj = callToService1(userDetails);
    person.setFirstName(returnedObj.getFirstName());
    person.setLastName(returnedObj.getLastName());
    person.setAge(returnedObj.getAge());
    person.setHeight(returnedObj.getHeight();
    person.setWeight(returnedObj.getWeight());

    return person;
}

private Person setFavourites(Person person, UserDetails userDetails){

    <List>favsList = callToService2(userDetails);
    person.setFavourites(returnedObj.getFavs(favsList));

    return person;
}

private Person setComments(Person person, UserDetails userDetails){

    <List>commentsList = callToService3(userDetails);
    person.setComments(returnedObj.getComments(commentsList));

    return person;
}

}

然后在我的控制器中我打电话

person = personHelper.getPerson(userDetails);
jsonResponse = jsonProcessor.writeAsString(person);

return jsonResponse; // returns the ajax response to js

提前感谢您的任何帮助或建议。

编辑:经过更多的研究后,我发现我填充的对象被称为数据传输对象,我使用Java Bean方法填充它。

2 个答案:

答案 0 :(得分:2)

现在有一种趋势是限制对象的可变性,因此基于setter的方法虽然可行但有时不被视为创建对象的最佳方式,甚至是数据传输类型的对象。另一件需要考虑的事情是,有多少对象了解彼此以及他们知道多少 - 看来你的PersonH​​elper类几乎需要了解UserDetails和Person的所有内容。因此,如果向Person添加一个字段,则需要将其添加到UserDetails,并添加到PersonH​​elper以填充该字段。

对于您的对象类型,您可能会发现Builder模式很有用。构建器是一种短期瞬态对象,旨在收集构造数据。通常,构建器将具有流畅的API,并传递给传输类的(私有)构造函数。这意味着负责构建对象的所有代码都清楚,这是它的责任,因为它适用于Builder。同时,构造的传输对象实际上是不可变的,并且更容易推理代码的线程安全性并理解可能在不同部分具有的值。

public class Person {
    private final String firstName;
    private final String lastName;

    private Person(final PersonBuilder builder) {
        this.firstName = builder.firstName;
        this.lastName = builder.lastName;
    }
    ... usual getters etc ...

    public static class PersonBuilder {
        private String firstName;
        private String lastName;

        private PersonBuilder() {
        }

        public PersonBuilder withFirstName(final String name) {
            this.firstName = name;
            return this;
        }

        public PersonBuilder withLastName(final String name) {
            this.lastName = name;
            return this;
        }

        public Person build() {
            return new Person(this);
        }
    }

    public static PersonBuilder newPerson() {
        return new PersonBuilder();
    }
}

在这个示例中,构建器有点过于繁琐,但是当您有二十或三十个不同的数据时,这些数据在某种程度上是可选的,它可以有意义并且使得构造代码非常容易阅读......

Person.newPerson().withFirstName("Sam").withLastName("Spade").build()

在我看来,您的用户详情&#39;对象可以变成一种构造者。所以你的'PersonH​​elper&#39; class最终只是调用userDetails.build(),而不是知道Person对象(和userDetails对象)包含哪些字段。

答案 1 :(得分:1)

您的问题没有一般范例,但这里有一些设计提示:

  1. 您的个人数据(名称,收藏夹)似乎分布在多个数据存储中,您必须在PersonH​​elper类中进行全部操作。我不知道这些服务是否在其他地方使用,但从控制器的角度来看,这个帮助器也应该是一项服务。

  2. 由于您的服务调用是独立的,您可以并行执行

  3. 对于某些类型的应用程序,如果您为UI级别公开这些服务,则会更好。例如,如果数据呈现在不同的UI块中,则客户端可以在收到响应后立即发出多个异步请求并显示数据。