Java 如果我想在这个场景中减少锅炉板代码,我应该使用继承吗?
我有一个Pojo类,它对应于数据库中的一个表。类Report.java有几个字段:Java 如果我想在这个场景中减少锅炉板代码,我应该使用继承吗?,java,design-patterns,Java,Design Patterns,我有一个Pojo类,它对应于数据库中的一个表。类Report.java有几个字段: class Report { public Date createDate; public String creator; public String description; public String id; } 从第一个需求开始,我需要使用id返回Report对象,以便在数据库中搜索它。响应应仅包含这4个字段。但是现在他们想要有另一个REST端点,这样就有了id,我需要在响应中返回
class Report {
public Date createDate;
public String creator;
public String description;
public String id;
}
从第一个需求开始,我需要使用id返回Report对象,以便在数据库中搜索它。响应应仅包含这4个字段。但是现在他们想要有另一个REST端点,这样就有了id,我需要在响应中返回额外的信息,比如datevaliduntil;
我正在考虑为此使用继承,例如:
class ExtendedReport extends Report {
public Date validUntil;
}
我不确定这是减少锅炉板的最佳方法,还是我应该采取另一种方法
谢谢。如果该类将1对1映射到数据库对象,并且您正在使用映射,那么最好将这两个类拆分,并利用所有继承优势
作为一般方法,我谦虚地建议将模型(映射存储库,例如关系数据库)细分为视图模型,这些模型是返回给客户机的对象。通常在应用程序的不同层之间存在对象分离,这意味着您可以拥有一个直接映射到数据库的报表对象,还可以拥有一组用于与客户机通信的不同对象。您还可以拥有第三组对象,即业务对象,它将包含与应用程序相关的逻辑。请注意,您将需要维护一个在这些对象之间转换的逻辑,可能是构建器模式或类似的东西。作为一个小例子,让我们考虑一下你的情况,你可以有:
现在使用这个简单的示例可能不太明显,但是分离对象将使以后扩展和修改应用程序更加容易。目前,您可能在所有级别上都有相同的信息,但稍后可能会发生变化,而且最好不要公开业务对象,因此,如果您在应用程序中使用报表类,例如,在API中共享它不是一个好主意。因此,我想说您可以在这里使用继承,但至少对我来说,我认为在应用程序和数据库级别使用这些相同的对象不是一个好主意。如果两个REST端点必须返回相同的报告,但暴露的信息量不同,那么您可能会发现
@JsonView
是有用的
下面是一个例子
我从«领域驱动设计»中学到的是:不要试图找到«silverbullet»模型。总是有不同的方式来表达你的概念。模型始终依赖于上下文 在这里,您的
报告
的存储方式是一种表示。
REST客户机希望读取它的方式是另一种表示。
您可以想象每个用例都有一个表示
在这种情况下,我不想为每个应用程序层之间或域范围内的上下文之间的映射编写代码
此外,我会避免继承,如有必要,我会选择一些接口,接受一些代码冗余。在OOD,特别是Java中,继承应该用来表示is-a关系。只要
ExtendedReport
是一个Report
,那么这可能是可以做到的。如果继承也为您保存了样板文件,那将是一个额外的好处。如果IS-A不合适,那么考虑授权和HAS-A,而不是继承。
public class Views {
public static class Public {
}
public static class Internal extends Public {
}
}
public class Item {
@JsonView(Views.Public.class)
public int id;
@JsonView(Views.Public.class)
public String itemName;
@JsonView(Views.Internal.class)
public String ownerName;
}
@JsonView(Views.Public.class)
@RequestMapping("/items/{id}")
public Item getItemPublic(@PathVariable int id) {
return ItemManager.getById(id);
}
@JsonView(Views.Internal.class)
@RequestMapping("/items/internal/{id}")
public Item getItemInternal(@PathVariable int id) {
return ItemManager.getById(id);
}