【设计模式】组合模式的实现--------Java

组合(Composite)模式

“数据结构”模式:常有一些组件在内部具有特定的数据结构,如果让客户程序依赖这些特定的数据结构,会破坏组件的复用性。这时,将这些特定的数据结构封装在内部,在外部提供统一的接口,来实现与特定数据结构无关的访问。

动机:将客户代码与复杂的对象容器结构解耦

组合模式的目的:不区分组合对象还是叶子对象,而是以一种统一的方式操作。

1.场景问题:(商品类别树)
包括:根节点、树枝节点、叶子节点
其中,根节点与树枝节点类似,都包含其他节点,成为容器节点。

package computer;

import java.util.ArrayList;
import java.util.Collection;

public class Test {
	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("套装");
		
		//按照树的结构来组合组合对象和叶子对象
		root.addComposite(c1);
		root.addComposite(c2);
		
		c1.addLeaf(l1);
		c1.addLeaf(l2);
		c2.addLeaf(l3);
		c2.addLeaf(l4);
		
		//从根节点开始展示树
		root.printStruct(0);
	}
}

//叶子类
class Leaf{
	//叶子名
	private String name="";

	public Leaf(String name) {
		this.name = name;
	}
	
	//输出叶子
	public void printStruct(int d) {
		for(int i=0;i<d;i++) {
			System.out.print(" ");
		}
		System.out.println("-"+name);
	}
}

//组合类(包含其他组合对象和叶子对象)
class Composite{
	//下层其他组合对象
	private Collection<Composite> childComposite=new ArrayList<Composite>();
	//下层叶子对象
	private Collection<Leaf> childLeaf=new ArrayList<Leaf>();
	
	private String name="";

	public Composite(String name) {
		super();
		this.name = name;
	}
	
	//添加下层组合对象
	public void addComposite(Composite c) {
		childComposite.add(c);
	}
	
	//添加下层叶子
	public void addLeaf(Leaf l) {
		childLeaf.add(l);
	}
	
	//从该层开始输出下层的对象(组合和叶子)
	public void printStruct(int d) {
		//输出该层
		for(int i=0;i<d;i++) {
			System.out.print(" ");
		}
		System.out.println("+"+name);
		//输出下层
		for(Leaf leaf:childLeaf) {
			leaf.printStruct(d+2);
		}
		for(Composite c:childComposite) {
			c.printStruct(d+2);
		}
	}
}

缺点:区分组合对象和叶子对象会使程序变得复杂,对功能拓展带来不便。

2.改进:
不区分叶子节点还是分支节点,抽象出共同基类Component,继承它产生叶子节点和容器节点。

package computer;

import java.util.ArrayList;

public class Test {
	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("套装");
		
		//按照树的结构来组合组合对象和叶子对象
		root.add(c1);
		root.add(c2);
		
		c1.add(l1);
		c1.add(l2);
		c2.add(l3);
		c2.add(l4);
		
		//从根节点开始展示树
		root.printStruct(0);
	}
}

//抽象基类
abstract class Component{
	protected String name;
	public Component(String name) {
		this.name=name;
	}
	//添加
	public abstract void add(Component component);
	//删除
	public abstract void remove(Component component);
	//输出
	public abstract void printStruct(int d);
}

//叶子类
class Leaf extends Component{

	public Leaf(String name) {
		super(name);
	}
	
	public void add(Component component) {
		System.out.println("不能添加分支!");
	}
	
	public void remove(Component component) {
		System.out.println("不能删除分支!");
	}
	
	//显示
	public void printStruct(int d) {
		for(int i=0;i<d;i++) {
			System.out.print(" ");
		}
		System.out.println("-"+name);
	}
}

//有枝节点
class Composite extends Component{
	
	//下层节点或叶子
	private ArrayList<Component> components=new ArrayList<Component>();

	public Composite(String name) {
		super(name);
	}

	public void add(Component component) {
		components.add(component);
	}

	public void remove(Component component) {
		components.remove(component);
	}

	//显示
	public void printStruct(int d) {
		for(int i=0;i<d;i++) {
			System.out.print(" ");
		}
		System.out.println("+"+name);
		for(Component component:components) {
			component.printStruct(d+2);
		}
	}
	
}

3.组合模式
【设计模式】组合模式的实现--------Java_第1张图片

package computer;

import java.util.ArrayList;

public class Test {
	public static void main(String[] args) {
		//生成树根,树根上长出两个树叶
		Composite composite=new Composite("root");
		composite.add(new Leaf("LeafA"));
		composite.add(new Leaf("LeafB"));
		
		//树根上长出分支,分支上有两片叶子
		Composite c1=new Composite("CompositeX");
		c1.add(new Leaf("LeafAx"));
		c1.add(new Leaf("LeafBx"));
		composite.add(c1);
		
		//分支CompositeX上长出一分支,分支上有两叶
		Composite c2=new Composite("CompositeY");
		c2.add(new Leaf("LeafAxY"));
		c2.add(new Leaf("LeafBxY"));
		c1.add(c2);
		
		//根部长出叶子
		composite.add(new Leaf("LeafC"));
		
		//根部掉落叶子
		Leaf leafd=new Leaf("LeafD");
		composite.add(leafd);
		composite.remove(leafd);
		
		//显示
		composite.printStruct(0);
	}
}

//抽象基类
abstract class Component{
	protected String name;
	public Component(String name) {
		this.name=name;
	}
	//添加
	public abstract void add(Component component);
	//删除
	public abstract void remove(Component component);
	//输出
	public abstract void printStruct(int d);
}

//叶子类
class Leaf extends Component{

	public Leaf(String name) {
		super(name);
	}
	
	public void add(Component component) {
		System.out.println("不能添加分支!");
	}
	
	public void remove(Component component) {
		System.out.println("不能删除分支!");
	}
	
	//显示
	public void printStruct(int d) {
		for(int i=0;i<d;i++) {
			System.out.print(" ");
		}
		System.out.println("-"+name);
	}
}

//有枝节点
class Composite extends Component{
	
	//下层节点或叶子
	private ArrayList<Component> components=new ArrayList<Component>();

	public Composite(String name) {
		super(name);
	}

	public void add(Component component) {
		components.add(component);
	}

	public void remove(Component component) {
		components.remove(component);
	}

	//显示
	public void printStruct(int d) {
		for(int i=0;i<d;i++) {
			System.out.print(" ");
		}
		System.out.println("+"+name);
		for(Component component:components) {
			component.printStruct(d+2);
		}
	}
	
}

组合模式的实现有两种形式:
(1)透明方式:Leaf类中有add()和remove()方法,如上。
(2)安全方式:基类中无add()和remove()虚方法,Leaf中也无需定义。

何时使用组合模式:需求中是体现部分与整体层次的结构时,希望用户忽略组合对象与单个对象的不同。

你可能感兴趣的:(设计模式,java,笔记)