Golang如何使用中介者模式协调多对象交互

中介者模式通过引入协调者集中管理对象交互,降低多对象间的直接耦合。在Go中,定义Mediator接口和具体中介者(如ChatRoom)来封装通信逻辑,同事对象(如User)仅持有中介者引用,通过其转发消息。示例中多个用户通过聊天室发送消息,避免了彼此直接依赖,适用于复杂交互场景,提升系统可维护性和扩展性。

golang如何使用中介者模式协调多对象交互

在Go语言中,中介者模式能有效降低多个对象之间的直接耦合。当多个组件需要频繁通信时,如果让它们彼此持有引用,会导致结构混乱、难以维护。中介者模式通过引入一个“协调者”来集中管理交互逻辑,使对象之间不再互相依赖,而是通过中介者进行通信。

什么是中介者模式

中介者模式(Mediator Pattern)是一种行为型设计模式,它用一个中介对象封装一系列对象之间的交互。对象之间不直接引用彼此,而是通过中介者进行消息传递,从而降低系统的耦合度。

这种模式特别适用于多个对象之间存在复杂交互的场景,比如聊天室、GUI组件联动、游戏中的角色与系统通信等。

Go中实现中介者模式的关键结构

在Go中实现中介者模式,通常包括以下几个部分:

立即学习“go语言免费学习笔记(深入)”;

Mediator接口:定义对象间通信的方法,如发送消息、注册参与者等。 ConcreteMediator:具体中介者,管理所有参与对象的引用,并实现协调逻辑。 Colleague(同事对象):各个参与交互的对象,它们只持有中介者的引用,不直接与其他同事通信。

下面是一个简单的聊天室示例,展示如何使用中介者模式协调多个用户的消息发送与接收。

// Mediator 接口

type Mediator interface {
  Send(message string, sender User)
}

// 用户结构体(同事对象)

type User struct {
  name    string
  mediator Mediator
}

func (u *User) Send(message string) {
  fmt.Printf(“%s 发送消息: %sn”, u.name, message)
  u.mediator.Send(message, *u)
}

func (u *User) Receive(message, senderName string) {
  fmt.Printf(“%s 收到 %s 的消息: %sn”, u.name, senderName, message)
}

// 聊天室作为具体中介者

type ChatRoom struct {
  users map[string]*User
}

func NewChatRoom() *ChatRoom {
  return &ChatRoom{users: make(map[string]*User)}
}

func (c *ChatRoom) Register(user *User) {
  user.mediator = c
  c.users[user.name] = user
}

func (c *ChatRoom) Send(message string, sender User) {
  for name, user := range c.users {
    if name != sender.name {
      user.Receive(message, sender.name)
    }
  }
}

// 使用示例

func main() {
  chatRoom := NewChatRoom()

  alice := &User{name: “Alice”}
  bob := &User{name: “Bob”}
  charlie := &User{name: “Charlie”}

  chatRoom.Register(alice)
  chatRoom.Register(bob)
  chatRoom.Register(charlie)

  alice.Send(“大家好!”)
  bob.Send(“Alice,你好!”)
}

适用场景与优势

中介者模式适合以下情况:

多个对象之间交互逻辑复杂,导致相互依赖严重。 希望将控制逻辑集中在一个地方,便于维护和扩展。 需要动态地启用或禁用某些交互行为。

优点包括:

减少子对象间的直接耦合,提升模块独立性。 将多对多的通信关系简化为一对多,结构更清晰。 便于测试,可以单独测试中介者或同事对象。

需要注意的是,中介者本身可能变得过于复杂,变成“上帝对象”。因此应合理划分职责,必要时可拆分中介者功能。

基本上就这些。用好中介者模式,能让Go项目中的协作逻辑更清晰,也更容易应对变化。

以上就是Golang如何使用中介者模式协调多对象交互的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1415055.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月16日 09:17:35
下一篇 2025年12月16日 09:17:56

相关推荐

  • XSLT如何实现模板重写?

    XSLT模板重写通过xsl:import和xsl:apply-imports实现,导入样式表的模板优先级高于被导入的样式表,从而允许覆盖或扩展基础模板;xsl:apply-imports可在重写模板中调用原模板逻辑,实现增量定制;结合导入优先级、模式匹配、特异性和文档顺序,可构建模块化、可维护的分层…

    2025年12月17日
    000
  • XSLT扩展函数如何自定义使用?

    XSLT扩展函数通过集成外部编程语言(如Java)弥补了XSLT内置功能的不足,允许执行复杂逻辑、文件操作、数据库访问等。其实现需三步:编写外部代码(如Java静态方法)、在XSLT中声明命名空间(如xmlns:my-ext=”java:com.example.StringUtils&#…

    2025年12月17日
    000
  • XSLT如何控制模板应用顺序?

    XSLT模板应用顺序由导入优先级、模式特异性、priority属性和文档顺序共同决定,其中导入的样式表优先级最低,模式越具体优先级越高,priority值越大优先级越高,最后通过mode实现多上下文独立匹配。 XSLT处理模板应用顺序,核心在于一套明确的优先级规则。它不是随机的,而是基于模板匹配模式…

    2025年12月17日
    000
  • XSLT如何动态选择模板应用?

    XSLT通过xsl:apply-templates的select属性实现节点的动态筛选,结合xsl:choose条件判断和mode模式切换,可在不同上下文中灵活选择模板,支持基于内容、属性或多视图需求的复杂转换,提升复用性与可维护性。 by 作者: 目录 <!– –&g…

    2025年12月17日
    000
  • XSLT如何对节点进行分组操作?

    XSLT分组主要有两种方式:XSLT 2.0+使用for-each-group指令,通过group-by等属性实现直观高效的分组;XSLT 1.0则依赖Muenchian Grouping,利用key()和generate-id()筛选每组首个节点,虽复杂但有效。 <xsl:for-each-…

    2025年12月17日
    000
  • XSLT如何避免重复代码编写?

    XSLT通过模板、模式和模块化解决XML转换中的重复问题:利用match实现结构匹配复用,mode分离不同输出场景的处理逻辑,具名模板封装通用函数,import/include机制支持代码复用与扩展,从而构建高效、可维护的转换系统。 ID: (ID: ) 然后,你可以通过 xsl:apply-tem…

    2025年12月17日
    000
  • XSLT模板优先级如何确定?

    XSLT模板优先级由match表达式特异性、priority属性值和导入顺序决定,特异性越高优先级越高,相同则比较priority数值,最后看xsl:import顺序,后导入的优先。 在这种情况下, main.xsl 中的 book 模板会覆盖 common.xsl 中的 book 模板。这是一种非…

    2025年12月17日
    000
  • XSLT如何定义十进制格式?

    答案:XSLT通过xsl:decimal-format定义数字格式规则,并用format-number()函数引用规则来格式化数值,支持小数点、千位分隔符、负号、特殊值等的自定义,适用于多语言和业务场景。 pattern-separator : 这个属性定义了在 format-number() 的 …

    2025年12月17日
    000
  • XSLT如何导入和包含其他样式表?

    XSLT中与的本质区别在于:支持优先级覆盖,用于扩展和定制基础样式表,导入的样式表中同名模板可被当前样式表覆盖;而是内容合并,无优先级,仅将外部样式表内容直接嵌入,同名元素会导致冲突错误。两者均需作为顶层元素使用,合理选择可提升代码模块化、可维护性与复用性。 XSLT中要导入和包含其他样式表,主要依…

    2025年12月17日
    000
  • XSLT如何输出XML声明?

    XSLT通过xsl:output元素控制XML声明输出,核心属性包括omit-xml-declaration、method、version、encoding和indent;其中omit-xml-declaration=”no”可确保声明输出,encoding建议设为UTF-8…

    2025年12月17日
    000
  • XPath的innermost()函数选择什么节点?

    innermost()函数筛选出节点集合中非其他节点祖先的最深层节点,用于精准定位层级结构中的最细粒度元素,常见于Saxon等扩展XPath环境,非标准函数故不普遍;其逻辑可通过谓词如$nodes[not(some $desc in $nodes satisfies . >> $desc…

    2025年12月17日
    000
  • XPath的.语法代表当前节点吗?

    .在XPath中代表当前上下文节点,用于基于当前位置进行相对路径导航,可明确指向当前元素以实现精准定位,常用于相对路径、谓语条件判断、函数参数中,如./span表示当前节点下的span子元素,//div[./@id=’main’]表示id属性为main的div,string(…

    2025年12月17日
    000
  • XPath的static-base-uri()函数获取什么?

    static-base-uri()函数为空的情况主要有:XPath表达式在代码中以字符串形式直接定义时,因无关联资源地址而返回空;动态生成的XPath表达式若生成上下文未提供基URI信息,则结果为空;某些XPath引擎实现不完整或未支持该函数时也可能返回空;尽管未声明命名空间不直接导致其为空,但可能…

    2025年12月17日
    000
  • XPath的parse-xml()函数如何解析字符串?

    parse-xml()函数的作用是将XML格式的字符串解析为XPath可操作的文档节点,使其能被路径表达式查询。例如,调用parse-xml($myXmlString)//item[name=’产品甲’]/price/@currency可从解析后的节点树中提取指定数据。该函数…

    2025年12月17日
    000
  • XPath的..语法如何选择父节点?

    ..的核心作用是选中当前节点的直接父节点,如//span/..可选中span的父节点li,连续使用可向上多级跳跃,常用于灵活定位。 XPath中那个看似简单的 .. 语法,其核心作用就是让你从当前所在的节点,向上一步,准确无误地选中它的直接父节点。这在处理XML或HTML文档时,简直是家常便饭,而且…

    2025年12月17日
    000
  • XPath的string-length()函数计算什么?

    string-length()函数用于计算字符串字符数,包括空格和特殊字符,支持Unicode,常用于数据验证、字符串截取、条件判断等场景。 XPath的 string-length() 函数,顾名思义,是用来计算字符串长度的。它会返回一个字符串中字符的数量,这个数量包括空格和其他特殊字符。简单来说…

    2025年12月17日
    000
  • XPath的available-environment-variables()?

    available-environment-variables()是Saxon扩展函数,非XPath标准,用于获取环境变量名序列,需结合system-property()获取值,使用时需注意安全风险并限制访问权限。 JAVA_HOME environment variable is not set.…

    2025年12月17日
    000
  • XPath的outermost()函数处理什么节点?

    outermost()函数用于筛选节点序列中最外层的节点,即移除被其他选中节点包含的后代节点,保留不被包含的祖先节点。例如在表达式outermost(//section | //p)中,若包含,则只保留和未被包含的,结果为和。与innermost()相反,后者保留最内层节点。outermost()适…

    2025年12月17日
    000
  • XML的DTD实体注入攻击怎么防范?解析时要注意什么?

    防范XML的DTD实体注入攻击最核心的策略是禁用外部实体解析。具体做法包括在XML解析器中关闭外部实体加载功能,如Java中通过设置SAXParserFactory和DocumentBuilderFactory的特性禁用外部实体、PHP中使用LIBXML_NOENT和LIBXML_NONET选项、P…

    2025年12月17日
    000
  • XPath的ancestor-or-self轴包含当前节点吗?

    是的,XPath的ancestor-or-self轴包含当前节点,它与ancestor轴的核心区别在于前者包含自身而后者仅包含祖先节点。当从一个节点出发时,ancestor-or-self会返回该节点及其所有祖先,适用于需要同时检查当前节点和上级节点的场景,如查找具有特定属性的最近容器、判断权限继承…

    2025年12月17日
    000

发表回复

登录后才能评论
关注微信