Go和Java实现组合模式
我们通过部门和员工的层次结构的示例来演示组合模式的用法。
1、组合模式
组合模式,又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对
象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。
这种模式创建了一个包含自己对象组的类。该类提供了修改相同对象组的方式。
-
意图:将对象组合成树形结构以表示"部分-整体"的层次结构。组合模式使得用户对单个对象和组合对象的使用
具有一致性。
-
主要解决:它在我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以像处理简单元素一
样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。
-
何时使用:1、您想表示对象的部分-整体层次结构(树形结构)。 2、您希望用户忽略组合对象与单个对象的
不同,用户将统一地使用组合结构中的所有对象。
-
如何解决:树枝和叶子实现统一接口,树枝内部组合该接口。
-
关键代码:树枝内部组合该接口,并且含有内部属性 List,里面放 Component。
-
应用实例: 1、算术表达式包括操作数、操作符和另一个操作数,其中,另一个操作数也可以是操作数、操作
符和另一个操作数。 2、在 JAVA AWT 和 SWING 中,对于 Button 和 Checkbox 是树叶,Container 是树枝。
-
优点:1、高层模块调用简单。 2、节点自由增加。
-
缺点:在使用组合模式时,其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则。
-
使用场景:部分、整体场景,如树形菜单,文件、文件夹的管理。
-
注意事项:定义时为具体类。
-
适用性:
你想表示对象的部分-整体层次结构。
你希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。
2、Go实现组合模式
package composite// ==========Employer(员工)==========
type Employer interface {// 新增员工Add(Employer)// 删除员工Delete(Employer)// 打印员工信息PrintInfo()
}
package compositeimport "fmt"// ==========ProjectManager(项目经理)==========
type ProjectManager struct {Name stringEmployers []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 compositeimport "fmt"// ==========ProjectAssistant(项目助理)==========
type ProjectAssistant struct {Name stringEmployers []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 stringEmployers []Employer
}// 新增员工
func (programmer *Programmer) Add(employer Employer) {
}// 删除员工
func (programmer *Programmer) Delete(employer Employer) {
}// 打印员工信息
func (programmer *Programmer) PrintInfo() {
}
package mainimport (. "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: 程序员一
3、Java实现组合模式
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<>();}// 打印员工信息@Overridepublic 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<>();}// 打印员工信息@Overridepublic 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;}// 新增员工@Overridepublic void add(Employer employer) {}// 删除员工@Overridepublic void delete(Employer employer) {}// 打印员工信息@Overridepublic 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:程序员一