具有许多子类的依赖注入
Dependency injection with many subclasses
我在 Guice 中有一个 class,它使用依赖注入在构造函数中获取 ~10 个参数。
这个 class 有许多派生的 classes。
所有派生的 classes 的构造函数只是将所有参数传递给 super.
向基础 class 的构造函数添加新参数需要将此参数添加到所有派生 class.
的所有构造函数
class MyBaseClass {
@Inject
MyBaseClass(arg1,arg2,arg3, ..., argn) {
this.arg1 = arg1
....
}
}
class MyDerivedClass1 extends MyBaseClass{
@Inject
MyDerivedClass1(arg1,arg2,arg3, ..., argn) {
super(arg1,arg2,arg3, ..., argn)
}
}
class MyDerivedClass2 extends MyBaseClass{
@Inject
MyDerivedClass2(arg1,arg2,arg3, ..., argn) {
super(arg1,arg2,arg3, ..., argn)
}
}
我的一个解决方案是将所有参数包装在一个 class 中,并将 class 注入基础 class 和所有派生的 classes。这样,当向注入的 class 添加新参数时,它将被注入所有派生的 classes.
类似于:
class MyBaseClassSettings {
@Inject
MyBaseClassSettings(arg1,arg2,arg3, ..., argn) {
this.arg1 = arg1
...
}
}
class MyBaseClass {
@Inject
MyBaseClass(MyBaseClassSettings settings) {
this.settings = settings;
}
}
class MyDerivedClass1 extends MyBaseClass{
@Inject
MyDerivedClass1(MyBaseClassSettings settings) {
super(settings)
}
}
class MyDerivedClass2 extends MyBaseClass{
@Inject
MyDerivedClass2(MyBaseClassSettings settings) {
super(settings)
}
}
假设 args 彼此之间并不真正相关(一个是与数据库的连接,另一个是将线程分配给任务的助手,另一个执行部分实际逻辑,另一个持有地理信息class 的配置...(仅示例))此解决方案是否可行?
如果是的话,包装器的一个好的命名是什么 class?
是的,非常合理的解决方案和层次结构的常用习惯用法。
你的名字就可以了。另一种命名模式是 BaseParams
或 BaseClassParams
,等等
务实地说,你的解决方案是可以的。您可以通过这种方式解决您的问题,而且不会花费您很多时间。
话虽如此,如果你有时间,你应该重构代码并将 class 拆分为多个 class。
有 10 个依赖项表明您的 class 做得很多,并且被认为是代码异味(请查看 this). Your class seems to be having too many responsibilities and thus is violating the Single Responsibility Principle. Consider Aggregated Services 以了解可能解决您问题的方法。
根据您的情况,您可以选择暂时执行建议的修复,并在以后有空时进行重构。看一下Technical Debt.
的概念
至于class的名字,你推荐的就可以了。另一个建议是 MyBaseClassDependencies
.
我在 Guice 中有一个 class,它使用依赖注入在构造函数中获取 ~10 个参数。
这个 class 有许多派生的 classes。 所有派生的 classes 的构造函数只是将所有参数传递给 super.
向基础 class 的构造函数添加新参数需要将此参数添加到所有派生 class.
的所有构造函数 class MyBaseClass {
@Inject
MyBaseClass(arg1,arg2,arg3, ..., argn) {
this.arg1 = arg1
....
}
}
class MyDerivedClass1 extends MyBaseClass{
@Inject
MyDerivedClass1(arg1,arg2,arg3, ..., argn) {
super(arg1,arg2,arg3, ..., argn)
}
}
class MyDerivedClass2 extends MyBaseClass{
@Inject
MyDerivedClass2(arg1,arg2,arg3, ..., argn) {
super(arg1,arg2,arg3, ..., argn)
}
}
我的一个解决方案是将所有参数包装在一个 class 中,并将 class 注入基础 class 和所有派生的 classes。这样,当向注入的 class 添加新参数时,它将被注入所有派生的 classes.
类似于:
class MyBaseClassSettings {
@Inject
MyBaseClassSettings(arg1,arg2,arg3, ..., argn) {
this.arg1 = arg1
...
}
}
class MyBaseClass {
@Inject
MyBaseClass(MyBaseClassSettings settings) {
this.settings = settings;
}
}
class MyDerivedClass1 extends MyBaseClass{
@Inject
MyDerivedClass1(MyBaseClassSettings settings) {
super(settings)
}
}
class MyDerivedClass2 extends MyBaseClass{
@Inject
MyDerivedClass2(MyBaseClassSettings settings) {
super(settings)
}
}
假设 args 彼此之间并不真正相关(一个是与数据库的连接,另一个是将线程分配给任务的助手,另一个执行部分实际逻辑,另一个持有地理信息class 的配置...(仅示例))此解决方案是否可行?
如果是的话,包装器的一个好的命名是什么 class?
是的,非常合理的解决方案和层次结构的常用习惯用法。
你的名字就可以了。另一种命名模式是 BaseParams
或 BaseClassParams
,等等
务实地说,你的解决方案是可以的。您可以通过这种方式解决您的问题,而且不会花费您很多时间。
话虽如此,如果你有时间,你应该重构代码并将 class 拆分为多个 class。
有 10 个依赖项表明您的 class 做得很多,并且被认为是代码异味(请查看 this). Your class seems to be having too many responsibilities and thus is violating the Single Responsibility Principle. Consider Aggregated Services 以了解可能解决您问题的方法。
根据您的情况,您可以选择暂时执行建议的修复,并在以后有空时进行重构。看一下Technical Debt.
的概念至于class的名字,你推荐的就可以了。另一个建议是 MyBaseClassDependencies
.