Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop 物体的构成_Oop_Composition - Fatal编程技术网

Oop 物体的构成

Oop 物体的构成,oop,composition,Oop,Composition,我有一个班,担任经理,做一些工作。 当应用服务器启动时启动的servlet将实例化此管理器。 我需要添加另一个类来完成其他工作,并且需要与经理协调。 我正在考虑将该类作为实例变量添加到管理器中。 我应该让管理器实例化新类(如在构造函数中),还是让servlet实例化新类并在管理器实例化后调用manager.setNewClass()。为了正确地进行解耦,您应该创建一个定义管理器期望的行为的接口,然后通过控制/依赖注入的反转提供一个实现。这将允许您单独测试管理器及其工作类(我称之为委托,但可能不是

我有一个班,担任经理,做一些工作。 当应用服务器启动时启动的servlet将实例化此管理器。 我需要添加另一个类来完成其他工作,并且需要与经理协调。 我正在考虑将该类作为实例变量添加到管理器中。 我应该让管理器实例化新类(如在构造函数中),还是让servlet实例化新类并在管理器实例化后调用manager.setNewClass()。为了正确地进行解耦,您应该创建一个定义管理器期望的行为的接口,然后通过控制/依赖注入的反转提供一个实现。这将允许您单独测试管理器及其工作类(我称之为委托,但可能不是)

编辑——这个答案假设是java,因为您提到了servlet

您有一个manager类,在其中您需要一个接口

class Manager {
    Worker worker;

    Manager(Worker worker) {
        this.worker = workder
    }
}
Worker是一个接口。它定义行为,但不定义实现

interface Worker {
    public void doesSomething(); //method definition but  no implementation
}
class WorkerImpl implements Worker {
    // must define a doesSomething() implementation
}
现在需要创建一个实现

interface Worker {
    public void doesSomething(); //method definition but  no implementation
}
class WorkerImpl implements Worker {
    // must define a doesSomething() implementation
}

经理只知道它有一些工人。您可以提供实现接口的任何类。这就是解耦——管理器不绑定到任何特定的实现,它只绑定到工作人员的行为。

好吧,作为一种过度概括,您应该在servlet中实例化它并将其传递给管理器(通过构造函数参数,或通过
setNewClass()
)。。。注入依赖项,而不是硬编码它们

然而,根据您的具体用例,即使这样也可能不是正确的答案。您最好使用一个用于构建manager类的工具。这样,构建器管理整个管理器的构造(包括任何依赖项),而不是将其硬编码到servlet中。这将把依赖关系从servlet移到构建器中(您可以在测试和其他代码中更好地处理构建器)

简单的回答是没有银弹。如果不了解所有类之间的硬关系以及角色和职责,就很难说最好的方法。但是,在构造函数中实例化几乎从来都不是一个好主意,您应该以某种形式注入依赖项(但从何处开始尚待讨论).

这让我想起了这种模式

在何处创建实例并不重要。只要创建最适合您的地方,如果您在其他地方需要它,只需应用一些基本的重构


如果您真的需要解耦,请尝试使用一些工具,如,但仅在您真的需要时使用。

您能否详细说明如何创建一个定义经理期望的行为的界面,我看不出您要去哪里?上面的答案并不完全正确。这不是一个“花哨”的问题——除非您创建一个接口,否则管理器不会通过任何一种方法与“委托”分离。它从构造函数调用或setNewClass和实例变量中的类型签名中知道标识。现在,使用第二种方法也将servlet耦合到类,因此两者都是耦合的。@siyphus我同意。改变我的答案