需要关于java复杂结构的建议(DAO和服务层链接/耦合) 介绍
我正试图用Java制作一个相当复杂的结构,包括接口、抽象类和泛型。没有泛型方面的经验,只有创建良好OOP设计的一般经验,这开始证明是一个相当大的挑战 我有一种感觉,我试图做的事情实际上是做不到的,但我可以接近它。我会尽量简短地解释。我将直接告诉大家,这个结构将代表我的DAO和服务层来访问数据库。使这个问题更加抽象只会使它更加困难 我的刀层是完全好的,因为它是。有一个泛型DAO接口,对于每个实体,都有一个DAO接口,它扩展泛型DAO接口并填充泛型类型。然后是一个抽象类,它由每个DAO实现扩展,然后实现相应的接口。最可能的情况是,这里的图表显示了产品的DAO示例: 现在对于服务类,我有一个类似的想法。无论如何,服务类中的大多数方法都映射到DAO方法如果您将上图中的每个“DAO”替换为“服务”,您将获得我的服务层的基础。但是,基于以下想法,我想做一件事: 实体的每个服务类将至少访问一个DAO对象,即它所设计的实体的DAO 这是 问题 如果我能做一个适当的OO设计,使每个服务类都有一个实例变量用于各自实体的DAO对象,那么在我看来,我的服务层将是完美的如果我的设计没有看上去那么好,欢迎提供建议。 我是这样实施的: 类抽象服务需要关于java复杂结构的建议(DAO和服务层链接/耦合) 介绍,java,oop,design-patterns,generics,Java,Oop,Design Patterns,Generics,我正试图用Java制作一个相当复杂的结构,包括接口、抽象类和泛型。没有泛型方面的经验,只有创建良好OOP设计的一般经验,这开始证明是一个相当大的挑战 我有一种感觉,我试图做的事情实际上是做不到的,但我可以接近它。我会尽量简短地解释。我将直接告诉大家,这个结构将代表我的DAO和服务层来访问数据库。使这个问题更加抽象只会使它更加困难 我的刀层是完全好的,因为它是。有一个泛型DAO接口,对于每个实体,都有一个DAO接口,它扩展泛型DAO接口并填充泛型类型。然后是一个抽象类,它由每个DAO实现扩展,然后
公共抽象类抽象服务{
EntityDAO EntityDAO;
公共服务(){
entityDAO=makeEntityDAO();//编译器/IDE警告:构造函数中的可重写方法调用
}
抽象EntityDAO makeEntityDAO();
}
类ProductServiceImpl
公共类ProductServiceImpl扩展了AbstractService{
公共产品服务impl(){
超级();
}
@凌驾
ProductDAOImpl makeEntityDAO(){
返回新产品daoimpl();
}
}
这个设计的问题是我不喜欢的编译器警告:它在构造函数中有一个可重写的方法调用(参见注释)。现在它被设计成可重写的,事实上我强制它以确保每个服务类都有一个对相应DAO的引用。这是我能做的最好的事情吗
我已经尽了最大的努力,包括你可能需要的一切,并且只包括你在这个问题上需要的东西。我现在要说的是,欢迎发表评论,并提供更广泛的答案,感谢您抽出时间阅读。
有关StackOverflow的其他资源
首先需要注意的是:通常在以表示/服务/DAO等层组织的应用程序中,您有以下规则:
- 每一层只知道下面的那一层
- 它只知道它的接口,而不知道它的实现类
- 您可以轻松地进行模拟和测试,因为类唯一依赖的是接口
- 您有一个由一小部分XML文件组成的文件,这些文件描述了应用程序的整个结构,当应用程序增长时,这非常方便
- 它是一个被广泛采用的标准,并且为许多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>