您的位置:首页 > 编程语言 > Java开发

实例探索Java模式之路——合成模式

2017-06-09 21:15 567 查看
合成模式

1、合成模式属于对象的结构模式,又叫做部分—整体模式。合成模式将对象组织到树结构中,用来描述整体与部分的关系。合成模式使客户端将单纯元素与复合元素同等看待。

2、基于继承的类型的等级结构以及基于合成的对象结构也是一个树结构。

3、合成模式结构:



抽象构件角色:一个抽象角色,它给出了参加组合的对象规定一个接口。此角色给出共同的接口及其默认行为。
树叶构件角色:代表参加组合的树叶对象。树叶没有下级子对象。定义出参加组合的原始对象的行为。
树枝构件角色:代表参加的有子对象的对象,并给出树枝构件对象的行为。

4、合成模式可以不提供父对象的管理方法,但合成对象必须在合适的地方提供子对象的管理方法。例如add(),remove()等。

5、合成模式分为安全式和透明式模式两种方式:

透明式:在Component里声明所有的管理子类对象的方法,这样的好处是所有的构件类都有相同的接口。在客户端看来,树叶类对象与合成类对象的区别在接口层次上消失了,客户端可以同等看待所有的对象。
缺点:不够安全,树叶类对象不可能有下以层次的对象,运行期会出错。

安全式:在Composite类里面声明所有用来管理子类的方法,安全,客户端不可以对树叶类对象使用这些方法。
缺点:不够透明,因为树叶类和合成类将具有不同的接口。

6、安全式的合成模式:

安全式的合成模式要求聚集的方法出现在树枝构件类中,而不出现在树叶构件类中。



抽象构件角色:一个抽象角色,它给出了参加组合的对象规定一个接口。此角色给出共同的接口及其默认行为。在安全式合成模式中,构件角色并不定义出管理子对象的方法,定义由树枝构件对象给出。
树叶构件角色:代表参加组合的树叶对象。树叶没有下级子对象。定义出参加组合的原始对象的行为。
树枝构件角色:代表参加的有子对象的对象,并给出树枝构件对象的行为。树枝构件给出所有的管理子对象的方法,如add() ,remove()的声明。

7、安全式模式的例子:

//安全式合成模式,管理聚集的方法只出现在树枝构件中,而不出现在树叶构件类中
public interface Component {

// 返还自己的实例
Composite getComposite();

// 某个商业方法
void sampleOperation();

}

import java.util.Enumeration;
import java.util.Vector;

//构件树枝类不仅给出抽象构件角色所声明的两个方法,而且声明并实现了管理聚集用的add(),remove()等方法
public class Composite implements Component {

private String name;
private Vector componentVector = new java.util.Vector();

// 有参构造,传入组合对象名字
public Composite(String name) {
this.name = name;
}

// 返还自己的实例
@Override
public Composite getComposite() {
System.out.println("树枝返回自己的实例");
return this;
}

// 某个商业方法
@Override
public void sampleOperation() {
Enumeration enumeration = components();
System.out.println("树枝商业方法");
while (enumeration.hasMoreElements()) {
((Component) enumeration.nextElement()).sampleOperation();

}
}

// 添加一个子构件对象

public void add(Component component) {
System.out.println("添加一个子构件对象");
componentVector.addElement(component);
}

// 删除一个子构件对象
public void remove(Component component) {
System.out.println("删除一个子构件对象");
componentVector.remove(component);
}

private Enumeration components() {
return componentVector.elements();
}

public void printStruct(String str) {
System.out.println(str + "-" + name);
}
}

//树叶
public class Leaf implements Component {

private String name;

//有参构造
public Leaf(String name) {
this.name = name;
}

// 返还自己的实例
@Override
public Composite getComposite() {
System.out.println("合成模式树叶返还自己的实例");
return null;
}

// 某个商业方法
@Override
public void sampleOperation() {
System.out.println("合成模式树叶的商业方法");
}

}

//测试类
public class client {
public static void main(String[] args) {

Composite root = new Composite("课程");

Composite c1 = new Composite("文科");
Composite c2 = new Composite("理科");

Leaf l1 = new Leaf("历史");
Leaf l2 = new Leaf("政治");
Leaf l3 = new Leaf("生物");
Leaf l4 = new Leaf("物理");
Leaf l5 = new Leaf("化学");

root.add(c1);
root.add(c2);c1.add(l1);
c1.add(l2);
c2.add(l3);
c2.add(l4);
c2.add(l5);

c2.remove(l5);

c1.sampleOperation();

l1.sampleOperation();

System.out.println(root);

}
}

8、透明式的合成模式:

透明式模式要求所有的具体构件类,不论树枝还是树叶,均符合一个固定的接口。



抽象构件角色:一个抽象角色,它给出了参加组合的对象规定一个接口。此角色给出共同的接口及其默认行为。这个接口用来管理所有的子对象,要求提供一个接口规范和管理下层组件接口,包括add(),remove()。

树叶构件角色:代表参加组合的树叶对象。树叶没有下级子对象。定义出参加组合的原始对象的行为。树叶角色给出add(),remove()的平庸实现。
树枝构件角色:代表参加的有子对象的对象,并给出树枝构件对象的行为。

9、透明式模式的例子:

//透明式模式要求所有的具体构件类,不论树枝还是树叶,均符合一个固定的接口。
public interface Component {

// 返还自己的实例
Composite getComposite();

// 某个商业方法
void sampleOperation();

// 添加一个子构件对象
void add(Component component);

// 删除一个子构件对象
void remove(Component component);
}

import java.util.Enumeration;
import java.util.Vector;

//构件树枝类不仅给出抽象构件角色所声明的两个方法,而且声明并实现了管理聚集用的add(),remove()等方法
public class Composite implements Component {

private String name;
private Vector componentVector = new java.util.Vector();

// 有参构造,传入组合对象名字
public Composite(String name) {
this.name = name;
}

// 返还自己的实例
@Override
public Composite getComposite() {
System.out.println("树枝返回自己的实例");
return this;
}

// 某个商业方法
@Override
public void sampleOperation() {
Enumeration enumeration = components();
System.out.println("树枝商业方法");
while (enumeration.hasMoreElements()) {
((Component) enumeration.nextElement()).sampleOperation();

}
}

// 添加一个子构件对象

public void add(Component component) {
System.out.println("添加一个子构件对象");
componentVector.addElement(component);
}

// 删除一个子构件对象
public void remove(Component component) {
System.out.println("删除一个子构件对象");
componentVector.remove(component);
}

private Enumeration components() {
return componentVector.elements();
}

}

//树叶
public class Leaf implements Component {

private String name;

// 有参构造
public Leaf(String name) {
this.name = name;
}

// 返还自己的实例
@Override
public Composite getComposite() {
System.out.println("合成模式树叶返还自己的实例");
return null;
}

// 某个商业方法
@Override
public void sampleOperation() {
System.out.println("合成模式树叶的商业方法");
}

@Override
public void add(Component component) {
// TODO Auto-generated method stub

}

@Override
public void remove(Component component) {
// TODO Auto-generated method stub

}

}

//客户端的变化是不再区分是树枝还是树叶,对于客户端而言都是Component对象

public class client {
public static void main(String[] args) {
Component root = new Composite("课程");

Component c1 = new Composite("文综");
Component c2 = new Composite("理综");

Component l1 = new Leaf("政治");
Component l2 = new Leaf("历史");
Component l3 = new Leaf("生物");
Component l4 = new Leaf("物理");
Component l5 = new Leaf("化学");

root.add(c1);
root.add(c2);
c1.add(l1);
c1.add(l2);
c2.add(l3);
c2.add(l4);
c2.add(l5);

c2.remove(l5);

c1.sampleOperation();

l1.sampleOperation();

System.out.println(root);
}
}

10、使用场景

需求中体现整体与部分的关系,希望用户可以忽略组合对象与单体对象的不同,统一使用组合结构中的所有对象,就考虑使用组合模式。

通过此实例,相信对该模式有了进一步的认识。

每天努力一点,每天都在进步。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  合成模式 Java模式