建议希望在一个复杂的结构中使用java(DAO和服务层链接/耦合) [英] Advice wanted on a complex structure in java (DAO and Service Layer linking/coupling)

查看:124
本文介绍了建议希望在一个复杂的结构中使用java(DAO和服务层链接/耦合)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

简介



我试图用Java中的接口,抽象类和泛型构造一个相当复杂的结构。没有经验的泛型和只有平均的经验创造良好的OOP设计,这开始是一个很大的挑战。



我有一些感觉,我正在尝试实际上不能做,但我可以接近它。我会尽可能简短的解释一下。我只是直接告诉我,这个结构将代表我的DAO和服务层来访问数据库。使这个问题更抽象只会使它更加困难。



我的DAO图层是完全正常的。有一个通用的DAO接口,对于每个实体,有一个扩展通用DAO接口的DAO接口,并填充通用类型。那么有一个抽象类,它被每个DAO实现扩展,反过来实现对应的接口。令人困惑的阅读很可能,所以这里显示了产品DAO的图表:





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


实体的每个服务类将至少访问一个DAO对象,即其设计的实体的DAO。 / p>

哪个是...



问题/问题



如果我可以使一个正确的OO设计来使每个服务类都有一个实例变量用于其各自实体的DAO对象,我的服务层将是完美的,在我看来。



我已经实现了这样:

>

类AbstractService



  public abstract class AbstractService< EntityDAO> {

EntityDAO entityDAO;

public AbstractService(){
entityDAO = makeEntityDAO(); //编译器/ IDE警告:构造函数中的覆盖方法调用
}

abstract EntityDAO makeEntityDAO();
}



Class ProductServiceImpl



  public class ProductServiceImpl extends AbstractService< ProductDAOImpl> {

public ProductServiceImpl(){
super();
}

@Override
ProductDAOImpl makeEntityDAO(){
返回新的ProductDAOImpl();
}
}

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



我已尽全力尽可能地包括您可能需要的所有内容,而且只需要您对此问题的需求。所有我现在要说的是,欢迎评论和更广泛的答案,感谢您抽出时间阅读。



其他资源StackOverflow



了解服务和DAO图层



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

解决方案

只是一个小笔记:通常在一个应用程序中组织起来,例如Presentation / Service / DAO,你有以下规则: p>


  • 每个层只知道下面的层。

  • 它只通过它的界面知道,而不是通过它的实现类。



这将提供更简单的测试,更好的代码封装和更清晰的不同层定义(通过接口这很容易被识别为公众API)



这就是说,有一种非常常见的方式来处理这种情况,使得最大的灵活性:依赖注入 Spring 是依赖注入的行业标准实施(以及许多其他功能)



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



重要提示: 这个概念是辉煌而强大的,但是死的简单愚蠢。您还可以使用反转控制架构模式,而不需要一个非常简单的实现框架,其中包含一个大型静态方法组装您的应用程序部件。但是在一个工业环境中,最好有一个框架可以注入数据库连接,Web服务存根客户端,JMS队列等等。






  • 你有一个轻松的时间嘲笑和测试,因为唯一的一个类依赖的是接口

  • 您有一个XML文件的单个文件描述您的应用程序的整个结构,这在您的应用程序增长时非常方便。

  • 这是一个非常广泛采用的标准由许多java开发人员所熟知。



示例java代码:

  public abstract class AbstractService< IEntityDAO> {

private IEntityDAO entityDAO; //你不知道具体的实现,也许这是一个测试目的的模拟

public AbstractService(){
}

protected EntityDAO getEntityDAO(){ //只有子类需要这个方法
}

public void setEntityDAO(IEntityDAO dao){// IOC容器将调用此方法
this.entityDAO = dao;
}
}

在spring配置文件中,你会有一些that:

 < bean id =ProductDAOclass =com.company.dao.ProductDAO/> 

[...]

< bean id =ProductServiceclass =com.company.service.ProductService>
< property name =entityDAOref =ProductDAO/>
< / bean>


Introduction

I am trying to make a rather complex structure in Java with interfaces, abstract classes and generics. Having no experience with generics and only average experience with creating good OOP designs, this is beginning to prove quite a challenge.

I have some feeling that what I'm trying to do cannot actually be done, but that I could come close enough to it. I'll try to explain it as brief as I can. I'm just going to tell straight away that this structure will represent my DAO and service layers to access the database. Making this question more abstract would only make it more difficult.

My DAO layer is completely fine as it is. There is a generic DAO interface and for each entity, there is a DAO interface that extends the generic one and fills in the generic types. Then there's an abstract class that is extended by each DAO implementation, which in turn implement the corresponding interface. Confusing read for most probably, so here's the diagram showing the DAO for Products as an example:

Now for the service classes, I had a similar construction in mind. Most of the methods in a service class map to the DAO methods anyway. If you replace every "DAO" in the diagram above with "Service", you get the basis for my service layer. But there is one thing that I want to do, based on the following idea I have:

Every service class for an entity will at least access one DAO object, namely the DAO of the entity that it is designed for.

Which is...

The question/problem

If I could make a proper OO design to make each service class have one instance variable for the DAO object of their respective entity my service layer would be perfect, in my view. Advice on this is welcome, in case my design is not so good as it seemed.

I have implemented it like this:

Class AbstractService

public abstract class AbstractService<EntityDAO> {

    EntityDAO entityDAO;

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

    abstract EntityDAO makeEntityDAO();
}

Class ProductServiceImpl

public class ProductServiceImpl extends AbstractService<ProductDAOImpl> {

    public ProductServiceImpl() {
        super();
    }

    @Override
    ProductDAOImpl makeEntityDAO() {
        return new ProductDAOImpl();
    }
}

The problem with this design is a compiler warning I don't like: it has an overridable method call in the constructor (see the comment). Now it is designed to be overridable, in fact I enforce it to make sure that each service class has a reference to the corresponding DAO. Is this the best thing I can do?

I have done my absolute best to include everything you might need and only what you need for this question. All I have to say now is, comments are welcome and extensive answers even more, thanks for taking your time to read.

Additional resources on StackOverflow

Understanding Service and DAO layers

DAO and Service layers (JPA/Hibernate + Spring)

解决方案

Just a little note first: usually in an application organized in layers like Presentation / Service / DAO for example, you have the following rules:

  • Each layer knows only the layer immediately below.
  • It knows it only by it's interfaces, and not by it's implementation class.

This will provide easier testing, a better code encapsulation, and a sharper definition of the different layers (through interfaces that are easily identified as public API)

That said, there is a very common way to handle that kind of situation in a way that allow the most flexibility: dependency injection. And Spring is the industry standard implementation of dependency injection (and of a lot of other things)

The idea (in short) is that your service will know that it needs a IEntityDAO, and that someone will inject in it and implementation of the interface before actually using the service. That someone is called an IOC container (Inversion of Control container). It can be Spring, and what it does is usually described by an application configuration file and will be done at application startup.

Important Note: The concept is brilliant and powerful but dead simple stupid. You can also use the Inversion of Control architectural pattern without a framework with a very simple implementation consisting in a large static method "assembling" your application parts. But in an industrial context it's better to have a framework which will allow to inject other things like database connection, web service stub clients, JMS queues, etc...

Benefits:

  • Your have an easy time mocking and testing, as the only thing a class depends on is interfaces
  • You have a single file of a small set of XML files that describe the whole structure of your application, which is really handy when your application grows.
  • It's a very widely adopted standard and well - known by many java developers.

Sample java code:

public abstract class AbstractService<IEntityDAO> {

    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;
    }
}

And in spring configuration file, you will have something like that:

<bean id="ProductDAO" class="com.company.dao.ProductDAO" />

[...]

<bean id="ProductService" class="com.company.service.ProductService">
    <property name="entityDAO" ref="ProductDAO"/>
</bean>

这篇关于建议希望在一个复杂的结构中使用java(DAO和服务层链接/耦合)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆