代码之家  ›  专栏  ›  技术社区  ›  devoured elysium

我应该通过在类中注入构造函数使具体的类依赖关系显式化吗?

  •  9
  • devoured elysium  · 技术社区  · 14 年前

    所以,假设我们有 ClassB ClassA :

    alt text

    class ClassB {
    }
    

    我的问题是,我应该创造 B类 甲级 ,或者我应该在层次结构中“向上”传递该职责吗?我将描述两个案例:

    class ClassA {
        private ClassB classB;
    
        public ClassA() {
            this.classB = new ClassB();
        }
    }
    

    class ClassA {
        private ClassB classB;
    
        public ClassA(ClassB classB) {
            this.classB = classB;
        }
    }
    

    我想听听你会怎么做,以及背后的理由是什么!

    谢谢

    5 回复  |  直到 14 年前
        1
  •  3
  •   Mark Heath    14 年前

    第一个选项(A创建B)的一些优点:

    1. A类用户不需要知道B或如何创建和配置B。这使得编程模型更简单。
    2. 也可以将B设为私有/内部的,这样您的库的用户就不需要费力地浏览许多他们不需要看到的helper类。
    3. 您可以将A的工作方式更改为完全不使用B,而不破坏调用代码。
    4. 封装-当A运行时,没有人可以从外部篡改B

    第二个选项的一些优点(A依赖于B):

    1. 类A的用户可以完全控制B对象—他们可以对B对象进行不同的配置,如果需要,他们可以将同一个对象传递到A的多个实例中。
    2. 更新 :如果在将来,创建B变得更加复杂(例如,B有自己的一些依赖项),那么它可以在外部管理,而无需对A进行更改。

    class ClassA {
        private ClassB classB;
    
        public ClassA(ClassB classB) {
            this.classB = classB;
        }
    
        public ClassA() : this(new ClassB()) {
    
        }
    }
    
        2
  •  3
  •   testalino    14 年前

    这要看执行情况,没有一般的答案。如果A拥有初始化B的所有相关数据和知识,那么它可以初始化B。

    如果你不想让A知道如何初始化B,或者你不想给A初始化的所有数据,那么你应该在外部创建它。

        3
  •  2
  •   Arseny    14 年前

    class ClassA {
    private InterfaceB B;
    
    public ClassA(InterfaceB B) {
        this.B = B;
    }
    }
    class classB: InterfaceB
    {
    }
    

    请注意,InterfaceB可能是一个常规类,作为派生类的基类。在这种情况下,它仍然作为接口工作。

        4
  •  1
  •   Adeel Ansari    14 年前

    在前者 A 承担全班的责任 B 实例化。所以,没有什么可以出错的。 知道 一个 想要的很少

    在后者中, 一个 不能那么肯定 .

    现在,当然是你的选择了。

        5
  •  0
  •   Co7e    10 年前

    第二个选项(通过构造器传递对象,即反转控件)的一些优点目前还没有提到:

    2) 如果总是在构造函数中传递依赖项(控制反转),那么可以说每个类有哪些依赖项一目了然。