java - 如何改进这种分层架构?

标签 java spring jpa spring-data software-design

在我的工作中,我们遵循这种分层架构:http://www.oracle.com/technetwork/java/dataaccessobject-138824.html

我们有以下内容:

Maven 数据库项目

Spring Data Repositories - 运行自定义 SQL 的自定义 @Query 方法
数据库服务 - 调用存储库接口(interface)以从数据库中保存或获取 JPA 模型数据
JPA 模型 - 包含我们只有 getter 和 setter 的 Hibernate JPA 模型

Maven 通用项目

DAOs - 调用数据库服务获取数据并将其转换为DTO对象或将我们的DTO对象转换为JPA模型以传递给数据库服务进行保存
业务对象 (BO) - 包含我们的业务逻辑并调用 DAO 来保存或获取数据 (DTO)
DTO - 与 JPA 模型相同,但具有可能不在数据库中的属性

依赖Maven Common Project的项目

这些项目有不同的目的:
- 一个项目是一个内部支持工具 - 另一个是我们客户的监控工具
- 另一个是驱动业务目的的自定义引擎

问题

我对该架构的问题是,如果我想向依赖于我们 Common 项目的模块添加新功能(如 getMostRecentOrder()),我必须创建 4 种方法而不是 1 种方法。此外,我们的一个应用程序还有另一层它抽象了 Spring,因为工程师不想/不需要知道它,总共创建了 5 个方法。

有没有人遵循类似的分层架构并能够解决或找到更好的解决方案?

与我一起工作的架构师喜欢这种结构,但我开始真的不喜欢它,因为添加所有这些方法只是为了取出数据对我来说很乏味,而且看起来我只用了很多重复代码数据类型因层而发生变化。

架构师希望我们的 BO 是通用的,例如 WeatherBO 具有所有天气业务逻辑,EventBO 具有所有事件逻辑等。我的问题是我们的 BO 开始有 1000 行代码,我觉得当我们有大课时很沮丧。

谁能提供一些关于简单(3 层与我的 4 或 5 层)、可维护、灵活、可扩展等(基本上是开发人员的第一梦想哈哈)的成功 Java 分层架构的一些见解?

更新: 提供层的伪代码

存储库

public interface IOrderRepository extends JpaRepository {
       @Query("FROM Order o WHERE o.time = Max Time")
       Order getMostRecentOrder();
}

数据库服务

 public interface IOrderService extends IService<Entity ID, Entity> {
        Order getMostRecentOrder();
 }

 @Service
 @Transactional
 public final class OrderServiceImpl implements IOrderService {
      @Autowired
      private IOrderRepository repository;          

      @Override
      public Order getMostRecentOrder() {
           return repository.getMostRecentOrder();
      }
 }

 public interface IOrderDAO extends IDAO<DTO Key, DTO> {
      OrderDTO getMostRecentOrder();
 }

 @Service
 @Transactional
 public final class OrderDAOImpl implements IOrderDAO {
      @Autowired
      private IOrderService service;
      // Spring Conversion Service that uses Dozer to convert JPA model to DTO
      @Autowired
      private ConversionService conversionService;

      @Override
      public OrderDTO getMostRecentOrder() {
          Order order = service.getMostRecentOrder();
          return conversionService.convert(order, OrderDTO.class);
      }
 }

 @Service
 public final class OrderBO {
     @Autowired
     private IOrderDAO orderDAO;

     public OrderDTO getMostRecentOrder() {
        return orderDAO.getMostRecentOrder();
     }
 }

网络服务调用

 @PATH("/orders")
 @Service
 public class OrderResource {

     @Autowired
     private OrderBO orderBO;

     @GET
     @PATH("/getMostRecentOrder")
     @Produces(APPLICATION_JSON)
     public Response getMostRecentOrder() {
        Response response = Response.ok().build();
        OrderDTO orderDTO = orderBO.getMostRecentOrder();
        response.withEntity(orderDTO).build();
        return response;
     }
 }

这只是一个示例,但 BO 比我提供的示例大很多,大约有 1000 行代码或接近。另外,我担心 DAO 也会变得相当大。对于每个 DTO 和 JPA 模型,我们都有一个 DAO、服务和存储库。 BO 通常是普通 DAO 的集合,例如,OrderBO 可以有订单 DAO、发票 DAO、客户 DAO 等。

最佳答案

我不认为这里有正确或错误的答案,但我通常做的是......

我会创建一个“数据库”项目。该项目将具有所有数据库交互。

然后我将创建一个“服务”项目,该项目将包含所有业务/服务操作。这个也直接与“数据库”项目交互。该项目将暴露所有业务方法,如saveClient(Client client)、deleteClient(Client client)、updateProjects(List projects)等。

然后我创建了 N 个“客户端”项目,它们将调用接口(interface)方法与我的“服务”项目进行交互。

只是一些旁注。 1- 客户端是客户端应用程序,例如 Web 应用程序或桌面或移动应用程序。根据需要,它们都“可以/应该”与同一服务层交互。 2- 这是概念性概述。

我尽量让一切都保持标准。 然而,你的“提示”是,如果你有一个新的“客户”要求,比如“按特定顺序显示项目”,你需要 3 或 4 个新方法。是的,您将需要编写 3 或 4 个新方法,具体取决于您拥有的层数。我记得使用整个 J2EE 堆栈的项目,其中一个简单的 CRUD 操作需要来自 DAO、外观、拦截器和其他一些的 12 个类。

就个人而言,我尝试遵循 KISS principle .

关于java - 如何改进这种分层架构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22546361/

相关文章:

java - 无法使用 Spring Data Redis 持久化数据

spring - 如何通过特定主体名称删除现有 session

java - Spring 3.0 禁用@Inject注解处理

java - Java Spring 中的延迟加载异常

java - JPA OneToMany 列表始终为空

java.lang.NoSuchMethodError : javax. persistence.JoinTable.indexes()[Ljavax/persistence/Index;

java - toString 方法打印空变量,无法理解为什么(Java)

java - 在带有自定义标签的android中使用 block 模板引擎

java - 计算通过 BufferedWriter 写入文件的字节数

java - DELETE 查询未从数据库表中删除