我们通过部门和员工的层次结构的示例来演示组合模式的用法。
组合模式,又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对
象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。
这种模式创建了一个包含自己对象组的类。该类提供了修改相同对象组的方式。
意图:将对象组合成树形结构以表示"部分-整体"的层次结构。组合模式使得用户对单个对象和组合对象的使用
具有一致性。
主要解决:它在我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以像处理简单元素一
样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。
何时使用:1、您想表示对象的部分-整体层次结构(树形结构)。 2、您希望用户忽略组合对象与单个对象的
不同,用户将统一地使用组合结构中的所有对象。
如何解决:树枝和叶子实现统一接口,树枝内部组合该接口。
关键代码:树枝内部组合该接口,并且含有内部属性 List,里面放 Component。
应用实例: 1、算术表达式包括操作数、操作符和另一个操作数,其中,另一个操作数也可以是操作数、操作
符和另一个操作数。 2、在 JAVA AWT 和 SWING 中,对于 Button 和 Checkbox 是树叶,Container 是树枝。
优点:1、高层模块调用简单。 2、节点自由增加。
缺点:在使用组合模式时,其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则。
使用场景:部分、整体场景,如树形菜单,文件、文件夹的管理。
注意事项:定义时为具体类。
适用性:
你想表示对象的部分-整体层次结构。
你希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。
package composite
// ==========Employer(员工)==========
type Employer interface {
// 新增员工
Add(Employer)
// 删除员工
Delete(Employer)
// 打印员工信息
PrintInfo()
}
package composite
import "fmt"
// ==========ProjectManager(项目经理)==========
type ProjectManager struct {
Name string
Employers []Employer
}
// 新增员工
func (projectManager *ProjectManager) Add(employer Employer) {
projectManager.Employers = append(projectManager.Employers, employer)
}
// 删除员工
func (projectManager *ProjectManager) Delete(employer Employer) {
for i := 0; i < len(projectManager.Employers); i++ {
if projectManager.Employers[i] == employer {
projectManager.Employers = append(projectManager.Employers[:i], projectManager.Employers[i+1:]...)
}
}
}
// 打印员工信息
func (projectManager *ProjectManager) PrintInfo() {
// 可以打印项目助理和程序员的信息
fmt.Println("ProjectManager PrintInfo:")
for _, employer := range projectManager.Employers {
switch emp := employer.(type) {
case *Programmer:
fmt.Println("Programmer:", emp.Name)
case *ProjectAssistant:
fmt.Println("ProjectAssistant:", emp.Name)
}
}
}
package composite
import "fmt"
// ==========ProjectAssistant(项目助理)==========
type ProjectAssistant struct {
Name string
Employers []Employer
}
// 新增员工
func (projectAssistant *ProjectAssistant) Add(employer Employer) {
projectAssistant.Employers = append(projectAssistant.Employers, employer)
}
// 删除员工
func (projectAssistant *ProjectAssistant) Delete(employer Employer) {
for i := 0; i < len(projectAssistant.Employers); i++ {
if projectAssistant.Employers[i] == employer {
projectAssistant.Employers = append(projectAssistant.Employers[:i], projectAssistant.Employers[i+1:]...)
}
}
}
// 打印员工信息
func (projectAssistant *ProjectAssistant) PrintInfo() {
// 可以打印程序员的信息
fmt.Println("ProjectAssistant PrintInfo:")
for _, employer := range projectAssistant.Employers {
switch emp := employer.(type) {
case *Programmer:
fmt.Println("Programmer:", emp.Name)
}
}
}
package composite
// ==========Programmer(程序员)==========
type Programmer struct {
Name string
Employers []Employer
}
// 新增员工
func (programmer *Programmer) Add(employer Employer) {
}
// 删除员工
func (programmer *Programmer) Delete(employer Employer) {
}
// 打印员工信息
func (programmer *Programmer) PrintInfo() {
}
package main
import (
. "proj/composite"
)
func main() {
// ==========项目经理==========
cpm := ProjectManager{Name: "项目经理"}
// ==========项目助理==========
cpa := &ProjectAssistant{Name: "项目助理"}
// ==========程序员一==========
cp1 := &Programmer{Name: "程序员一"}
// ==========程序员二==========
cp2 := &Programmer{Name: "程序员二"}
// 项目经理添加项目助理
cpm.Add(cpa)
// 项目经理添加程序员
cpm.Add(cp1)
cpm.Add(cp2)
cpm.PrintInfo()
// 删除程序员二
cpm.Delete(cp2)
cpm.PrintInfo()
}
# 输出
ProjectManager PrintInfo:
ProjectAssistant: 项目助理
Programmer: 程序员一
Programmer: 程序员二
ProjectManager PrintInfo:
ProjectAssistant: 项目助理
Programmer: 程序员一
package com.composite;
import java.util.List;
// ==========Employer(员工)==========
public abstract class Employer {
public String name;
public List<Employer> employers;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Employer> getEmployers() {
return employers;
}
public void setEmployers(List<Employer> employers) {
this.employers = employers;
}
// 新增员工
public void add(Employer employer) {
employers.add(employer);
}
// 删除员工
public void delete(Employer employer) {
employers.remove(employer);
}
// 打印员工信息
public abstract void printInfo();
}
package com.composite;
import java.util.ArrayList;
// ==========ProjectManager(项目经理)==========
public class ProjectManager extends Employer {
public ProjectManager(String name) {
setName(name);
employers = new ArrayList<>();
}
// 打印员工信息
@Override
public void printInfo() {
// 可以打印项目助理和程序员的信息
System.out.println("ProjectManager PrintInfo:");
for(Employer employer :employers){
if (employer instanceof ProjectAssistant){
System.out.println("ProjectAssistant:" + employer.getName());
}else if (employer instanceof Programmer){
System.out.println("Programmer:" + employer.getName());
}
}
}
}
package com.composite;
import java.util.ArrayList;
// ==========ProjectAssistant(项目助理)==========
public class ProjectAssistant extends Employer{
public ProjectAssistant(String name) {
setName(name);
//项目助理,表示没有下属了
employers = new ArrayList<>();
}
// 打印员工信息
@Override
public void printInfo() {
// 可以打印程序员的信息
System.out.println("ProjectAssistant PrintInfo:");
for(Employer employer:employers){
if (employer instanceof Programmer){
System.out.println("Programmer:" + employer.getName());
}
}
}
}
package com.composite;
// ==========Programmer(程序员)==========
public class Programmer extends Employer {
public Programmer(String name) {
setName(name);
//程序员,,表示没有下属了
employers = null;
}
// 新增员工
@Override
public void add(Employer employer) {
}
// 删除员工
@Override
public void delete(Employer employer) {
}
// 打印员工信息
@Override
public void printInfo() {
}
}
package com.composite;
public class Test {
public static void main(String[] args) {
// ==========项目经理==========
Employer pm = new ProjectManager("项目经理");
// ==========项目助理==========
Employer pa = new ProjectAssistant("项目助理");
// ==========程序员一==========
Employer programmer1 = new Programmer("程序员一");
// ==========程序员二==========
Employer programmer2 = new Programmer("程序员二");
// 项目经理添加项目助理
pm.add(pa);
// 项目经理添加程序员
pm.add(programmer1);
pm.add(programmer2);
pm.printInfo();
// 删除程序员二
pm.delete(programmer2);
pm.printInfo();
}
}
# 输出
ProjectManager PrintInfo:
ProjectAssistant:项目助理
Programmer:程序员一
Programmer:程序员二
ProjectManager PrintInfo:
ProjectAssistant:项目助理
Programmer:程序员一