`
huhu_long
  • 浏览: 69084 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

组合模式

 
阅读更多
Compose objects into TREE structures...
所以当碰到树形结构时, 我们就应该考虑是否可以用Composite模式。

下面我们以一般网站的导航栏来做介绍。
没个Item都对应一个节点, 节点存储了导航的URL

组合模式又分为:
。安全模式
。透明模式

那么先来看看安全模式是怎样滴。

定义一个Node抽象类, 灰常简单, 暴露两个属性
public abstract class Node {
	private String name;
	private String url;

	public String getName() {
		return name;
	}

	public String getUrl() {
		return url;
	}

	public Node(String name, String url) {
		this.name = name;
		this.url = url;
	}
}


然后是叶子节点, 叶子节点没有Child, 所以直接从Node继承过来, 不需要修改
public class Leaf extends Node {

	public Leaf(String name, String url) {
		super(name, url);
	}
}


再就是分支节点了
public class Branch extends Node {

	// children 里面的元素有可能是 Branch, 也有可能是 Leaf
	private List<Node> children = new ArrayList<Node>();

	public Branch(String name, String url) {
		super(name, url);
	}

	public void addChild(Node node) {
		this.children.add(node);
	}

	public void removeChild(Node node) {
		if (this.children.contains(node))
			this.children.remove(node);
	}

	public List<Node> getChildren() {
		return this.children;
	}
}


好啦, 看看客户端代码吧:
public class Client {
	public static void main(String[] args) {
		Node tree = buildTree();

		printTreeInfo(tree);
	}

	private static Node buildTree() {
		Branch root = new Branch("root", "/root");

		root.addChild(new Leaf("level1-1", "/level1-1"));
		root.addChild(new Leaf("level1-2", "/level1-2"));

		Branch level1 = new Branch("level1-3", "/level1-3");
		level1.addChild(new Leaf("level1-3-2-1", "/level1-3-2-1"));
		level1.addChild(new Leaf("level1-3-2-2", "/level1-3-2-2"));

		root.addChild(level1);

		return root;
	}

	@SuppressWarnings("unchecked")
	private static void printTreeInfo(Node tree) {
		if (tree instanceof Leaf) {
			System.out.println("Name = " + tree.getName() + "; URL = "
					+ tree.getUrl());
		} else {
			System.out.println("Name = " + tree.getName() + "; URL = "
					+ tree.getUrl());
			List<Node> children = ((Branch) tree).getChildren();
			Iterator iter = children.iterator();
			while (iter.hasNext()) {
				printTreeInfo((Node) iter.next());
			}
		}
	}
}


执行结果如下:
引用
Name = root; URL = /root
Name = level1-1; URL = /level1-1
Name = level1-2; URL = /level1-2
Name = level1-3; URL = /level1-3
Name = level1-3-2-1; URL = /level1-3-2-1
Name = level1-3-2-2; URL = /level1-3-2-2


介绍完了安全模式, 再来看看透明模式
那本例来说, 所谓透明模式, 其实就是把Branch里面的add, remove, getChildre方法移到Node类里面去, 然后在客户端代码不需要进行类型的强制转换。

Node类改动比较大
public abstract class Node {
	private String name;
	private String url;

	// children 里面的元素有可能是 Branch, 也有可能是 Leaf
	private List<Node> children = new ArrayList<Node>();

	public String getName() {
		return name;
	}

	public String getUrl() {
		return url;
	}

	public Node(String name, String url) {
		this.name = name;
		this.url = url;
	}

	public void addChild(Node node) {
		this.children.add(node);
	}

	public void removeChild(Node node) {
		if (this.children.contains(node))
			this.children.remove(node);
	}

	public List<Node> getChildren() {
		return this.children;
	}
}


Leaf类比支持add, remove, getChildre方法, 应该明确出来
public class Leaf extends Node {

	public Leaf(String name, String url) {
		super(name, url);
	}

	@Override
	@Deprecated
	public void addChild(Node node) {
		throw new UnsupportedOperationException();
	}

	@Override
	@Deprecated
	public List<Node> getChildren() {
		throw new UnsupportedOperationException();
	}

	@Override
	@Deprecated
	public void removeChild(Node node) {
		throw new UnsupportedOperationException();
	}
}


Branch类得到了简化
public class Branch extends Node {

	public Branch(String name, String url) {
		super(name, url);
	}
}


客户端唯一不同的地方就是用超类申明, 并且不用强制转换
Node root = new Branch("root", "/root");

Node level1 = new Branch("level1-3", "/level1-3");

List<Node> children = tree.getChildren();


最后来看看执行结果, 和安全模式也是一样滴
引用
Name = root; URL = /root
Name = level1-1; URL = /level1-1
Name = level1-2; URL = /level1-2
Name = level1-3; URL = /level1-3
Name = level1-3-2-1; URL = /level1-3-2-1
Name = level1-3-2-2; URL = /level1-3-2-2
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics