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:程序员一
相关推荐
吾与谁归in18 分钟前
【C#设计模式(13)——代理模式(Proxy Pattern)】
设计模式·c#·代理模式
吾与谁归in19 分钟前
【C#设计模式(14)——责任链模式( Chain-of-responsibility Pattern)】
设计模式·c#·责任链模式
闲人一枚(学习中)27 分钟前
设计模式-创建型-原型模式
设计模式
ifanatic41 分钟前
[面试]-golang基础面试题总结
面试·职场和发展·golang
儿时可乖了1 小时前
使用 Java 操作 SQLite 数据库
java·数据库·sqlite
ruleslol1 小时前
java基础概念37:正则表达式2-爬虫
java
懒是一种态度1 小时前
Golang 调用 mongodb 的函数
数据库·mongodb·golang
Iced_Sheep1 小时前
干掉 if else 之策略模式
后端·设计模式