合成模式
合成模式属于对象的结构模式,有时又叫做部分–整体的模式。合成模式将对象组织到树结构中,可以用来描述整体与部分的关系。合成模式可以使客户端将单纯元素与复合元素同等看待 –《JAVA与模式》
合成模式定义
在电脑系统中的文件操作系统就是一种最为常见的合成模式,简单解释一下,就是如对于每一个文件它即可以代表自己,也同时持有了它的子文件的引用,当然假如一个只有一个文件也是可以单独存在的,这里我盗用一张图来简单说明一下吧
合成模式的分类
- 安全式的合成模式:所谓安全式的合成模式就是在叶子节点的和其它节点的共有的方法进行抽象,但是作为叶子节点自己单独独有的方法和其他节点独有的方法作为自己的方法来实现不对外暴露
代码如下
public interface Node { /**这是所有节点必须通用的方法*/ void print(); } public class Leaf implements Node { private String name; @Override public void print() { System.out.println("我的名称:" + name); } public String getName() { return name; } public void setName(String name) { this.name = name; } } public class Tree implements Node{ private String name; private List<Node> nodes; public boolean addNode(Node node) { if (node == null || nodes == null) { throw new NullPointerException(""); } return nodes.add(node); } public boolean removeNode(Node node) { if (node == null || nodes == null) { throw new NullPointerException(""); } return nodes.remove(node); } public List<Node> getAllChildNodes() { return nodes; } @Override public void print() { System.out.println("我是一个" + name); // 这里使用了Gson的jar包依赖,自己可以百度一下 System.out.println("整棵树打印" + new Gson().toJson(this)); } public String getName() { return name; } public void setName(String name) { this.name = name; } public List<Node> getNodes() { return nodes; } public void setNodes(List<Node> nodes) { this.nodes = nodes; } } public class Client { public static void main(String[] args) { Tree root = new Tree(); Tree leftTree = new Tree(); Tree rightTree = new Tree(); Leaf leftLeaf = new Leaf(); Leaf rightLeaf = new Leaf(); List<Node> rootChilds = new ArrayList<Node>(); List<Node> leftChilds = new ArrayList<Node>(); List<Node> rightChilds = new ArrayList<Node>(); root.setName("根节点"); root.setNodes(rootChilds); root.addNode(leftTree); root.addNode(rightTree); leftTree.setName("左子树"); leftTree.setNodes(leftChilds); leftLeaf.setName("左叶子"); leftTree.addNode(leftLeaf); rightTree.setName("右子树"); rightTree.setNodes(rightChilds); rightLeaf.setName("右叶子"); rightTree.addNode(rightLeaf); // 上面所操作构建了一个树形结构 root.print(); } }
透明式的合成模式
与安全模式唯一不同的就是,在所有具体的子类中出现的方法都必须在接口中进行进行规范化。
代码如下
public interface Node { /**打印自己*/ void print(); /**添加子节点*/ boolean addNode(Node node); /**删除子节点*/ boolean removeNode(Node node); /**获取所有子节点*/ List<Node> getAllChildNodes(); } public class Leaf implements Node { private String name; @Override public void print() { System.out.println("我是叶子节点:" + name); } @Override public boolean addNode(Node node) { throw new RuntimeException("一个叶子节点是不能添加子节点的"); } @Override public boolean removeNode(Node node) { throw new RuntimeException("一个叶子节点是不能移除子节点的"); } @Override public List<Node> getAllChildNodes() { throw new RuntimeException("一个叶子节点是不能获取所有子节点的"); } public String getName() { return name; } public void setName(String name) { this.name = name; } } public class Tree implements Node{ private String name; private List<Node> childNodes; @Override public void print() { System.out.println("我是一个" + name); // 这里使用了Gson的jar包依赖,自己可以百度一下 System.out.println("整棵树打印" + new Gson().toJson(this)); } @Override public boolean addNode(Node node) { return childNodes.add(node); } @Override public boolean removeNode(Node node) { return childNodes.remove(node); } @Override public List<Node> getAllChildNodes() { return childNodes; } public String getName() { return name; } public void setName(String name) { this.name = name; } public List<Node> getChildNodes() { return childNodes; } public void setChildNodes(List<Node> childNodes) { this.childNodes = childNodes; } } public class Client { public static void main(String[] args) { Tree root = new Tree(); Tree leftTree = new Tree(); Tree rightTree = new Tree(); Leaf leftLeaf = new Leaf(); Leaf rightLeaf = new Leaf(); List<Node> rootChilds = new ArrayList<Node>(); List<Node> leftChilds = new ArrayList<Node>(); List<Node> rightChilds = new ArrayList<Node>(); root.setName("根节点"); root.setNodes(rootChilds); root.addNode(leftTree); root.addNode(rightTree); leftTree.setName("左子树"); leftTree.setNodes(leftChilds); leftLeaf.setName("左叶子"); leftTree.addNode(leftLeaf); rightTree.setName("右子树"); rightTree.setNodes(rightChilds); rightLeaf.setName("右叶子"); rightTree.addNode(rightLeaf); // 上面所操作构建了一个树形结构 root.print(); } }
上述博客部分内容参考《JAVA与模式》之合成模式