@Autowired所有的东西!

最近,我写了@Autowired注释 ,它使我们可以编写更少的代码,从而使我们的生活更轻松 。 但是,使用它通常会使您的设计更加复杂。 尤其是当我们谈论在类的属性上使用它时。 它更容易违反
单一责任原则 。 这样可以更容易地注意到这一点。

可以将@Autowired与属性一起使用,但是,我认为,构造函数的存在会在问题出现时以过多的依赖关系可视化该问题。 即使没有在我们这边加倍照顾。

不断增长的代码

让我们使用文章中有关构造方法和设置方法的已知示例,但我们将对其进行一些修改。

因此,曾经有一个事件必须处理。 首先,我们必须从数据库中检索所有必需的信息,然后,我们就可以基于该信息触发适当的操作。

根据需求,我们创建了以下代码片段:

public class SomeHandler {
   @Autowired private final Repository repository;
   @Autowired private final Trigger trigger;

   public void handle(SomeEvent event) {
       // some code
   }
}

但是改变是唯一可以确定的。 客户提出了新的要求,我们不得不扩展功能。 客户希望存储所有信息,然后才能采取适当的措施。 他们还希望在发生任何紧急事件时得到通知。

经过所有更改后,我们最终得到如下结果:

public class SomeHandler {
   @Autowired private final Repository repository;
   @Autowired private final Trigger trigger;
   @Autowired private final SnapshotTaker snapshotTaker;
   @Autowired private final Notifier notifier;

   public void handle(SomeEvent event) {
       // some code
   }
}

从类的角度来看,这是编写良好的代码吗? 好吧,我相信三到四个依赖关系绝对应该给我们理由,开始考虑进行小型重新设计。

不幸的是,这并不是我在单个类的代码中见过的最多的依赖项……

@Autowired在哪里?

好的,但是@Autowired必须做什么? 解决该问题的方法是在需要时重构和重新设计代码,对吗? 我相信你们中的一些人会同意我的看法。 但是,在做出任何更改决定之前,我们必须找出问题所在。

好的,再说一次– @Autowired必须做什么? 依赖项的数量是否有问题是显而易见的吗? 好吧,在字段上使用@Autowired使它有点模糊。 当您查看上面的代码时,似乎并不会感到很痛苦。 这些只是四行代码,短行代码。 我们可能会争辩说,任何优秀的开发人员都应该知道什么时候太多了,但是为什么我们应该假设何时可以编写可以表达问题本身的代码呢?

如果所有这些依赖项都是必需的,我们可以使用构造函数来注入它们:

public class SomeHandler {
   private final Repository repository;
   private final Trigger trigger;
   private final SnapshotTaker snapshotTaker;
   private final Notifier notifier;
   
   @Autowired
   public SomeHandler(Repository repository, Trigger trigger, SnapshotTaker snapshotTaker, Notifier notifier) {
       this.repository = repository;
       this.trigger = trigger;
       this.snapshotTaker = snapshotTaker;
       this.notifier = notifier;
   }

   public void handle(SomeEvent event) {
       // some code
   }
}

现在,代码“告诉”我们一些东西。 这个长的构造函数声明看起来并不好。 我们不必考虑四个是否太多。 我们看到了。

在示例中,我们同时使用了类和方法的简称,但是在实际应用中,有时这些名称要更长一些,以便尽可能地描述:

@Autowired
public SomeHandler(EventRepository eventRepository, EventActionTrigger eventActionTrigger, EventSnapshotTaker eventSnapshotTaker, EmergencyIssueNotifier emergencyIssueNotifier) {
   this.repository = eventRepository;
   this.trigger = eventActionTrigger;
   this.snapshotTaker = eventSnapshotTaker;
   this.notifier = emergencyIssueNotifier;
}

现在问题更明显了,不是吗?

并且添加另一个依赖项只会伤害我们的眼睛(如果尚未发生):

@Autowired
public SomeHandler(EventRepository eventRepository, EventActionTrigger eventActionTrigger, EventSnapshotTaker eventSnapshotTaker, EmergencyIssueNotifier emergencyIssueNotifier, SomeAnotherDependency someAnotherDependency) {
   this.eventRepository = eventRepository;
   this.eventActionTrigger = eventActionTrigger;
   this.eventSnapshotTaker = eventSnapshotTaker;
   this.emergencyIssueNotifier = emergencyIssueNotifier;
   this.someAnotherDependency = someAnotherDependency;
}

我们需要更深入!

但是现在不要停下来。 让我们看一下扩展类时的代码:

public interface Handler {
 void handle(Event event);
}

public abstract class BasicEventHandler {
   @Autowired private final EventRepository eventRepository;
   @Autowired private final EventActionTrigger eventActionTrigger;

   // some code
}

public class SomeHandler extends BasicEventHandler implements Handler {
   @Autowired private final EventSnapshotTaker eventSnapshotTaker;
   @Autowired private final EmergencyIssueNotifier emergencyIssueNotifier;
   @Autowired private final SomeAnotherDependency someAnotherDependency;
   
   public void handle(SomeEvent event) {
       // some code
   }
}

在第一个示例中,我们可以争论声明对象依赖项的代码行数是否足够大,这使我们感到担忧。 当我们扩展一个类时,在一个特定的类中这个数字可能很好。

但是,此代码的问题甚至比前面的示例更大。

作者通常可以确定他们的解决方案是好的。 这就是我们(作者)对待正在创造的东西的方式。

但是这次,即使是代码审阅者也可能不会注意到问题。 不幸的是,并不是每个人都会看一下父类。 在检查代码时,需要付出额外的努力。 即使没有签出分支,我们仍然必须转到IDE并打开类。 也许不是很多,但请相信我,对于我们中的某些人来说,太多了​​。

如果我们同意构造函数是类的必需部分,那么就不会出现问题。

public class SomeHandler extends BasicEventHandler implements Handler {
   private final EventSnapshotTaker eventSnapshotTaker;
   private final EmergencyIssueNotifier emergencyIssueNotifier;
   private final SomeAnotherDependency someAnotherDependency;

   @Autowired
   public SomeHandler(EventRepository eventRepository, EventActionTrigger eventActionTrigger, EventSnapshotTaker eventSnapshotTaker, EmergencyIssueNotifier emergencyIssueNotifier, SomeAnotherDependency someAnotherDependency) {
      super(eventRepository, eventActionTrigger);
      this.eventSnapshotTaker = eventSnapshotTaker;
      this.emergencyIssueNotifier = emergencyIssueNotifier;
      this.someAnotherDependency = someAnotherDependency;
   } 
  
   public void handle(SomeEvent event) {
       // some code
   }
}

使其明显!

我们可以想想有多少是太多的条款协议。 我们可以尝试遵循自己的规则。 但是,总有人会挑战这一点。 谁将编写代码,并试图证明所有内容都适合并且应该在一起,但这还不是“太多”。

不要争论, 让代码说明一切!

翻译自: https://www.javacodegeeks.com/2016/03/autowired-all-the-things.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值