【问题标题】:Dependency injection with many subclasses具有许多子类的依赖注入
【发布时间】:2016-01-02 22:34:05
【问题描述】:

我在 Guice 中有一个类,它使用依赖注入在构造函数中获取 ~10 个参数。

这个类有很多派生类。 所有派生类的构造函数只是将所有参数传递给super。

向基类的构造函数添加新参数需要将此参数添加到所有派生类的所有构造函数。

    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 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 彼此并不真正相关(一个是与数据库的连接,另一个是为任务分配线程的助手,另一个负责部分实际逻辑,另一个负责地理配置班级...(只是示例))这个解决方案是否可以考虑?

如果是这样,包装类的好命名是什么?

【问题讨论】:

  • 虽然这种方法没问题,但您应该检查所有这些 args 参数是否没有任何共同点......也许您发现您可以派生“数据库设置”而不是“设置”, “用户设置”,...并使用多个有意义的包装器。

标签: java inheritance constructor dependency-injection guice


【解决方案1】:

务实地说,您的解决方案是可以的。您可以通过这种方式解决您的问题,而且不会花费您很多时间。

话虽如此,如果你有时间,你可能应该重构代码并将类拆分为多个类。

有 10 个依赖项表明你的类做得很多,并且被认为是代码异味(查看this)。你的班级似乎有太多的责任,因此违反了Single Responsibility Principle。考虑Aggregated Services 来解决您的问题。

根据您的情况,您可以选择现在进行建议的修复,然后在有时间时进行重构。看看Technical Debt的概念。

至于课程名称,您建议的名称就可以了。另一个建议是MyBaseClassDependencies

【讨论】:

    【解决方案2】:

    是的,完全合理的解决方案和层次结构的常用习语。

    你的名字就好了。另一种命名模式是BaseParamsBaseClassParams 等。

    【讨论】:

    • 在这种情况下,访问字段的更好方法是什么。像这样分配它们:this.db = params.db,然后在不更改的情况下访问它们或将所有出现的 this.db 替换为 this.params.getDb()
    • 可能是前者,假设它有吸气剂:this.db = params.getDb()。它将更传统,与您的其他代码(包括子类)相似。
    猜你喜欢
    • 1970-01-01
    • 2020-10-24
    • 2012-01-03
    • 2014-10-06
    • 1970-01-01
    • 2015-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多