Go和Java实现组合模式

Go和Java实现组合模式

我们通过部门和员工的层次结构的示例来演示组合模式的用法。

1、组合模式

组合模式,又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对

象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。

这种模式创建了一个包含自己对象组的类。该类提供了修改相同对象组的方式。

  • 意图:将对象组合成树形结构以表示"部分-整体"的层次结构。组合模式使得用户对单个对象和组合对象的使用

    具有一致性。

  • 主要解决:它在我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以像处理简单元素一

    样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。

  • 何时使用:1、您想表示对象的部分-整体层次结构(树形结构)。 2、您希望用户忽略组合对象与单个对象的

    不同,用户将统一地使用组合结构中的所有对象。

  • 如何解决:树枝和叶子实现统一接口,树枝内部组合该接口。

  • 关键代码:树枝内部组合该接口,并且含有内部属性 List,里面放 Component。

  • 应用实例: 1、算术表达式包括操作数、操作符和另一个操作数,其中,另一个操作数也可以是操作数、操作

    符和另一个操作数。 2、在 JAVA AWT 和 SWING 中,对于 Button 和 Checkbox 是树叶,Container 是树枝。

  • 优点:1、高层模块调用简单。 2、节点自由增加。

  • 缺点:在使用组合模式时,其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则。

  • 使用场景:部分、整体场景,如树形菜单,文件、文件夹的管理。

  • 注意事项:定义时为具体类。

  • 适用性:

    你想表示对象的部分-整体层次结构。

    你希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。

2、Go实现组合模式

go 复制代码
package composite

// ==========Employer(员工)==========
type Employer interface {
	// 新增员工
	Add(Employer)
	// 删除员工
	Delete(Employer)
	// 打印员工信息
	PrintInfo()
}
go 复制代码
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)
		}
	}
}
go 复制代码
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)
		}
	}
}
go 复制代码
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() {
}
go 复制代码
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()
}
shell 复制代码
# 输出
ProjectManager PrintInfo:
ProjectAssistant: 项目助理
Programmer: 程序员一
Programmer: 程序员二
ProjectManager PrintInfo:
ProjectAssistant: 项目助理
Programmer: 程序员一

3、Java实现组合模式

go 复制代码
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();

}
java 复制代码
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());
            }
        }
    }
}
java 复制代码
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());
            }
        }
    }
}
java 复制代码
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() {

    }
}
java 复制代码
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();
    }
}
shell 复制代码
# 输出
ProjectManager PrintInfo:
ProjectAssistant:项目助理
Programmer:程序员一
Programmer:程序员二
ProjectManager PrintInfo:
ProjectAssistant:项目助理
Programmer:程序员一
相关推荐
Damon_X11 分钟前
桥接模式(Bridge Pattern)
设计模式·桥接模式
苹果醋31 小时前
React源码02 - 基础知识 React API 一览
java·运维·spring boot·mysql·nginx
Hello.Reader1 小时前
深入解析 Apache APISIX
java·apache
菠萝蚊鸭2 小时前
Dhatim FastExcel 读写 Excel 文件
java·excel·fastexcel
旭东怪2 小时前
EasyPoi 使用$fe:模板语法生成Word动态行
java·前端·word
007php0072 小时前
Go语言zero项目部署后启动失败问题分析与解决
java·服务器·网络·python·golang·php·ai编程
∝请叫*我简单先生2 小时前
java如何使用poi-tl在word模板里渲染多张图片
java·后端·poi-tl
ssr——ssss2 小时前
SSM-期末项目 - 基于SSM的宠物信息管理系统
java·ssm
一棵星2 小时前
Java模拟Mqtt客户端连接Mqtt Broker
java·开发语言
鲤籽鲲3 小时前
C# Random 随机数 全面解析
android·java·c#