Java 装饰图案如何遵循构图

Java 装饰图案如何遵循构图,java,Java,我在HeadFirst DesginPattern一书中读到,装饰器模式使用组合关系来动态地为对象提供附加功能。但是在下面的代码中,我找到了聚合关系而不是组合 据我所知,合成和聚合的区别在于: 聚合:聚合对象的生命或存在相互独立,但一个对象扮演另一个对象的所有者角色 public abstract class Girl { String description = "no particular"; public String getDescription(){

我在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());        
    }
}
合成:复合对象的生命或存在取决于容器对象的存在,没有容器对象,复合对象的存在就没有意义

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());        
    }
}
有人能指出/解释上面的代码是如何遵循组合的吗

聚合和合成之间的相似性使得它们经常被用作同义词。依我看,如果你没有理由做出区分,那就不值得花时间讨论它到底是什么。如果你确实有理由,你可能已经知道它属于哪一个了

它们在概念上非常接近,因此它们就是你对待它们的方式。如果将关系用作单个单元,则它是一个组合。如果您与它们相互独立地进行交互,则这是一个聚合

主要的细节在于它为什么重要。我能想到的区分这两者的主要需要是垃圾收集。在
聚合中
容器的属性在其容器上下文之外可能仍然有意义。在
组合中
容器的属性应随容器一起销毁

当一个人观察到一个与定义相反的对象存在的价值时,我相信它可以表示为两者。在某些情况下,您可能希望仅销毁容器并保留内容(
aggregation
)。然而,如果没有它的委托,它是没有意义的。这在某种程度上定义了一种逆合成。你永远不会想毁掉孩子,留下装饰师

尽管
Science
实际上是一个具体的
Girl
,但是
Science.getDescription
的实现会覆盖基本实现,将请求委托给具体的
Girl
。如果没有使用有效的
girl
实现进行初始化,此实现细节将使
Science
girl变得毫无意义

如果存在本身是无意义的,那么它通常不是一个聚合,而是一个组合


另一方面,通过实现接口而不是继承基类来更清楚地表示装饰器。遵循单一责任原则,您可以确定装饰师不是该主题的实现。

一个很好的解释:……也许“HeadFirst设计模式手册”的定义没有(您)严格。(因为很多人只是随便地把这两个词都当作“1对N关系”的同义词)我知道这句话,但它在谷歌搜索中排名靠前。。从你的例子来看,如果没有一个女孩的物体来装饰,科学就不可能存在,没有它,从功能上来说,它就没有任何意义。这不是作文吗?我一直认为人和心是构成,学生和学校是聚合。。非常基本,但在我看来很有用。