首页 > 其他分享 >设计模式之组合模式

设计模式之组合模式

时间:2024-09-25 10:23:17浏览次数:5  
标签:name 组合 对象 Component 模式 组件 设计模式 children

组合模式

组合模式是一种结构型设计模式,用于将对象组织成树形结构以表示部分-整体的层次关系。它使得客户端可以统一地处理单个对象和组合对象。

核心概念

  1. 透明性:组合模式通过使组件的接口包含管理子部件的操作(如添加、删除等),提供了透明的操作方式。这意味着客户端无需关心它正在处理的是叶节点还是组合节点,从而简化了客户端代码。

  2. 单一职责原则:虽然在组合模式中,组件接口同时拥有管理子部件和业务方法的责任,这看似违背了单一职责原则。但实际上,它确保了组合结构的统一性,使得任何组件都可以进行类似的操作,这在很多情况下是一个权衡的结果。

  3. 安全性与透明性的权衡:在设计组合模式时,可以选择更加安全的方式,即在组件接口中不提供管理子部件的操作,只在具体的Composite类中实现这些操作。这样可以避免叶节点对象调用这些操作时出错。但这种方法牺牲了一定的透明性,因为客户端代码在调用这些管理操作之前,需要确定节点的类型。

结构组成

  • Component(抽象组件):定义了叶子和组合对象共有的接口,这包括添加、删除以及显示等操作。
  • Leaf(叶子组件):表示叶子节点对象,实现了抽象组件定义的操作,但通常不具备添加或移除子对象的功能。
  • Composite(组合组件):表示分支节点对象,拥有子节点,实现了抽象组件的接口,并持有一个或多个子部件的引用,用于管理和转发对子部件的操作请求。

应用场景

  • 当你需要表示对象的部分-整体层次结构时。
  • 当你希望用户可以忽略组合对象与单个对象的差异,统一地使用组合结构中的所有对象时。

优缺点

优点

  • 定义了包含基本对象和组合对象的类层次结构。
  • 简化了客户端代码,即客户端可以一致地使用组合结构和单个对象。
  • 更容易扩展,可以很容易地添加新的组件。

缺点

  • 可以使设计变得过于通用,有时候可能需要对这些结构进行限制,这在组合模式中不是很容易实现。

代码实践

下面是一个使用Go语言实现的组合模式的示例。在这个例子中,我们将创建一个简单的文件系统结构,其中包括文件和文件夹。文件夹可以包含其他文件夹或文件。

首先,我们定义一个抽象的组件接口 Component,它包含一个 operation 方法用于显示组件的详情。

package main

import "fmt"

// Component interface
type Component interface {
    operation()
}

// File implements Component
type File struct {
    name string
}

func (f *File) operation() {
    fmt.Println("File:", f.name)
}

// Folder implements Component and holds a slice of children Components
type Folder struct {
    name     string
    children []Component
}

func (f *Folder) operation() {
    fmt.Println("Folder:", f.name)
    for _, component := range f.children {
        component.operation()
    }
}

func (f *Folder) add(component Component) {
    f.children = append(f.children, component)
}

func (f *Folder) remove(component Component) {
    for i, child := range f.children {
        if child == component {
            f.children = append(f.children[:i], f.children[i+1:]...)
            break
        }
    }
}

// main function to use the composite pattern
func main() {
    // Create leaf nodes
    file1 := &File{name: "File1"}
    file2 := &File{name: "File2"}
    file3 := &File{name: "File3"}

    // Create composite nodes
    folder1 := &Folder{name: "Folder1"}
    folder2 := &Folder{name: "Folder2"}

    // Compose the file system structure
    folder1.add(file1)
    folder1.add(folder2)
    folder2.add(file2)
    folder2.add(file3)

    // Perform operation
    folder1.operation()
}

在这个例子中:

  • File 类型实现了 Component 接口,代表叶节点。
  • Folder 类型也实现了 Component 接口,但它还包含了一个 children 切片来存储其子节点,代表容器节点。它还提供了 addremove 方法来管理其子节点。

主函数 main 创建了几个文件和文件夹,并将它们组合成一个文件系统的层次结构。然后,它调用 folder1.operation(),这将递归地打印出所有组件的名称。

这个例子展示了如何使用组合模式来处理具有层次结构的对象,如文件和文件夹,同时保持对单个对象和组合对象的一致处理方式。

总结

组合模式提供了一种灵活的方式来组织和管理具有层次结构的对象,使得整体和部分可以被一致地处理。这种模式在需要处理树形结构的应用中特别有用,如用户界面组件、文件系统等。在设计时,应考虑如何定义组件接口以及如何管理子组件的添加和删除,以确保系统的灵活性和健壮性。

标签:name,组合,对象,Component,模式,组件,设计模式,children
From: https://www.cnblogs.com/zhifwu/p/18430816

相关文章

  • Redis实战--Redis的数据持久化与搭建Redis主从复制模式和搭建Redis的哨兵模式
            Redis作为一个高性能的key-value数据库,广泛应用于缓存、消息队列、排行榜等场景。然而,Redis是基于内存的数据库,这意味着一旦服务器宕机,内存中的数据就会丢失。为了解决这个问题,Redis提供了数据持久化的机制,包括RDB和AOF两种方式。此外,为了提高数据的可用性和可......
  • ArgoWorkflow教程(五)---Workflow 的多种触发模式:手动、定时任务与事件触发
    上一篇我们分析了argo-workflow中的archive,包括流水线GC、流水线归档、日志归档等功能。本篇主要分析Workflow中的几种触发方式,包括手动触发、定时触发、Event事件触发等。1.概述ArgoWorkflows的流水线有多种触发方式:手动触发:手动提交一个Workflow,就会触发一次构建......
  • 设计模式——观察者模式
    设计模式——观察者模式1.天气预报应用案例具体需求:气象站可以将每天测量到的温度,湿度,气压等等以公告的形式发布出去(比如发布到自己的网站或第三方)。需要设计开放型API,便于其他第三方也能接入气象站获取数据。提供温度、气压和湿度的接口测量数据更新时,要能实时的通知......
  • 计算机低能儿从0刷leetcode | 17.电话号码的数字组合 | 回溯思想
    题目:17.电话号码的字母组合解答:看题解学习到这种思想叫做回溯法,学习了一下,这是建立在DFS的基础上搜索思路,还分为递归式回溯以及非递归式回溯,这道题使用的是递归回溯。递归回溯的大致框架如下:voidDFS(inti){//搜索第i层   if(i>n){//搜索结束       ......
  • 【Linux】多线程:线程池的创建、日志类、RAII互斥锁、单例模式:饿汉方式与懒汉方式
    目录一、线程池概念二、线程的封装及线程池类成员变量的介绍 三、单例模式饿汉方式(EagerInitialization)懒汉方式(LazyInitialization)四、RAII类型的互斥锁 五、日志类的实现六、简单的任务类创建七、线程池的创建 一、线程池概念线程池(ThreadPool)是一种基于......
  • 设计模式_1_单例模式
    单例模式什么是单例设计模式单例模式是一种创建型设计模式,它的核心思想是保证一个类只有一个实例,并提供一个全局访问点来访问这个实例。只有一个实例的意思是,在整个应用程序中,只存在该类的一个实例对象,而不是创建多个相同类型的对象。全局访问点的意思是,为了让其他类能够获......
  • 【LeetCode Hot 100】17. 电话号码的字母组合
    题目描述本题需要用回溯算法遍历穷举所有可能的解。回溯算法维护一个字符串序列,记录已经有的字母排列,用一个索引值记录该字符串序列下一个将要处理的位置。每次递归将索引值加一,回溯之后将字符串序列中上次加入的字符退出序列中,枚举下一个可能的值。总的来说是一个较为基础的回溯......
  • 饿汉式懒汉式的简单实现 --单例模式001
    单例模式-设计模式--001设计模式与单例模式饿汉式懒汉式的简单实现一、饿汉式二、懒汉式设计模式与单例模式设计模式是软件开发人员在软件设计中,对常见问题的解决方案的总结和抽象。针对软件开发中常见问题和模式的通用解决方案。一种可以被重复利用的解决方案。......
  • 《程序猿之设计模式实战 · 适配器模式》
    ......
  • 设计模式之中介模式(三分钟学会一个设计模式)
    中介模式(Mediator)又称之为调停模式。mediator[ˈmiːdieɪtə(r)]n.调停者;斡旋者;解决纷争的人(或机构);本意就是解决纠纷的中间人它是面向对象六大原则中最少知道原则的一个典型应用。(关于面向对象六大原则,可看前文:https://www.cnblogs.com/jilodream/p/5353512.html)大概意......