组合模式
组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。
这种模式创建了一个包含自己对象组的类。该类提供了修改相同对象组的方式。
我们通过下面的实例来演示组合模式的用法。实例演示了一个组织中员工的层次结构。
介绍
意图:将对象组合成树形结构以表示"部分-整体"的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
主要解决:它在我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以像处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。
何时使用: 1、您想表示对象的部分-整体层次结构(树形结构)。 2、您希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。
如何解决:树枝和叶子实现统一接口,树枝内部组合该接口。
关键代码:树枝内部组合该接口,并且含有内部属性 List,里面放 Component。
应用实例: 1、算术表达式包括操作数、操作符和另一个操作数,其中,另一个操作数也可以是操作数、操作符和另一个操作数。 2、在 JAVA AWT 和 SWING 中,对于 Button 和 Checkbox 是树叶,Container 是树枝。
优点: 1、高层模块调用简单。 2、节点自由增加。
缺点:在使用组合模式时,其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则。
使用场景:部分、整体场景,如树形菜单,文件、文件夹的管理。
注意事项:定义时为具体类。
demo
入口类
package component_method_mod;
import org.junit.Test;
/**
* 组合模式
* 将对象组合成树形结构以表示“部分-整体”的层次结构。“Composite(组合)使得用户对单个对象和组合对象的使用具有一致性。”
*
* 类型:结构型模式
*
* 适用性:
*
* 想表示对象的部分-整体层次结构
* 希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象
*/
public class Client {
@Test
public void test(){
Animal tiger = new Tiger("刀疤虎");
Animal cat = new Cat("咖啡猫");
Animal cat2 = new Cat("芭比猫");
Animal dog = new Dog("华田狗");
Animal dog2 = new Dog("单身狗");
Animal chick = new Chick("黄花鸡");
Animal chick2 = new Chick("雀斑鸡");
Animal duck = new Duck("白羽鸭");
tiger.add(cat);
tiger.add(cat2);
tiger.add(dog2);
tiger.add(dog);
dog.add(chick);
dog.add(chick2);
chick.add(duck);
printInfo("/",tiger);//输出树级结构
}
/**
* 迭代输出 树级结构
* @param pre
* @param a
*/
public static void printInfo(String pre ,Animal a){
System.out.println(String.format("%s 下属:%s",pre,a.getName()));
if(null == a.getSubAnimal()){
return;
}
for(Animal b : a.getSubAnimal()){
printInfo(a.getName(),b);
}
}
}
执行结果打印如下:
/ 下属:刀疤虎
刀疤虎 下属:咖啡猫
刀疤虎 下属:芭比猫
刀疤虎 下属:单身狗
刀疤虎 下属:华田狗
华田狗 下属:黄花鸡
黄花鸡 下属:白羽鸭
华田狗 下属:雀斑鸡
抽象类,组件animal
package component_method_mod;
import java.util.List;
/**
* Component(组件)
*
* 为组合中的对象声明接口
* 在适当的情况下,实现所有类共有接口的缺省行为
* 声明一个接口用于访问和管理Component的子组件
*/
public abstract class Animal {
private String name;
protected List<Animal> animalList;
public abstract void add(Animal animal);
public abstract void delete(Animal animal);
public void say(){
System.out.println(String.format("name is %s",name));
};
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Animal> getSubAnimal(){
return animalList;
}
}
具体类,老虎
package component_method_mod;
import java.util.ArrayList;
/**
* Composite
*
* 定义有子部件的那些部件的行为。
* 存储子部件。
*
* 在Component接口中实现与子部件有关的操作。
*/
public class Tiger extends Animal {
public Tiger(String name) {
setName(name);
animalList = new ArrayList<Animal>();
}
@Override
public void add(Animal animal) {
animalList.add(animal);
}
@Override
public void delete(Animal animal) {
animalList.remove(animal);
}
}
具体类 狗
package component_method_mod;
import java.util.ArrayList;
public class Dog extends Animal {
public Dog(String name){
setName(name);
animalList = new ArrayList<Animal>();//无下属
}
@Override
public void add(Animal animal) {
animalList.add(animal);
}
@Override
public void delete(Animal animal) {
animalList.remove(animal);
}
}
具体类猫
package component_method_mod;
public class Cat extends Animal{
public Cat(String name) {
setName(name);
animalList = null;//无下属
}
@Override
public void add(Animal animal) {
}
@Override
public void delete(Animal animal) {
}
}
具体类 鸡
package component_method_mod;
import java.util.ArrayList;
public class Chick extends Animal {
public Chick(String name){
setName(name);
animalList = new ArrayList<Animal>();//无下属
}
@Override
public void add(Animal animal) {
animalList.add(animal);
}
@Override
public void delete(Animal animal) {
animalList.remove(animal);
}
}
具体类 鸭
package component_method_mod;
/**
* Leaf(叶子)
*
* 在组合中表示叶节点对象,叶节点没有子节点
* 在组合中定义节点对象的行为
*/
public class Duck extends Animal {
public Duck(String name) {
setName(name);
animalList = null;
}
@Override
public void add(Animal animal) {
}
@Override
public void delete(Animal animal) {
}
}