明:CQRS 在 Elixir 中的实验

简介

学习编程语言时,通过动手项目实践往往能取得最佳效果,因为真实场景的挑战能加速技能掌握。凭借C#背景和对Brighter框架的持续贡献,我决定通过构建名为Ming的项目来深化Elixir技能。该项目在探索Elixir函数式编程范式的同时,实现了*CQRS(*命令查询职责分离)等设计模式。

Ming项目

Ming的设计灵感来源于Brighter框架Commanded,其核心目标是将C#中的CQRS原则移植并适配到Elixir生态中。

名称由来

或许你会疑惑为什么选择"明"(Ming)这个名称。我希望这个库名简短易记,在发音上接近Brighter且便于英文交流。葡萄牙语命名未果后,正在学习中文的我发现"Ming"(明)的发音非常契合这个要求。

核心概念

处理器(Handlers)

Ming中的处理器是简单的模块,通过定义`execute/2`函数处理命令/事件和执行上下文。例如:

ruby 复制代码
defmodule SampleHandler do
  @moduledoc false

  def execute(%Ming.ExampleCommand1{}, %Ming.ExecutionContext{}), do: :ok
end

这种设计既保留了C#接口的简洁性,又利用Elixir的模式匹配特性提升了代码可读性。

命令/事件路由

通过use Ming.Router定义分发规则注册处理器:

ruby 复制代码
defmodule Ming.SampleRouter do
  @moduledoc false
  use Ming.Router

  dispatch [SampleCommand, SampleEvent], to: ReturningAKeyHandler
  dispatch SampleEvent, to: ReturningAKeyHandler
end

路由器会生成发送/发布管道。当某个命令注册了多个处理器时,Ming会返回*{:error, :more_than_one_handler_founded}*错误,以此强制显式设计。

中间件

通过middleware/1send_middleware/1publish_middleware/1向管道添加中间件:

ruby 复制代码
defmodule Ming.SampleRouter do
  @moduledoc false
  use Ming.Router

  middleware SomeMiddleware

  dispatch [SampleCommand, SampleEvent], to: ReturningAKeyHandler
  dispatch SampleEvent, to: ReturningAKeyHandler
end

这允许实现日志记录或事务管理等横切关注点,类似于.NET中间件管道,但保持了Elixir的函数式纯粹性。

宏(Macros)

Elixir的宏功能在编译时生成代码方面非常强大,但调试和排查问题较为困难(可能因我经验不足)。C#中类似特性是源代码生成器,但需要掌握Roslyn API。

命令处理器

在Brighter中,IAmACommandProcessor 集中管理命令发送/事件发布。Ming通过Ming.CommandProcessor实现类似功能:

ruby 复制代码
defmodule SampleCommandProcessor do
  use Ming.CommandProcessor, otp_app: :sample

  router SampleRouter
end

该模块注册路由器并作为交互入口点,充分利用Elixir OTP的健壮性优势。

改进路线图

  • 文档完善: 遵循Elixir官方指南结构提升可读性,并通过Hex.pm发布
  • 功能扩展: 消息网关消费、后期处理方法等特性开发
  • 测试覆盖: 完善测试用例验证错误处理和中间件行为

总结

Ming展示了Elixir的函数式编程特性和OTP生态系统如何构建可扩展、易维护的系统。通过融合C# Brighter框架的设计思想与Elixir语言优势,该项目成功搭建了不同编程范式间的桥梁。对于学习者而言,从微型项目起步,结合《Programming Elixir》等官方文档,是掌握该语言的有效路径。

参考资料

Ming项目GitHub地址

相关推荐
塔中妖5 天前
Windows 安装 RabbitMQ 详细教程(含 Erlang 环境配置)
windows·rabbitmq·erlang
Andy Dennis17 天前
一文了解异步通信基础消息队列之RabbitMQ(一)
分布式·消息队列·rabbitmq·erlang·异步任务
cheniie1 个月前
Nerves从Hello World到点亮LED
树莓派·elixir·nerves
ZvUUNRLrkJx1 个月前
探索PFC开关电源仿真之全桥LLC
erlang
强化试剂1 个月前
Acridinium-Biotin,吖啶生物素偶联物在化学发光免疫分析中的应用逻辑
erlang·laravel·composer
qq 8762239652 个月前
12脉冲整流器24脉冲整流器matlab仿真 matlab/simulink ~
erlang
武子康2 个月前
Java-207 RabbitMQ Direct 交换器路由:RoutingKey 精确匹配、队列多绑定与日志分流实战
java·消息队列·rabbitmq·erlang·ruby·java-rabbitmq
武子康2 个月前
Java-203 RabbitMQ 生产者/消费者工作流程拆解:Connection/Channel、默认交换器、ACK
java·分布式·消息队列·rabbitmq·erlang·ruby·java-rabbitmq
武子康2 个月前
Java-202 RabbitMQ 生产安装与容器快速启动:Erlang 兼容、RPM 部署与常用命令
java·消息队列·rabbitmq·erlang·java-rabbitmq·mq
互亿无线明明3 个月前
如何为全球业务构建可扩展的“群发国际短信接口”?
java·c++·python·golang·eclipse·php·erlang