组成与减少耦合?

时间:2012-07-10 08:38:08

标签: java oop composition

我在使用组合使用对象作为其他对象中的属性(以及在属性上调用方法)与使用良好的整体耦合之间有点混淆。

这里有权衡吗?

也许更容易给出不良耦合的例子来解释差异(如果存在差异)?

编辑示例:

public class MyClass(){
    MyOtherClass moc;

    public MyClass(MyOtherClass temp){
        moc = temp;
    }

    public void method(){
        moc.call()
    }
}

这是一种错误的耦合,因为它依赖于组合关系?如果没有,在这个例子中会出现什么不好的耦合。

2 个答案:

答案 0 :(得分:2)

关联类的两种基本方法是inheritancecomposition。当您在两个类之间建立继承关系时,您可以利用dynamic bindingpolymorphism

鉴于inheritance关系使得很难更改超类的interface,因此值得研究composition提供的替代方法。事实证明,当您的目标是代码重用时,composition提供了一种方法,可以生成更易于更改的代码。

class Fruit {

// Return int number of pieces of peel that
// resulted from the peeling activity.
public int peel() {

    System.out.println("Peeling is appealing.");
    return 1;
}
}

class Apple extends Fruit {
}

class Example1 {

public static void main(String[] args) {

    Apple apple = new Apple();
    int pieces = apple.peel();
}
}

但是,如果在将来某个时候,您希望将peel()的返回值更改为类型Peel,则会破坏Example1代码的代码,即使Example1直接使用Apple并且从未明确提及水果

Composition为Apple重用Fruit peel()的实现提供了另一种方法。 Apple可以保留对Fruit实例的引用,并定义自己的peel()方法,而不是扩展Fruit,而只是在Fruit上调用peel()。这是代码:

class Fruit {

// Return int number of pieces of peel that
// resulted from the peeling activity.
public int peel() {

    System.out.println("Peeling is appealing.");
    return 1;
}
 }

class Apple {

private Fruit fruit = new Fruit();

public int peel() {
    return fruit.peel();
}
}

class Example2 {

public static void main(String[] args) {

    Apple apple = new Apple();
    int pieces = apple.peel();
}
}

Inheritance提供比Composition更高的耦合。

答案 1 :(得分:2)

而不是差/良好耦合,似乎最接受的术语是紧密/松散耦合,松散耦合对象是首选。在您的示例中,更紧密的耦合可能是这样的(添加了用于说明的功能):

public class MyClass()
{
    MyOtherClass moc;
    public MyClass(MyOtherClass temp)
    {
        moc = temp;
    }

    public void method()
    {
        for (int i = 0; i < moc.items.Count; i++)
        {
            moc.items[i].Price += 5;
        }
    }
}

在这里,MyClass依赖于MyOtherClass的具体实现细节(项目列表的实现,成本等)。处理此类场景的更松散耦合的方法是将该逻辑移动到MyOtherClass上的函数中。这样,MyOtherClass的所有实现细节都隐藏在MyClass中,并且可以独立于MyClass进行更改。