装饰者模式如何遵循构图

时间:2013-11-08 05:41:57

标签: java

我在HeadFirst DesginPattern书中读到,装饰器模式使用组合关系动态地为对象提供附加功能。但是在下面的代码中我找到了聚合关系而不是组合。

据我所知,组合和聚合之间的区别是:

聚合:聚合对象的生命或存在是相互独立的,但是一个对象扮演另一个对象的所有者的角色。

组合:复合对象的生命或存在依赖于容器对象的存在,没有容器对象,复合对象的存在是没有意义的。

public abstract class Girl {

    String description = "no particular";

    public String getDescription(){
        return description;
    }
}

public class AmericanGirl extends Girl {

    public AmericanGirl(){
        description = "+American";
    }
}

public class EuropeanGirl extends Girl {

    public EuropeanGirl() {
        description = "+European";
    }
}

public abstract class GirlDecorator extends Girl {

    public abstract String getDescription();
}

public class Science extends GirlDecorator {

    private Girl girl;

    public Science(Girl g) {
        girl = g;
    }

    @Override
    public String getDescription() {
        return girl.getDescription() + "+Like Science";
    }

    public void caltulateStuff() {
        System.out.println("scientific calculation!");
    }
}

public class Main {

    public static void main(String[] args) {
        Girl g1 = new AmericanGirl();
        System.out.println(g1.getDescription()); 
        Science g2 = new Science(g1);
        System.out.println(g2.getDescription());        
    }
}

有人可以指出/解释上面的代码是如何遵循组合的吗?

1 个答案:

答案 0 :(得分:1)

aggregation composition 之间的相似性使它们经常被用作同义词。国际海事组织如果你没有理由进行区分,那么它的实际辩论时间是不值得的。如果你确实有理由,你可能已经知道它属于哪个。

他们在概念上足够接近他们是如何对待他们的。如果您将关系用作单个单元,则它是 composition 。如果您彼此独立地互动,那么它就是 aggregation

主要细节在于它的重要性。我能想到的两者之间的区别主要是垃圾收集。在 aggregation 中,容器的属性在其容器上下文之外可能仍然有意义。在 composition 中,容器的属性应该与容器一起销毁。

当观察到与定义相反的对象存在的值时,我相信它可以表示为两者。在某些情况下,您可能希望仅销毁容器并保留内容( aggregation )。但是,如果没有它的代表,它就毫无意义。这定义了一些 inverse composition 。你永远不想破坏孩子并保留装饰。

虽然Science实际上是具体的Girl,但Science.getDescription的实现会覆盖基本实现,以将请求委托给具体的Girl。此实现细节使Science女孩没有用有效的Girl实现进行初始化而毫无意义。

如果存在本身没有意义,那么它通常不是 aggregation ,而可能是 composition

另外,通过实现接口而不是继承基类,可以更清楚地表达装饰器。坚持单一责任原则,您就可以确定装饰者不是该主题的实现。