组合模式是一种树状结构的专用模式,主要用来组合对象。它可以比较清晰的显示出部分和整体层次,因为这种模式的妙用在于整合而不是创建,因此我们常把他看做结构型模式的一种。
场景描述
某公司CEO下设有销售经理和市场经理,两个经理下各自有自己的下属员工,现遍历公司人员结构树,打印所有人员的薪资职位等状况。
代码实现
下面是改写自菜鸟教程的一段示例代码:
class Employee {
name: string;
dept: string;
salary: number;
subordinates: Array<Employee>;
constructor(name: string, dept: string, sal: number) {
this.name = name;
this.dept = dept;
this.salary = sal;
this.subordinates = [];
}
add(e: Employee): void {
this.subordinates.push(e)
}
remove(e: Employee): void {
let n = this.subordinates.indexOf(e);
this.subordinates.splice(n, -1);
}
getSubordinates(): Array<Employee> {
return this.subordinates;
}
toString(): string {
return ("Employee :[ Name : "+ this.name
+", dept : "+ this.dept + ", salary :"
+ this.salary+" ]")
}
}
let CEO:Employee = new Employee("John","CEO", 30000);
let headSales:Employee = new Employee("Robert","Head Sales", 20000);
let headMarketing:Employee = new Employee("Michel","Head Marketing", 20000);
let clerk1:Employee = new Employee("Laura","Marketing", 10000);
let clerk2:Employee = new Employee("Bob","Marketing", 10000);
let salesExecutive1:Employee = new Employee("Richard","Sales", 10000);
let salesExecutive2:Employee = new Employee("Rob","Sales", 10000);
CEO.add(headSales);
CEO.add(headMarketing);
headSales.add(salesExecutive1);
headSales.add(salesExecutive2);
headMarketing.add(clerk1);
headMarketing.add(clerk2);
//打印该组织的所有员工
console.log(CEO.toString());
for (let headEmployee of CEO.getSubordinates()) {
console.log(headEmployee.toString());
for (let employee of headEmployee.getSubordinates()) {
console.log(employee.toString());
}
}
程序运行结果:
组合模式可以将分散的数据和对象整合成整体,方便调用和扩展。组合后的对象被公共使用,因此需要按单例原则设计,保证实例唯一。开发过程中为保证安全,还需要尽量对树上不同节点的读写权限做一定的控制。