@@@模式定义:
将对象组合成树型结构以表示“部分-整体”的层次结构。
组合模式使得用户对单个对象和组合对象的使用具有一致性。
@@@练习示例:
商品类别树
@@@示例代码:
<不用模式>
\product\Leaf.java
\product\Composite.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\user\Client.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<问题描述>
必须区分组合对象和叶子对象,并进行有区别的对待;
<使用模式>
\pattern\Component.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\pattern\Leaf.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\pattern\Composite.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\user\CilentPattern.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@@模式的实现:
1. 有“安全性”和“透明性”两种实现方式;
@@@模式的优点:
1. 定义了包含基本对象和组合对象的类层次结构;
2. 统一了组合对象和叶子对象;
3. 简化了客户端调用;
4. 更容易扩展;
@@@模式的缺点:
1. 很难限制组合中的组件类型;
@@@模式的本质:
统一叶子对象和组合对象。
@@@模式体现的设计原则:
NA
将对象组合成树型结构以表示“部分-整体”的层次结构。
组合模式使得用户对单个对象和组合对象的使用具有一致性。
@@@练习示例:
商品类别树
@@@示例代码:
<不用模式>
\product\Leaf.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
package product;
/**
* 叶子对象
*/
public class Leaf {
/**
* 叶子对象的名字
*/
private String name = "";
/**
* 构造方法,传入叶子对象的名字
* @param name 叶子对象的名字
*/
public Leaf(String name) {
this.name = name;
}
/**
* 输出叶子对象的结构,叶子对象没有子对象,也就是输出叶子对象的名字
* @param preStr 前缀,主要是按照层级拼接的空格,实现向后缩进
*/
public void printStruct(String preStr) {
System.out.println(preStr + "-" + name);
}
}
\product\Composite.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
package product;
import java.util.ArrayList;
import java.util.Collection;
/**
* 组合对象,可以包含其他组合对象或者叶子对象
*/
public class Composite {
/**
* 用来记录包含的其他组合对象
*/
private Collection<Composite> childComposite =
new ArrayList<Composite>();
/**
* 用来记录包含的其他叶子对象
*/
private Collection<Leaf> childLeaf =
new ArrayList<Leaf>();
/**
* 组合对象的名字
*/
private String name = "";
/**
* 构造方法,传入组合对象的名字
* @param name 组合对象的名字
*/
public Composite(String name) {
this.name = name;
}
/**
* 向组合对象加入被它包含的其他组合对象
* @param c 被它包含的其他组合对象
*/
public void addComposite(Composite c) {
this.childComposite.add(c);
}
/**
* 向组合对象加入被它包含的叶子对象
* @param leaf 被它包含的叶子对象
*/
public void addLeaf(Leaf leaf) {
this.childLeaf.add(leaf);
}
/**
* 输出组合对象自身的结构
* @param preStr 前缀,主要是按照层级拼接的空格,实现向后缩进
*/
public void printStruct(String preStr) {
// 先把自己输出去
System.out.println(preStr + "" + this.name);
// 然后添加一个空格,表示向后缩进一个空格,输出自己包含的叶子对象
preStr += " ";
for(Leaf leaf : childLeaf) {
leaf.printStruct(preStr);
}
// 输出当前对象的字对象
for(Composite c : childComposite) {
// 递归输出每个子对象
c.printStruct(preStr);
}
}
}
\user\Client.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
package user;
import product.Composite;
import product.Leaf;
public class Client {
public static void main(String[] args) {
// 定义所有的组合对象
Composite root = new Composite("服装");
Composite c1 = new Composite("男装");
Composite c2 = new Composite("女装");
// 定义所有的叶子对象
Leaf leaf1 = new Leaf("衬衣");
Leaf leaf2 = new Leaf("夹克");
Leaf leaf3 = new Leaf("裙子");
Leaf leaf4 = new Leaf("套装");
// 按照树的结构来组合组合对象和叶子对象
root.addComposite(c1);
root.addComposite(c2);
c1.addLeaf(leaf1);
c1.addLeaf(leaf2);
c2.addLeaf(leaf3);
c2.addLeaf(leaf4);
// 调用根对象的输出功能来输出整棵树
root.printStruct("");
}
}
<问题描述>
必须区分组合对象和叶子对象,并进行有区别的对待;
<使用模式>
\pattern\Component.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
package pattern;
/**
* 抽象的组件对象
*/
public abstract class Component {
/**
* 输出组件自身的名称
*/
public abstract void printStruct(String preStr);
/**
* 向组合对象中加入组件对象
* @param child 被加入组合对象中的组件对象
*/
public void addChild(Component child) {
throw new UnsupportedOperationException("不支持该功能");
}
/**
* 从组合对象中移出某个组件对象
* @param child 被移出的组件对象
*/
public void removeChild(Component child) {
throw new UnsupportedOperationException("不支持该功能");
}
/**
* 返回某个索引对应的组件对象
* @param index 需要获取的组件对象的索引,索引从0开始
* @return 索引对应的组件对象
*/
public Component getChildren(int index) {
throw new UnsupportedOperationException("不支持该功能");
}
}
\pattern\Leaf.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
package pattern;
/**
* 叶子对象
*/
public class Leaf extends Component {
/**
* 叶子对象的名字
*/
private String name = "";
/**
* 构造方法,传入叶子对象的名字
* @param name 叶子对象的名字
*/
public Leaf(String name) {
this.name = name;
}
/**
* 输出叶子对象的结构,叶子对象没有子对象,也就是输出叶子对象的名字
* @param preStr 前缀,主要是按照层级拼接的空格,实现向后缩进
*/
@Override
public void printStruct(String preStr) {
System.out.println(preStr + "-" + name);
}
}
\pattern\Composite.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
package pattern;
import java.util.ArrayList;
import java.util.List;
/**
* 组合对象,可以包含其他组合对象或者叶子对象
*/
public class Composite extends Component {
/**
* 用来存储组合对象中包含的子组件对象
*/
private List<Component> childComonents = null;
/**
* 组合对象的名字
*/
private String name = "";
/**
* 构造方法,传入组合对象的名字
* @param name 组合对象的名字
*/
public Composite(String name) {
this.name = name;
}
@Override
public void addChild(Component child) {
// 延迟初始化
if (childComonents == null) {
childComonents = new ArrayList<Component>();
}
childComonents.add(child);
}
/**
* 输出组合对象自身的结构
* @param preStr 前缀,主要是按照层级拼接的空格,实现向后缩进
*/
@Override
public void printStruct(String preStr) {
// 先把自己输出去
System.out.println(preStr + "" + this.name);
// 如果还包含有子组件,那么就输出这些子组件对象
if (this.childComonents != null) {
// 添加一个空格,表示向后缩进一个空格
preStr += " ";
// 输出当前对象的子对象
for (Component c : childComonents) {
// 递归输出每个子对象
c.printStruct(preStr);
}
}
}
}
\user\CilentPattern.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
package user;
import pattern.Component;
import pattern.Composite;
import pattern.Leaf;
public class CilentPattern {
public static void main(String[] args) {
// 定义所有的组合对象
Component root = new Composite("服装");
Component c1 = new Composite("男装");
Component c2 = new Composite("女装");
// 定义所有的叶子对象
Component leaf1 = new Leaf("衬衣");
Component leaf2 = new Leaf("夹克");
Component leaf3 = new Leaf("裙子");
Component leaf4 = new Leaf("套装");
// 按照树的结构来组合组合对象和叶子对象
root.addChild(c1);
root.addChild(c2);
c1.addChild(leaf1);
c1.addChild(leaf2);
c2.addChild(leaf3);
c2.addChild(leaf4);
// 调用根对象的输出功能来输出整棵树
root.printStruct("");
}
}
@@@模式的实现:
1. 有“安全性”和“透明性”两种实现方式;
@@@模式的优点:
1. 定义了包含基本对象和组合对象的类层次结构;
2. 统一了组合对象和叶子对象;
3. 简化了客户端调用;
4. 更容易扩展;
@@@模式的缺点:
1. 很难限制组合中的组件类型;
@@@模式的本质:
统一叶子对象和组合对象。
@@@模式体现的设计原则:
NA