找回密码
 立即注册
首页 业界区 业界 【中介者设计模式详解】C/Java/JS/Go/Python/TS不同语言 ...

【中介者设计模式详解】C/Java/JS/Go/Python/TS不同语言实现

届表 2025-6-6 09:45:24
简介

中介者模式(Mediator Pattern)是一种行为型模式。它限制对象之间的直接交互,它用一个中介对象来封装一系列的动作,以让对象之间进行交流。中介者使各个对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
当一些对象和其他对象紧密耦合以致难以对其进行修改时,或当组件因过于依赖其他组件而无法在不同应用中复用时,可使用中介者模式。
 
作用


  • 用来降低多个对象和类之间的通信复杂性。
  • 对象之间不再显式地相互引用,但可以独立地改变它们之间的交互,从而保持松耦合。
 
实现步骤


  • 定义一个工具接口,供不同工具类来实现。建立多个具体工具类实现基础工具接口。
  • 定义一个基础抽象类,里面聚合了工具接口,相当于桥接。
  • 再重新定义一个新抽象类,继承自基础抽象类,并补充一些方法。
  • 建立具体对象类继承新抽象类,调用桥接接口里的方法来实现功能。
 
UML

1.png
 
 Java代码

 
中介者抽象接口
  1. // RoomMediator.java 定义中介者接口或抽象类
  2. public interface RoomMediator {
  3.    public void register(AbstractUser user);
  4.    public void sendTo(AbstractUser from, AbstractUser to, String message);
  5.    public void send(AbstractUser from, String message);
  6. }
复制代码
 
 
通用中介者

 
  1. // GeneralRoom.java 中介者的具体实现类
  2. public class GeneralRoom implements RoomMediator {
  3.    public List users = new ArrayList();
  4.    @Override
  5.    public void register(AbstractUser user) {
  6.       // 用户注册登记,追加用户列表
  7.       user.setRoomMediator(this);
  8.       users.add(user);
  9.    }
  10.    // 作为中介者通知给某个用户
  11.    @Override
  12.    public void sendTo(AbstractUser from, AbstractUser to, String message) {
  13.       System.out.println(
  14.             "GeneralRoom:sendTo() [from: " + from.getName() + " message: " + message + " to: " + to.getName() + " ]");
  15.       // 根据用户名称定向发送
  16.       to.recieve(from, message);
  17.    }
  18.    // 作为中介者通知给全体用户
  19.    @Override
  20.    public void send(AbstractUser from, String message) {
  21.       System.out.println("GeneralRoom:send() [from: " + from.getName() + " message: " + message + "]");
  22.       for (AbstractUser user : users) {
  23.          user.recieve(from, message);
  24.       }
  25.    }
  26. }
复制代码
 
抽象用户类

 
  1. // AbstractUser.java 定义抽象用户类,聚合中介者
  2. public abstract class AbstractUser {
  3.    private String name;
  4.    public RoomMediator roomMediator;
  5.    public AbstractUser(String name) {
  6.       this.name = name;
  7.    }
  8.    public void setRoomMediator(RoomMediator roomMediator) {
  9.       this.roomMediator = roomMediator;
  10.    }
  11.    public abstract void send(String message);
  12.    public abstract void sendTo(AbstractUser to, String message);
  13.    public abstract void recieve(AbstractUser from, String message);
  14.    public String getName() {
  15.       return this.name;
  16.    }
  17. }
复制代码
 
 
具体用户对象

 
  1. // CommonUser.java 普通用户继承了抽象用户,实现了具体功能
  2. public class CommonUser extends AbstractUser {
  3.    public CommonUser(String name) {
  4.       super(name);
  5.    }
  6.    @Override
  7.    public void send(String message) {
  8.       System.out.println("CommonUser:send() [user: " + this.getName() + " message:" + message + "]");
  9.       // 通过中介者来中转消息
  10.       this.roomMediator.send(this, message);
  11.    }
  12.    @Override
  13.    public void sendTo(AbstractUser to, String message) {
  14.       System.out.println("CommonUser:sendTo() [user: " + this.getName() + " message:" + message + " to: " + to.getName() + "]");
  15.       // 通过中介者来中转消息
  16.       this.roomMediator.sendTo(this, to, message);
  17.    }
  18.    @Override
  19.    public void recieve(AbstractUser from, String message) {
  20.       System.out.println("CommonUser:recieve() [user: " + this.getName() + " message: " + message + " from:" + from.getName() + "]");
  21.    }
  22. }
复制代码
 
  1. // MemberUser.java 会员用户继承了抽象用户,实现了具体功能
  2. public class MemberUser extends AbstractUser {
  3.    public MemberUser(String name) {
  4.       super(name);
  5.    }
  6.    @Override
  7.    public void send(String message) {
  8.       System.out.println("MemberUser:send() [user: " + this.getName() + " message:" + message + "]");
  9.       // 通过中介者来中转消息
  10.       this.roomMediator.send(this, message);
  11.    }
  12.    @Override
  13.    public void sendTo(AbstractUser to, String message) {
  14.       System.out
  15.             .println("MemberUser:sendTo() [user: " + this.getName() + " message:" + message + " to: " + to.getName() + "]");
  16.       // 通过中介者来中转消息
  17.       this.roomMediator.sendTo(this, to, message);
  18.    }
  19.    @Override
  20.    public void recieve(AbstractUser from, String message) {
  21.       System.out.println("MemberUser:recieve() [user: " + this.getName() + " message: " + message
  22.             + " from user:" + from.getName() + "]");
  23.    }
  24. }
复制代码
 
  1.  
复制代码
测试调用

 
  1. public class Test {
  2.   public static void start() {
  3.   /**
  4.    * 中介者模式用一个中介对象来封装一系列动作,让对象之间利用中介者来交流。
  5.    * 这里聊天室就是一个中介者,用户和用户之间的消息传递,全部依靠聊天室来完成。
  6.    * 先给聊天室注册用户,也给用户绑定上中介者,双方彼此持有关系。
  7.    * 中介者的成员之间的消息传递通过中介者来代理传达。
  8.    */
  9.     // 声明一个聊天室
  10.     GeneralRoom generalRoom = new GeneralRoom();
  11.     // 给聊天室添加点不同的人
  12.     AbstractUser user1 = new CommonUser("user1");
  13.     generalRoom.register(user1);
  14.     CommonUser user2 = new CommonUser("user2");
  15.     generalRoom.register(user2);
  16.     MemberUser user3 = new MemberUser("user3");
  17.     generalRoom.register(user3);
  18.     // user1 发送给全体
  19.     user1.send("hi, I'm " + user1.getName() + ".");
  20.     // user2 发送给 user3
  21.     user2.sendTo(user3, "haha.");
  22.   }
  23.   public static void main(String[] args) {
  24.     System.out.println("test start:");
  25.     start();
  26.   }
  27. }
复制代码
 
Go代码

 
中介者抽象接口
  1. // RoomMediator.go 定义中介者接口或抽象类
  2. type RoomMediator interface {
  3.   Register(user AbstractUser)
  4.   SendTo(from AbstractUser, to AbstractUser, message string)
  5.   Send(from AbstractUser, message string)
  6. }
复制代码
 
 
通用中介者

 
  1. // GeneralRoom.go 中介者的具体实现类
  2. type GeneralRoom struct {
  3.   users []AbstractUser
  4. }
  5. func (g *GeneralRoom) Register(user AbstractUser) {
  6.   // 用户注册登记,追加用户列表
  7.   user.SetRoomMediator(g)
  8.   g.users = append(g.users, user)
  9. }
  10. // 作为中介者通知给某个用户
  11. func (g *GeneralRoom) SendTo(from AbstractUser, to AbstractUser, message string) {
  12.   fmt.Println("GeneralRoom::SendTo() [from: " + from.GetName() + " message: " + message + " to: " + to.GetName() + "]")
  13.   // 定向发送给某个用户,名称唯一
  14.   to.Recieve(from, message)
  15. }
  16. // 作为中介者通知给全体用户
  17. func (g *GeneralRoom) Send(from AbstractUser, message string) {
  18.   fmt.Println("GeneralRoom::Send() [from: " + from.GetName() + " message: " + message + "] ")
  19.   for _, user := range g.users {
  20.     user.Recieve(from, message)
  21.   }
  22. }
复制代码
 
 
抽象用户类
  1. // AbstractUser.go 定义抽象用户类,聚合中介者
  2. type AbstractUser interface {
  3.   SetRoomMediator(roomMediator RoomMediator)
  4.   Send(message string)
  5.   SendTo(to AbstractUser, message string)
  6.   Recieve(from AbstractUser, message string)
  7.   GetName() string
  8. }
复制代码
 
 
具体用户对象

 
  1. // CommonUser.go 普通用户继承了抽象用户,实现了具体功能
  2. type CommonUser struct {
  3.   Name         string
  4.   roomMediator RoomMediator
  5. }
  6. func (c *CommonUser) SetRoomMediator(roomMediator RoomMediator) {
  7.   c.roomMediator = roomMediator
  8. }
  9. func (c *CommonUser) Send(message string) {
  10.   fmt.Println("CommonUser:Send() [user: " + c.GetName() + " message: " + message + "]")
  11.   // 通过中介者来中转消息
  12.   c.roomMediator.Send(c, message)
  13. }
  14. func (c *CommonUser) SendTo(to AbstractUser, message string) {
  15.   fmt.Println("CommonUser:SendTo() [user: " + c.GetName() + " message: " + message + "]")
  16.   // 通过中介者来中转消息
  17.   c.roomMediator.SendTo(c, to, message)
  18. }
  19. func (c *CommonUser) Recieve(from AbstractUser, message string) {
  20.   fmt.Println("CommonUser:Recieve() [user: " + c.GetName() + " message: " + message + " from: " + from.GetName() + "]")
  21. }
  22. func (c *CommonUser) SetName(name string) {
  23.   c.Name = name
  24. }
  25. func (c *CommonUser) GetName() string {
  26.   return c.Name
  27. }
复制代码
 
 
  1. // MemberUser.go 会员用户继承了抽象用户,实现了具体功能
  2. type MemberUser struct {
  3.   // Name首字母大写以便跨模块访问
  4.   Name         string
  5.   roomMediator RoomMediator
  6. }
  7. func (c *MemberUser) SetRoomMediator(roomMediator RoomMediator) {
  8.   c.roomMediator = roomMediator
  9. }
  10. func (c *MemberUser) Send(message string) {
  11.   fmt.Println("MemberUser:Send() [user: " + c.GetName() + " message: " + message + "]")
  12.   // 通过中介者来中转消息
  13.   c.roomMediator.Send(c, message)
  14. }
  15. func (c *MemberUser) SendTo(to AbstractUser, message string) {
  16.   fmt.Println("MemberUser:SendTo() [user: " + c.GetName() + " message: " + message + "]")
  17.   // 通过中介者来中转消息
  18.   c.roomMediator.SendTo(c, to, message)
  19. }
  20. func (c *MemberUser) Recieve(from AbstractUser, message string) {
  21.   fmt.Println("MemberUser:Recieve() [user: " + c.GetName() + " message: " + message + " from: " + from.GetName() + "]")
  22. }
  23. func (c *MemberUser) SetName(name string) {
  24.   c.Name = name
  25. }
  26. func (c *MemberUser) GetName() string {
  27.   return c.Name
  28. }
复制代码
 
 
测试调用

 
  1. func main() {
  2.   fmt.Println("test start:")
  3.   /**
  4.    * 中介者模式用一个中介对象来封装一系列动作,让对象之间利用中介者来交流。
  5.    * 这里聊天室就是一个中介者,用户和用户之间的消息传递,全部依靠聊天室来完成。
  6.    * 先给聊天室注册用户,也给用户绑定上中介者,双方彼此持有关系。
  7.    * 中介者的成员之间的消息传递通过中介者来代理传达。
  8.    */
  9.   // 声明一个聊天室
  10.   var generalRoom = new(src.GeneralRoom)
  11.   // 给聊天室添加点不同的人
  12.   var user1 = &src.CommonUser{
  13.     Name: "user1",
  14.   }
  15.   generalRoom.Register(user1)
  16.   var user2 = &src.CommonUser{
  17.     Name: "user2",
  18.   }
  19.   generalRoom.Register(user2)
  20.   var user3 = &src.MemberUser{
  21.     Name: "user3",
  22.   }
  23.   generalRoom.Register(user3)
  24.   // user1 发送给全体
  25.   user1.Send("hi, I'm " + user1.GetName() + ".")
  26.   // user2 发送给 user3
  27.   user2.SendTo(user3, "haha.")
  28. }
复制代码
 
 
C语言简版

 
  1. #include <stdio.h>
  2. /**
  3. * 中介者模式是一种行为型设计模式,它可以用来减少类之间的直接依赖关系,
  4. * 将对象之间的通信封装到一个中介者对象中,从而使得各个对象之间的关系更加松散。
  5. * 在中介者模式中,对象之间不再直接相互交互,而是通过中介者来中转消息。
  6. */
  7. typedef struct Colleague Colleague;
  8. typedef struct Mediator Mediator;
  9. // 定义抽象交互对象类
  10. struct Colleague
  11. {
  12.   int id;
  13.   struct Mediator *mediator;
  14.   void (*send)(struct Colleague *sender, char *message);
  15.   void (*send_to)(struct Colleague *sender, Colleague *receiver, char *message);
  16.   void (*receive)(struct Colleague *receiver, Colleague *sender, char *message);
  17. };
  18. // 定义中介者类
  19. struct Mediator
  20. {
  21.   struct Colleague **colleagues;
  22.   int colleagues_length;
  23.   void (*send)(Colleague *sender, char *message);
  24.   void (*send_to)(Colleague *sender, Colleague *receiver, char *message);
  25. };
  26. // 交互对象发送消息
  27. void colleague_send(Colleague *sender, char *message)
  28. {
  29.   printf("\r\n colleague_send() [sender->id=%d message=%s]", sender->id, message);
  30.   Mediator *mediator = sender->mediator;
  31.   // 由中介者代为转发消息给全体接收者
  32.   mediator->send(sender, message);
  33. }
  34. // 交互对象发送消息
  35. void colleague_send_to(Colleague *sender, Colleague *receiver, char *message)
  36. {
  37.   printf("\r\n colleague_send_to() [sender->id=%d receiver->id=%d message=%s]", sender->id, receiver->id, message);
  38.   Mediator *mediator = sender->mediator;
  39.   // 由中介者代为转发消息给指定接收者
  40.   mediator->send_to(sender, receiver, message);
  41. }
  42. // 对象接收消息
  43. void colleague_receive(Colleague *receiver, Colleague *sender, char *message)
  44. {
  45.   printf("\r\n colleague_receive() [receiver->id=%d send->id=%d message=%s]", receiver->id, sender->id, message);
  46. }
  47. // 中介者发送消息
  48. void mediator_send(Colleague *sender, char *message)
  49. {
  50.   printf("\r\n mediator_send() [sender->id=%d message=%s]", sender->id, message);
  51.   Colleague *receiver;
  52.   for (int i = 0; i < sender->mediator->colleagues_length; i++)
  53.   {
  54.     // 中介者通知全体接收者
  55.     receiver = sender->mediator->colleagues[i];
  56.     receiver->receive(receiver, sender, message);
  57.   }
  58. }
  59. // 中介者发送消息
  60. void mediator_send_to(Colleague *sender, Colleague *receiver, char *message)
  61. {
  62.   // 中介者通知指定接收者
  63.   printf("\r\n mediator_send_to() [sender->id=%d receiver->id=%d message=%s]", sender->id, receiver->id, message);
  64.   receiver->receive(receiver, sender, message);
  65. }
  66. // 初始化交互对象类
  67. void colleague_constructor(Colleague *self, int id)
  68. {
  69.   self->id = id;
  70.   self->send = colleague_send;
  71.   self->send_to = colleague_send_to;
  72.   self->receive = colleague_receive;
  73. }
  74. // 初始化中介者类
  75. void mediator_constructor(Mediator *self, Colleague **colleagues, int colleagues_length)
  76. {
  77.   self->colleagues = colleagues;
  78.   self->colleagues_length = colleagues_length;
  79.   // 给每个对象绑定中介者
  80.   for (int i = 0; i < self->colleagues_length; i++)
  81.   {
  82.     self->colleagues[i]->mediator = self;
  83.   }
  84.   self->send = &mediator_send;
  85.   self->send_to = &mediator_send_to;
  86. }
  87. // test
  88. int main()
  89. {
  90.   // 初始化具体交互对象a,分别绑定相关函数
  91.   Colleague colleague_a;
  92.   colleague_constructor(&colleague_a, 1);
  93.   // 初始化具体交互对象b,分别绑定相关函数
  94.   Colleague colleague_b;
  95.   colleague_constructor(&colleague_b, 2);
  96.   // 定义交互对象数组
  97.   Colleague *colleagues[] = {&colleague_a, &colleague_b};
  98.   int colleagues_length = sizeof(colleagues) / sizeof(colleagues[0]);
  99.   printf("colleagues_length=%d", colleagues_length);
  100.   // 初始化中介者类,绑定交互对象
  101.   Mediator mediator;
  102.   mediator_constructor(&mediator, colleagues, colleagues_length);
  103.   // 交互类发送消息
  104.   colleague_a.send(&colleague_a, "Hi, all! I'm a.");
  105.   printf("\r\n ==== \r\n");
  106.   colleague_a.send_to(&colleague_a, &colleague_b, "Hello, colleague_b. I am a!");
  107.   printf("\r\n ==== \r\n");
  108.   colleague_b.send_to(&colleague_b, &colleague_a, "Hi, colleague_a! I'm b.");
  109.   return 0;
  110. }
复制代码
 
 
更多语言版本

不同语言实现设计模式:https://github.com/microwind/design-pattern

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

7 天前

举报

感谢分享,学习下。
前天 12:06

举报

yyds。多谢分享
6 小时前

举报

yyds。多谢分享
3 小时前

举报

感谢分享,学习下。
您需要登录后才可以回帖 登录 | 立即注册