2014-08-28 135 views
0

我有一个基类。POJO中的泛型 - 这是一个很好的做法

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

说我有很多类扩展BaseDocument一个下面。

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

在某些情况下将整个文档发送到UI是没有意义的。大多数情况下,我只需要id和名称。 因此,对于每个文档,我都有一个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; 
     } 

    } 

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

编辑:假设我需要在用户界面中显示笔记,除了笔记我还需要显示创建笔记的用户名。我使用的是mongodb,当我保存该笔记时,我还将UserVO保存在笔记中,该笔记将具有用户标识和用户名称。如果我在保存笔记时仅保存用户标识,则需要在显示时再进行一次查询以获取用户名。我想避免这种情况。

+0

是的。 java反射很昂贵。你不能写工厂来创建对象吗? – Adi 2014-08-28 14:46:36

+0

我绝对不会考虑这个好做法。如果你使用反射来构建一个简单的对象,这是一个好兆头,你需要回到绘图板。不过,我认为这不太可能是性能问题,但这实际上取决于您创建这些对象的频率。对我而言,可读性是这里重要的关注点。 无论如何,VO课程的目的是什么?为什么不设计一个定义UI需求的类/接口,然后用不同的文档类型来实现它。或者,也许我误解了你。 – 2014-08-28 15:19:39

+1

@MikkelK。我编辑了答案,希望我能传达正在尝试做的事情。 – titogeo 2014-08-28 17:47:23

回答

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; 
    } 
} 
相关问题