Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
需要关于java复杂结构的建议(DAO和服务层链接/耦合) 介绍_Java_Oop_Design Patterns_Generics - Fatal编程技术网

需要关于java复杂结构的建议(DAO和服务层链接/耦合) 介绍

需要关于java复杂结构的建议(DAO和服务层链接/耦合) 介绍,java,oop,design-patterns,generics,Java,Oop,Design Patterns,Generics,我正试图用Java制作一个相当复杂的结构,包括接口、抽象类和泛型。没有泛型方面的经验,只有创建良好OOP设计的一般经验,这开始证明是一个相当大的挑战 我有一种感觉,我试图做的事情实际上是做不到的,但我可以接近它。我会尽量简短地解释。我将直接告诉大家,这个结构将代表我的DAO和服务层来访问数据库。使这个问题更加抽象只会使它更加困难 我的刀层是完全好的,因为它是。有一个泛型DAO接口,对于每个实体,都有一个DAO接口,它扩展泛型DAO接口并填充泛型类型。然后是一个抽象类,它由每个DAO实现扩展,然后

我正试图用Java制作一个相当复杂的结构,包括接口、抽象类和泛型。没有泛型方面的经验,只有创建良好OOP设计的一般经验,这开始证明是一个相当大的挑战

我有一种感觉,我试图做的事情实际上是做不到的,但我可以接近它。我会尽量简短地解释。我将直接告诉大家,这个结构将代表我的DAO和服务层来访问数据库。使这个问题更加抽象只会使它更加困难

我的刀层是完全好的,因为它是。有一个泛型DAO接口,对于每个实体,都有一个DAO接口,它扩展泛型DAO接口并填充泛型类型。然后是一个抽象类,它由每个DAO实现扩展,然后实现相应的接口。最可能的情况是,这里的图表显示了产品的DAO示例:

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

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

这是

问题 如果我能做一个适当的OO设计,使每个服务类都有一个实例变量用于各自实体的DAO对象,那么在我看来,我的服务层将是完美的如果我的设计没有看上去那么好,欢迎提供建议。

我是这样实施的:

类抽象服务
公共抽象类抽象服务{
EntityDAO EntityDAO;
公共服务(){
entityDAO=makeEntityDAO();//编译器/IDE警告:构造函数中的可重写方法调用
}
抽象EntityDAO makeEntityDAO();
}
类ProductServiceImpl
公共类ProductServiceImpl扩展了AbstractService{
公共产品服务impl(){
超级();
}
@凌驾
ProductDAOImpl makeEntityDAO(){
返回新产品daoimpl();
}
}
这个设计的问题是我不喜欢的编译器警告:它在构造函数中有一个可重写的方法调用(参见注释)。现在它被设计成可重写的,事实上我强制它以确保每个服务类都有一个对相应DAO的引用。这是我能做的最好的事情吗

我已经尽了最大的努力,包括你可能需要的一切,并且只包括你在这个问题上需要的东西。我现在要说的是,欢迎发表评论,并提供更广泛的答案,感谢您抽出时间阅读。

有关StackOverflow的其他资源


首先需要注意的是:通常在以表示/服务/DAO等层组织的应用程序中,您有以下规则:

  • 每一层只知道下面的那一层
  • 它只知道它的接口,而不知道它的实现类
这将提供更简单的测试、更好的代码封装和更清晰的不同层定义(通过易于识别为公共API的接口)

也就是说,有一种非常常见的方法可以以一种允许最大灵活性的方式处理这种情况:。并且是依赖注入(以及许多其他东西)的行业标准实现

简而言之,您的服务将知道它需要一个IEntityDAO,在实际使用该服务之前,有人将注入它并实现接口。某人被称为IOC容器(container)。它可以是,它的功能通常由应用程序配置文件描述,并将在应用程序启动时完成

重要提示:这个概念既聪明又强大,但绝对简单愚蠢。您还可以在没有框架的情况下使用控制反转体系结构模式,该框架具有一个非常简单的实现,包括一个大型静态方法“组装”您的应用程序部件。但在工业环境中,最好有一个框架,允许注入其他东西,如数据库连接、web服务存根客户端、JMS队列等

好处:

  • 您可以轻松地进行模拟和测试,因为类唯一依赖的是接口
  • 您有一个由一小部分XML文件组成的文件,这些文件描述了应用程序的整个结构,当应用程序增长时,这非常方便
  • 它是一个被广泛采用的标准,并且为许多java开发人员所熟知
示例java代码:

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;
    }
}
公共抽象类抽象服务{
private-IEntityDAO-entityDAO;//您不知道具体的实现,可能它是一个用于测试的模拟
公共服务(){
}
受保护的EntityDAO getEntityDAO(){//只有子类需要此方法
}
public void setEntityDAO(IEntityDAO dao){//IOC容器将调用此方法
this.entityDAO=dao;
}
}
在spring配置文件中,您将有如下内容:

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

[...]

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

[...]

如果您在
AbstractService
的构造函数中实例化DAO,则不必调用可重写方法:
entityDao=(Class)((ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[0]在您的服务级别中,您可能希望
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;
    }
}
<bean id="ProductDAO" class="com.company.dao.ProductDAO" />

[...]

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