gpt4 book ai didi

hibernate - 通用 DAO 模式实现设计

转载 作者:行者123 更新时间:2023-12-04 11:26:53 25 4
gpt4 key购买 nike

我正在做一个 GWT+Hibernate 项目。它由各种模块组成,我将在其中命名两个 - 公司和登录。对于每个模块,我都创建了一个 RPC 服务,这样项目就不会以一个可以完成所有工作的神一样的服务而告终。

为了与数据库交互,我使用 Hibernate API——具体来说,是 POJO 中的 EntityManager 和 Annotations。

另外,我创建了一个通用 DAO 类来处理基本的 CRUD 操作。 GenericDAO 类也将处理 EntityManager。
每个模块服务类都将扩展这个 GenericDAO,以便它可以添加自己的查询方法。

以下是 GenericDAO 类的 stub -

public class GenericDataAccessService<EntityType, PrimaryKeyType extends Serializable> {

// Constructor

@Override
public void save(EntityType newEntity) {
// TODO Auto-generated method stub
}

@Override
public void update(EntityType entity) {
// TODO Auto-generated method stub

}

@Override
public EntityType find(PrimaryKeyType primaryKey) {
// TODO Auto-generated method stub
return null;
}

@Override
public List<EntityType> findByProperty(String property) {
// TODO Auto-generated method stub
return null;
}

@Override
public List<EntityType> findAll() {
// TODO Auto-generated method stub
return null;
}

@Override
public void delete(PrimaryKeyType primaryKey) {
// TODO Auto-generated method stub

}

@Override
public void delete(EntityType entity) {
// TODO Auto-generated method stub

}
}

现在,假设我想要公司模块的另一种查找方法。所以,我写了我的 CompanyService 类 -
public class CompanyService extends GenericDataAccessService<Company, int> {

public void addCompany(Company company) {
super.save(company);
}

public Company updateCompany(Company company) {
return super.update(company);
}

public List<Company> findMatchingCompanies(String companyName) {
return super.findByProperty(companyName);
}

public void deleteCompany (int companyId) {
super.delete(companyId);
}

public List<Company> findThroughSomeCustomSearch() {
// custom query code.
}
}

其他模块也遵循类似的脚步。这样,我也可以为每个模块的服务添加非数据访问相关的方法。

现在,我需要在客户端公开这些模块。我选择不以任何方式公开 GenericDAO 类;所以没有接口(interface)。相反,我为每个模块创建一个接口(interface)。

因此,对于 CompanyService,它是 -
public interface CompanyService {

public void addCompany(Company company);

public Company updateCompany(Company company);

public List<Company> findMatchingCompanies(String companyName);

public void deleteCompany (int companyId);

public List<Company> findThroughSomeCustomSearch();
}

其他模块的接口(interface)也是如此。

这是一个好的设计吗? GenericDAO 确实保存了一些 session 管理和基本 CRUD 操作的样板代码。但是,由于 Hibernate API,每个方法的代码已经减少到 3-4 行。在这种情况下,我没有发现 GenericDAO 的任何其他用途。还是我以错误的方式实现它?

请提出比这更好的方法,以防这种设计不够好。

编辑:
我想知道在这种情况下你会给服务模块起什么名字。我现在正在使用“Impl”后缀,但感觉就像卡在我的喉咙里。
例如,对于公司模块,
接口(interface) - CompanyService
类 - CompanyServiceImpl

更好的建议?

最佳答案

我认为你可以做几件事来改善这一点:

联轴器 :

大多数时候,组合比继承更可取。由于这种关系,您的服务是强耦合的。我打算改变它,改用组合如下:

public class CompanyService  {
private GenericDataAccessService<Company, int> dao; // interface

public void addCompany(Company company) {
dao.save(company);
}
....
}

为了打破依赖关系,dao 字段应该是一个抽象类或接口(interface)(我既不知道您的代码也不知道您的需求也不知道 java)以允许您注入(inject)它。

可测试性 :

注入(inject)这些类的依赖项还可以帮助您轻松地测试代码并注入(inject)模拟实例。

不需要的操作 :

使用继承会强制您执行您可能不想允许的操作。例如,假设您有一个 AuditingDataService,如下所示:
public class AuditingService extends GenericDataAccessService<Audit, int> 

如果这样做,您的 AuditingService 将继承 删除方法!!!你能像我一样感受到那种强烈的气味吗?它将把你带到以下点。

反模式

在前面的示例中(用于审核日志条目的删除方法),您将被迫使用无所事事或抛出异常方法来覆盖它,以防止有人使用它……嗯……嗯……嗯……那可以吗?好的设计?

结论 :

我认为不是,仅仅是因为继承在这里不太适合。

暂时忘记 LoC,专注于改变设计。

更新 :

Java 有自己的命名约定,如果 Impl 是一个糟糕的后缀,它是每个 Java 程序员都理解和共享的约定之一。所以,我觉得没问题。

关于hibernate - 通用 DAO 模式实现设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14537049/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com