想要在java中的复杂结构上建议(DAO和服务层链接/耦合)

介绍

我试图在Java中使用接口,抽象类和generics构建一个相当复杂的结构。 由于没有仿制药的经验,只有平均创建优质OOP设计的经验,这开始certificate是一个相当大的挑战。

我有一种感觉,我正在尝试做的事情实际上无法完成,但我可以接近它。 我会尽量简短地解释一下。 我只想告诉我,这个结构将代表我的DAO和服务层来访问数据库。 使这个问题更抽象只会让它变得更加困难。

我的DAO层完全没有问题。 有一个通用的DAO接口,每个实体都有一个DAO接口,它扩展了generics接口并填充了generics类型。 然后是每个DAO实现扩展的抽象类,后者又实现相应的接口。 很可能会混淆读取,所以这里是以产品DAO为例的图表:

该图显示了Product实体的DAO实现

现在,对于服务类,我有一个类似的结构。 无论如何,服务类中的大多数方法都映射到DAO方法。 如果您使用“服务”替换上图中的每个“DAO”,您将获得我的服务层的基础。 但根据我的以下想法,有一件事我想做:

实体的每个服务类至少将访问一个DAO对象,即它所针对的实体的DAO。

哪个是……

问题/问题

如果我可以进行适当的OO设计, 使每个服务类都有一个实例变量用于各自实体的DAO对象,我认为服务层将是完美的。 对我的建议是受欢迎的,以防我的设计看起来不那么好。

我已经像这样实现了它:

类AbstractService

public abstract class AbstractService { EntityDAO entityDAO; public AbstractService() { entityDAO = makeEntityDAO(); //compiler/IDE warning: overridable method call in constructor } abstract EntityDAO makeEntityDAO(); } 

类ProductServiceImpl

 public class ProductServiceImpl extends AbstractService { public ProductServiceImpl() { super(); } @Override ProductDAOImpl makeEntityDAO() { return new ProductDAOImpl(); } } 

这个设计的问题是我不喜欢的编译器警告:它在构造函数中有一个可覆盖的方法调用 (请参阅注释)。 现在它被设计为可覆盖的,实际上我强制执行它以确保每个服务类都具有对相应DAO的引用。 这是我能做的最好的事情吗?

我尽我所能包括你可能需要的一切,只包括你对这个问题的需求。 我现在要说的是,欢迎提出意见和更多答案, 感谢您花时间阅读。

StackOverflow上的其他资源

了解服务和DAO层

DAO和服务层(JPA / Hibernate + Spring)

首先要注意一点:例如,通常在像Presentation / Service / DAO这样的层组织的应用程序中,您有以下规则:

  • 每个图层只知道下面的图层。
  • 它只通过它的接口知道它,而不是它的实现类。

这将提供更简单的测试,更好的代码封装,以及不同层的更清晰定义(通过易于识别为公共API的接口)

也就是说,有一种非常常见的方式来处理这种情况,允许最大的灵活性: dependency injection 。 而Spring是dependency injection(以及许多其他东西)的行业标准实现

这个想法(简而言之)是你的服务将知道它需要一个IEntityDAO,并且在实际使用该服务之前, 有人会注入它并实现接口。 有人被称为IOC容器( Inversion of Control容器)。 它可以是Spring ,它的作用通常由应用程序配置文件描述,并将在应用程序启动时完成。

重要提示:这个概念非常强大而且非常简单,但很简单。 您还可以使用Inversion of Control架构模式,而不需要框架,其中包含一个非常简单的实现,其中包含一个“组装”应用程序部件的大型静态方法。 但在工业环境中,最好有一个框架,允许注入其他东西,如数据库连接,Web服务存根客户端,JMS队列等…

优点:

  • 您可以轻松地进行模拟和测试,因为类唯一依赖的是接口
  • 您有一小组XML文件的单个文件,用于描述应用程序的整个结构,这在您的应用程序增长时非常方便。
  • 它是一个被广泛采用的标准,并且被许多Java开发人员所熟知。

示例java代码:

 public abstract class AbstractService { private IEntityDAO entityDAO; // you don't know the concrete implementation, maybe it's a mock for testing purpose public AbstractService() { } protected EntityDAO getEntityDAO() { // only subclasses need this method } public void setEntityDAO(IEntityDAO dao) { // IOC container will call this method this.entityDAO = dao; } } 

在spring配置文件中,你会有类似的东西:

  [...]