2017-02-03 48 views
1

对主题“宁​​可组成了继承”,我的老师这样说:组成,转发和包装

  • 组成:现有的类将成为新的一个
  • 转发的一个组成部分:每个实例方法在新的类,调用了现有的类的实例包含相应的方法并返回结果
  • 包装:新类封装现有

我不太明白这三个概念,所以我试着写下一些代码:

//Composition is this 
Class A{ 
    public void doSomething(){ 
     //do some code 
    } 
} 

Class B{ 
    A a = new A(); 
    public void doOther(){ 
     a.doSomething(); //this is forwarding 
    } 
} 

那么什么是包装呢?

回答

1

你的第一个例子不是组合。

Composition是2名对象,其中一个对象(所构成的对象)是其他的场构件(所有者)之间的“has-a”的关系。

组成是:

class DemoA { 
    DemoB b; //composition 
} 

我们会说: “DemoA由复员的”。

如果DemoB对象仍然是可用的,当DemoA变得无法访问,我们认为DemoBaggregated。例如,虽然密钥环可能已被破坏,但仍可使用密钥。密钥环由密钥组成,但不拥有它们,表示聚合。


你转发的例子看起来不错,但要求不要说“返回结果”,这可能意味着该方法不应该是无效的:

class DemoA { 
    private DemoB b; 

    public int doSomething() { 
     return b.doSomething(); //forwarding/delegating 
    } 
} 

至于包装,它们封装了对象的行为,暴露了新的(通常更复杂的)行为。一个例子是DataInputStream,它包装InputStream以允许您读取String对象和更多,当InputStream只有原始数据时。

class DemoB { 
    public int read() { 
     //...Read one int of data 
    } 
} 

class DemoA { 
    private DemoB b; 

    public DemoA(DemoB b) { 
     this.b = b; 
    } 

    public List<Integer> readUntil(List<Integer> dataList, Supplier<Boolean> condition) { 
     while(condition.get()) 
      dataList.add(b.read()); 

     return dataList; 
    } 
} 

在这个例子中,DemoA包裹DemoB揭露readUntil行为,一些DemoB无法执行的。

这有点傻例子,但希望表达一点:我们DemoB对象不能执行的行为,我们需要(readUntil),所以我们把它包在处理的行为对我们是一个类型的,所以我们不是活得不断重写这种行为。

0

现有类成为新的一个

的对战

一个组件的新类封装现有

听起来冗余。

包装和构图在概念上传达了同样的东西。

在您的实际示例代码:

class A{ 
    public void doSomething(){ 
     //do some code 
    } 
} 

class B{ 
    A a = new A(); 
    public void doOther(){ 
     a.doSomething(); //this is forwarding 
    } 
} 

,因为它在它的状态存储A实例,并使用它在doOtherMethod()实现的B类组成一个A实例。
尽管如此,您可以执行包装/合成,但不使用调度模式,因为所调用的方法在作曲者和合成实例之间不是对称的。您的确称为b.doOther(),即a.doSomething()

一个基本的调度模式将看起来像:

class A{ 
    public void doSomething(){ 
     //do some code 
    } 
} 

class B{ 
    A a = new A(); 
    public void doSomething(){ 
     a.doSomething(); //this is forwarding 
    } 
} 

在这里,您拨打正是在构成的情况下同样的方法,在作曲家实例:doSomething()方法。
您可以在B课程中添加一些其他方法。