我目前正在开发一个开源项目,要求我重构很多旧代码,并利用hibernate进行数据库访问。春天将它们捆绑在一起。现在的代码使用了“上帝”对象,其中数据库查询,业务逻辑,数据库行和数据库。所有getter和setter都实现在一个对象中。
我想要做的是将这些对象重构为以下层:
到目前为止一直很好,但现在有一个要求,我不希望最终用户使用任何DO getter& setter方法。所以我让它们受到包保护,并将getter和setter添加到我的管理层。 管理类getter / setter将添加业务逻辑方面的东西,然后调用DO的setter / getters。
所以我现在有这样的东西(所有管理/ DAO类都有接口,但为了简单起见,我把它们排除了):
public class PersonManager{
@Autowired(required = true)
protected PersonDAO personDAO;
public List<PersonDO> findAll(){
return personDAO.findAll();
}
public void setPersonName(PersonDO person, String name)
{
...Business logic authentication checks...
person.setName(name);
}
}
此方法再次运行良好,但现在每次开发人员想要使用后端时,管理对象都需要与数据库对象一起使用。由于这是一个开源项目,我担心只要将DO方法公之于众,诱惑就可能有点太大了。跳过管理器(并再次向DO添加业务逻辑代码)。
所以我现在想到的是创建一个额外的层,将管理器和DO封装到一个对象中,如下所示:
public class Person()
{
protected PersonManager personManager;
protected PersonDO personDO;
public List<Person> findAll(){
return personManager.findAll();
}
public void setPersonName(String name)
{
...Business logic authentication checks...
person.setName(name);
}
}
这会将后端封装到过去存在的旧“上帝对象”中,但其好处是完全空洞的,只需要调用“分层后端API”。所以其他开源贡献者仍然可以在后端被清理的同时使用旧代码。
但是我的设置中存在一个小问题,那就是当我们真正想要Person对象时,“findAll()”方法会返回一个“PersonDO”对象列表! (这是因为这是hibernate返回我的对象的方式) 所以我对如何最好地解决这个问题感到失望。
除了将经理用于一切之外,没有别的办法吗?或者我错过了一些其他方式我可以封装经理&amp; DO成为一个对象。
答案 0 :(得分:1)
在这种情况下常用的模式是值对象(VO)和服务类的分离。服务类的各个公共方法通常遵循事务脚本模式。有人称这种方法为“贫血对象模型”,但为了更好或更值得,它似乎非常适合现代测试方法(TDD,模拟等)以及依赖注入和数据库事务管理。
如果您遵循此项目,您将返回API,可以安全地使用上游的简单VO。数据库事务边界应该处于各个API方法的级别,因此从API调用返回的VO将与数据库断开连接,并且对其值的更改将不会使其返回到数据库,除非将VO传递回API为此目的明确设计的方法。