我应该将方法从服务移动到自己的类,还是不行?

时间:2014-02-26 08:24:22

标签: oop design-patterns service transactions

在java项目中,我们有一个包含许多方法的胖服务类:

@Service
@Transaction
public class FatService {

   @Autowired
   private FatRepository fatRepository;

   public void doSomethingSpecial() {
      // complex logic
      fatRepository.save(foo);
      fatRepository.save(bar);
   }

   public void doSomething1() {}
   public void doSomething2() {}
   public void doSomething3() {}
   public void doSomething4() {}
   public void doSomething5() {}
   public void doSomething6() {}
   public void doSomething7() {}
   public void doSomething8() {}

}

此服务旨在为代码库中的所有类提供事务边界。它有一些数据库操作。如果我们涉及交易,我们只需要维护这个类。

但它很胖,我发现有一些方法仅用于其他一些类,例如doSomethingSpecial(),仅用于课程Special

@Component
class Special {
    @Autowired
    private FatService fatService;

    doSomething() {
        // do something first

        fatService.doSomethingSpecial();

        // do something last
    }
}

我不想将逻辑拆分为两个不同的类,因此我将doSomethingSpecial()方法从FatService移到Special

@Component
class Special {
    @Autowired
    private FatService fatService;

    doSomething() {
        // do something first

        doSomethingSpecial();

        // do something last
    }

    @Transactional
    private doSomethingSpecial() {
       // this method is move from FatService
       fatService.save(foo);
       fatService.save(bar);
    }
}

注意我仍然在方法@Transactional上保留doSomethingSpecial注释。同时向save添加FatService方法:

public void save(Object obj) {
    fatRepository.save(obj);
}

但是我的同事说我不应该把它移到Speical,因为我们必须管理两个不同类的交易,如果交易遍布所有代码库,代码很难维护。

我想知道什么是最佳解决方案?

  1. 我不希望逻辑因为事务而分裂成不同的类
  2. 我仍然希望交易管理轻松

2 个答案:

答案 0 :(得分:2)

基本上,涉及数据库的典型应用程序中的所有内容都是事务性的。因此,除非您的应用程序是一个小型玩具应用程序,否则将每个事务方法放在一个类中是不可管理的:您最终会得到一个包含数百或数千种方法的类。如果你有一个分层应用程序,那么每个服务都应该是事务性的,而且这只需要一个注释,所以没有太多要管理的。

也就是说,你的重构有一个严重的错误:尽管Special.doSomethingSpecial()方法被注释为事务性的,但它实际上并非如此,因为它是一个直接从同一个类的另一个方法调用的私有方法。因此事务性Spring拦截器无法拦截方法调用并处理事务。简而言之,@Transactional仅在Spring bean调用另一个 Spring bean时才有效。

答案 1 :(得分:0)

胖服务可能是你的业务责任分开不清楚,你应该重新思考有限的上下文,将胖服务拆分到不同的上下文并根据无处不在的语言重命名服务。不建议将方法移入特殊类,它会让服务层没有意义,就像用毒药解渴一样。