关于"更喜欢构图而非继承",我的老师说:
我不太了解这三个概念,所以我试着写下一些代码:
//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
}
}
什么是包装?
答案 0 :(得分:2)
你的第一个例子不是作文。
Composition是两个对象之间的“has-a”关系,其中一个对象(组合对象)是另一个对象的字段成员(所有者)。
组成将是:
class DemoA {
DemoB b; //composition
}
我们会说“DemoA由DemoB组成”。
如果在DemoB
无法访问时DemoA
对象仍然可用,我们会将DemoB
视为aggregated。例如,尽管密钥环可能已被破坏,仍然可以使用密钥。密钥环将由密钥组成,但不拥有它们,表示聚合。
您的转发示例看起来很好,虽然要求确实说“返回结果”,这可能表明方法不应该是无效的:
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 ),所以我们将它包装在一个处理我们的行为,所以我们不会经常改写这种行为。
答案 1 :(得分:0)
现有的类成为新类的一个组件
Versus
新类封装了现有的
听起来多余。
包装和构图确实在概念上传达了同样的东西。
在您的实际示例代码中:
class A{
public void doSomething(){
//do some code
}
}
class B{
A a = new A();
public void doOther(){
a.doSomething(); //this is forwarding
}
}
B
类组成A
实例,因为它将A
实例存储在其状态中,并在doOtherMethod()
实现中使用它。
但是,您执行包装/合成但不使用调度模式,因为调用的方法在编写器和组合实例之间不对称。您确实致电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
}
}
在此,您在组合实例中调用与在composer实例中完全相同的方法:doSomething()
方法。
你当然可以在B类中添加一些其他方法。