为啥使用框架的功能被认为是错误的
Posted
技术标签:
【中文标题】为啥使用框架的功能被认为是错误的【英文标题】:Why is using the framework's features considered wrong为什么使用框架的功能被认为是错误的 【发布时间】:2022-01-08 09:39:35 【问题描述】:我作为初级开发人员加入了一家公司,并被分配对各种应用程序进行维护和修复。
在我必须在一个团队中工作的每个项目中,我总是听到有人抱怨我的代码过于“框架耦合”,我应该使用纯 Java 编写代码而不是使用 Spring 框架的功能(哎呀,我什至得到了因使用@Autowired 而不是构造函数注入而大喊大叫)
我对这件事感到非常沮丧,我想知道我是否错了。框架的特性难道不是程序员使用该框架的主要原因吗?
【问题讨论】:
我推荐阅读 Bob 大叔的书“The Clean Code”。 ---无论错误多么严重,我们都不应该互相吼叫。我建议寻找一个开放的对话。 a) 承认我们不理解某事并 b) 在我们不理解某事时寻求解释,这绝不是一件坏事。 然后阅读他的“Clean Coder” :) 说真的,阅读这两本书很有启发性:) @late1 好吧...坚持你的立场。明确说明您被聘为初级开发人员。我们公司(我认为大多数其他公司)的政策是,初级人员需要支持和指导。但是,如果您的雇主不愿意投入必要的时间,请做好被解雇的准备。但是话又说回来……这真的是您想继续为之工作的雇主吗?这些是只有您可以回答的问题(请不要在这里回答 - 自己回答并采取相应的行动)。 @Turing85 猜我得先读一下那本书,然后再做一些改变:) 我猜你用@Autowired
注释了私有字段。不应该这样做的明显原因是,如果不使用奇怪的 hack,该类现在是不可测试的。类的消费者看不到这个类依赖其他东西等等。Oliver Drotbohm(Spring Data的作者)很久以前写过关于字段注入相关的问题odrotbohm.de/2013/11/why-field-injection-is-evil
【参考方案1】:
请不要混淆两个不同的概念:“特定项目的条件标准”和“最佳实践” - 如果您是初级开发人员,您只需要接受条件标准,如果您是团队负责人,则应仔细评估“最佳实践”是否实际上是最好的。如果您的团队决定不与Spring Framework 这意味着他们缺少很多特性(或需要从头开始实现这些特性),以便假设将来切换 DI 框架的可能性。
关于“字段注入”的邪恶,问题在于“构造函数注入”的布道者完全忽略了很多情况下它根本不起作用的事实,例如考虑以下代码:
@Component
@RequiredArgsConstructor
class A
private final B b;
@Component
@RequiredArgsConstructor
class B
private final A a;
由于循环依赖,DI 框架将无法引导这些 bean,您可以通过以下选项使其工作:
不要使用构造函数注入 将“某处”@Lazy 注释(或创建您自己的代理以避开 Spring)。放在哪里?实际上在这两个类中,因为行为取决于依赖解析的根:如果我们以A
开头,那么B
需要是@Lazy,反之亦然。但问题是这种解决方法只是将问题从引导阶段转移到运行时
接受您的代码异味并对其进行重构,但请始终牢记引导阶段可能随时失败,即执行 DI 框架应该完成的工作
【讨论】:
【参考方案2】:通常,这种思维方式背后的原因是,用最少的工作量将您今天使用的框架换成其他框架会更容易。您可能会争辩说这不是很常见的事情,或者您经常这样做,但是,即使原因并不能说服您,尝试尽可能多地将您的代码与底层框架解耦通常是一个好习惯多种原因(除了刚才提到的原因,您还让单元测试变得更容易)。
关于@Autowired
主题,构造函数注入通常是首选,主要有两个原因:
-
您清楚地定义了您的类正常工作的依赖关系;
对它进行单元测试会更容易,因为如果您可以通过构造函数“注入”它们,那么模拟它的依赖关系会更容易。
【讨论】:
如果使用 Constructor Injection 能带来如此大的不同,那我就用它让大家开心。感谢您的回答以及有关构造函数注入的好处的其他信息。 不客气。不幸的是,在您的工作环境中,支持和指导似乎并不是您必须自己完成的事情。尝试之前 cmets 中提到的书籍,对于 Spring 主题,请尝试 manning.com/books/spring-in-action-sixth-edition ;) 祝你好运!以上是关于为啥使用框架的功能被认为是错误的的主要内容,如果未能解决你的问题,请参考以下文章
为啥循环条件内的 iostream::eof 被认为是错误的(即 `while (!stream.eof())`)?