POJO中的泛型 - 这是一个很好的做法

时间:2014-08-28 14:41:39

标签: java generics reflection

我有一个基类。

@Data
class BaseDocument{
    String id;
    String name;
    //Other fields
}

假设我有很多类扩展了下面的BaseDocument。

class NoteDocument extends BaseDocument{
    String description;
    Long lastModifiedDate;
    //etc
}

在某些情况下,将整个文档发送到UI是没有意义的。大多数情况我只需要id和name。 因此,对于每个文档,我都有一个VO类。

@Data
class BaseVO {
    private String id;
    private String name;
}

@Data
class NoteVO extends BaseVO{
    //Nothing here now

}

在NoteDocument中我有。

public NoteVO getVo(){
        Assert.notNull(getId());
        NoteVO noteVo = new NoteVO();
        noteVo.setName(getName());
        noteVo.setId(getId());
        return noteVo;
    }

现在我必须在扩展BaseDocument的所有类中复制此方法。

相反,我改变了我的BaseDocument,如下所示。

    @Data
    class BaseDocument<V extends BaseVO>{
        String id;
        String name;

        public V getVo(Class className)  {
            Assert.notNull(getId());
            V vo = null;
            try {
                vo = (V) className.newInstance();
                vo.setName(getName());
                vo.setId(getId());
            } catch (IllegalAccessException|InstantiationException e){
                e.printStackTrace();
            }
            Assert.notNull(vo);
            return vo;
        }

    }

我是仿制药的新手。我的第一个问题是,这是一个很好的做法。使用反射创建实例,任何性能问题都有问题吗?有没有更好的方法来实现(编写更少的代码)。

编辑:假设我需要在UI中显示注释,同时注意我需要显示创建注释的用户的名称。我正在使用mongodb,当我保存笔记时,我还将NoteV中的UserVO保存,其中包含用户ID和用户名。如果我在保存笔记时仅保存用户ID,我将不得不再进行一次查询以在显示时获取用户名。我想避免这种情况。

1 个答案:

答案 0 :(得分:0)

不要使用反射;使用继承和可能的协变返回类型。它将更快,更清晰,更精确,更易于维护。您可能还会发现添加方法以逐步填充VO很有用。我没有想出一个干净的方法来应用泛型这种情况,但我认为你不需要它们:

class BaseVO {
    String id;
    String name;

    void setId(String id) {
        this.id = id;
    }

    void setName(String name) {
        this.name = name;
    }
}

class NoteVO extends BaseVO {
    // ...
}

@Data
class BaseDocument {
    String id;
    String name;
    //Other fields

    protected void populateBaseVO(BaseVO vo) {
        vo.setId(id);
        vo.setName(name);
    }

    public BaseVO getVO() {
        BaseVO vo = new BaseVO();

        populateBaseVO(vo);
        return vo;
    }
}

@Data
class NoteDocument extends BaseDocument {
    String description;
    Long lastModifiedDate;
    // ....

    protected void populateNoteVO(NoteVO vo) {
        populateBaseVO(vo);
        // ...
    }

    public NoteVO getVO() {
        NoteVO vo = new NoteVO();

        populateNoteVO(vo);
        return vo;
    }
}