组合模式 详解
定义
将对象组合成树形结构以表示“部分-整体”的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性;
结构型模式
角色
- 抽象构件角色(Component):组合中的对象声明接口,在适当的情况下,实现所有类共有接口的默认行为。声明一个接口用于访问和管理,;
- 部分构件角色(Leaf):没有子节点,实现抽象构件角色的接口;
- 组合构件角色(Composite): 有子节点,实现抽象构件的角色声明的接口了;;
从网上找到的例图
适用场景
- 需要体现部分和整体的层次结构;
- 希望用户可以忽略组合对象和单个对象的不同,统一的使用组合结构中的所有对象时;
例子
实现代码
/**
* Created by George on 16/7/9.
*/
// 抽象化构件角色
var Commponent = function () {
this.name = null;
this.add = function (c) {
console.log("add child");
};
this.remove = function () {
console.log("remove child");
};
this.getChild = function () {
console.log("get child");
};
};
// 部分类构件角色
var Leaf = function () {
};
Leaf.prototype = new Commponent();
Leaf.prototype.add = function () {
};
Leaf.prototype.remove = function () {
};
Leaf.prototype.getChild = function () {
console.log(this.name + "执行了");
};
// 组合类构件角色
var Composite = function () {
this.list = [];
};
Composite.prototype = new Commponent();
Composite.prototype.add = function (c) {
this.list.push(c);
};
Composite.prototype.remove = function (c) {
this.list.remove(c);
};
Composite.prototype.getChild = function () {
console.log(this.name + "执行了");
for (var i = 0;i < this.list.length; i++) {
this.list[i].getChild();
}
};
// 主要实现
var root = new Composite();
root.name = "root";
var leftroot = new Composite();
leftroot.name = "leftroot";
var rightroot = new Composite();
rightroot.name = "rightroot";
var leftNode = new Leaf();
leftNode.name = "leftleaf";
var rightNode = new Leaf();
rightNode.name = "rightleaf";
leftroot.add(leftNode);
leftroot.add(rightNode);
rightroot.add(leftNode);
rightroot.add(rightNode);
root.add(leftroot);
root.add(rightroot);
root.getChild();
实现结果:
优缺点
- 调用简单,客户端可以一致的使用组合结构或其中某个对象,用户可以忽略单个对象还是组合结构;
- 容易在组合体内加入对象组件,客户端不必因为加入了新的对象组件而更改代码;
注意的是
1.部分组件和整体组件都是实现类,而不是接口,违反了依赖倒置原则;
![](https://i.loli.net/2018/11/17/5beff4d639cbb.jpg)
关注公众号:数据结构与算法那些事儿,每天一篇数据结构与算法