Ruby的Module - 将思想捆绑到“高级别”的工具

在Ruby中,Module是将代码模块化并捆绑到高级别的工具。像世界地图一样结构化代码结构以便理解。

밤치 275

朴文浩博士一直强调模块化

大脑是这样学习的。

  • 将其分解为小单元(细胞,功能)
  • 将这些单元组合成模块
  • 这些模块汇聚在一起形成系统

编码也是一样的。

  • 方法:一个动作
  • 类:一个对象(存在)
  • 模块(Module):将多个类/方法组合成更大概念的上层框架

在Ruby中,模块可以这样使用:

  1. 命名空间绑定
  2. 共享通用功能(Mixin)
  3. 定义表示领域(按主题划分的世界)的上层概念

一旦理解这一点,

代码不再只是“文件集合”,而是开始看起来像是大脑中结构化的宇宙地图


1. 命名空间(Namespace):区分世界的框架

例如,

假设您想在多个地方使用名为User的类。

  • 管理员页面的User
  • 商城的User
  • 用于API的User

如果只创建一个class User会怎样?

名称会冲突。思维也会混乱。

这时模块将帮助分离世界

module Admin
  class User
    def info
      puts "这是管理员页面的用户。"
    end
  end
end

module Shop
  class User
    def info
      puts "这是商城的客户用户。"
    end
  end
end

admin_user = Admin::User.new
shop_user = Shop::User.new

admin_user.info  # => 这是管理员页面的用户。
shop_user.info   # => 这是商城的客户用户。

在这里,模块就像是:

“这是Admin世界的User”

“这是Shop世界的User”

成为区分世界的框架

朴文浩式思维

  • 框架:即使名称相同,根据上层框架的不同,角色也会有所不同
  • 立体化:将User的概念存储为具有坐标的结构,而不是平面
  • 模块化:在大脑中产生“按领域分类的抽屉”感觉

现在,您的大脑会认识到,

“即使名称相同,如果世界不同,那就是完全不同的存在”

这种更高层次的理解。


2. Mixin:将共同能力“插入”到多个类中的模块

第二个用途非常强大。

模块可以成为将共同功能捆绑在一起以便重复使用的块

例如,

假设多种类型的对象都要“记录日志”。

  • 用户(User)的操作日志
  • 订单(Order)的状态更改日志
  • 支付(Payment)的失败日志

如果分别复制粘贴到每个类中?

  • 代码重复
  • 维护困难
  • 要修复一个bug,需要修改三个地方

这时模块 + include就发挥作用了。

module Loggable
  def log(message)
    time = Time.now
    puts "[#{time}] #{message}"
  end
end

class User
  include Loggable

  def sign_in
    log("用户已登录。")
  end
end

class Order
  include Loggable

  def submit
    log("订单已接收。")
  end
end

user = User.new
user.sign_in
# [2025-12-09 23:12:34] 用户已登录。

order = Order.new
order.submit
# [2025-12-09 23:12:35] 订单已接收。

发生了什么

  • Loggable模块将“记录日志的能力”模块化
  • 进行include Loggable后,
    该类就可以像自己的方法一样使用log方法
  • 即,“将能力包插入到多个类中”

从大脑角度看

  • 当一个功能需要在多个地方共享时,
    大脑将其捆绑为“上层概念”
  • 模块正是扮演这种上层概念的角色
  • 不仅仅是代码,思维结构本身也被抽象化

“啊,日志不是User或Order的一部分,

而是多个主体共享的上层能力。”

一旦有了这种领悟,

编码不再只是“编写代码”,而是

开始感觉像是在设计世界结构


3. 抽象化:模块是创建“领域语言”的层级

通过有效使用模块,

代码逐渐变得像“领域语言”

例如,假设有一个名为“支付系统”的领域。

module Payment
  module Gateway
    def charge(amount)
      puts "请求支付#{amount}元。"
    end
  end

  module Refundable
    def refund(amount)
      puts "退款#{amount}元。"
    end
  end
end

class Order
  include Payment::Gateway
  include Payment::Refundable
end

order = Order.new
order.charge(50000)
order.refund(20000)

这里的模块不仅仅是简单的功能。

它们是用代码表示领域概念

  • Payment::Gateway → 表示“支付请求功能”的模块
  • Payment::Refundable → 表示“退款功能”的模块
  • Order是将这两者结合的存在

通过反复这样做,

Ruby代码逐渐变成了这样的感觉。

“我所思考的业务概念直接变成了代码?”

在这一点上,开发者不再是

简单的实现者,而是

设计领域的人,即设计者/哲学家。


4. 模块 vs 类:有何不同?

让我们总结一下。

概念 角色 大脑感觉
方法 一个动作 动词,行为
一个对象(存在),状态+行为 名词(人,物),实体
模块 多个类/方法的上层概念集合 世界观,能力包,领域级结构

在Ruby中,模块不会自己创建实例

MyModule.new这样的操作是不允许的。

相反:

  • 成为其他类的一部分,提供能力块
  • 提供命名空间,成为上层框架

换句话说,

类是“存在”

模块是“存在共享的概念·能力·世界观”


5. 真正重要的是“大脑如何改变”

一旦理解了模块,

大脑就会这样进化。

  1. 将代码视为概念单位,而不是文件单位
- “这个功能属于哪里?”  
    → “这个功能被User,Order和Payment共享,所以将其提取为模块。”
  1. 形成领域语言
- “Payment::Gateway”,“Notification::Sender”,“Auth::Tokenizable”之类的  
    → 您的服务拥有自己的词汇
  1. 复杂度大大降低
- 明确了要修改的地方:  
    “要更改日志逻辑” → 仅需修改`Loggable`模块
  1. 大脑结构也像模块一样整理
- 当一个功能需要在多个地方共享时,  
    大脑将其**“捆绑为上层概念”**

6. 亲自尝试任务:创建自己的模块

现在,

将“模块”植入您的大脑的任务。

任务1:创建Timestamped模块

要求:

  • 创建名为Timestamped的模块
  • 提供一个stamp方法
    • 调用时:以“[当前时间] 消息”格式输出
  • PostComment类中include以便共同使用

预期流程:

module Timestamped
  # 在此处创建stamp方法
end

class Post
  include Timestamped

  def publish
    stamp("文章已发布。")
  end
end

class Comment
  include Timestamped

  def write
    stamp("评论已发表。")
  end
end

post = Post.new
post.publish

comment = Comment.new
comment.write

任务2:将自己的领域模块绑定在一起

选择一个主题:

  • 学习(Study)
  • 健身(Fitness)
  • 博客(Blog)
  • 购物(Shop)
  • 乐队练习(Band)

例如:Study领域

  • Study::Trackable – 记录学习时间的模块
  • Study::Report – 输出周/月统计的模块

然后创建DayStudyTaskStudy等类,

include Study::Trackable来使用。

在尝试这个任务时,

您已经成为了一个“用Ruby设计自己的世界”的人。


结论:理解模块后,代码变成了‘世界设计语言’

到目前为止的流程:

  • 方法:行动的最小单位
  • 类:存在(对象)的框架
  • 模块:多个存在共享的概念/能力/世界观

现在,当编写代码时,

您可以这样思考。

“这是一个对象的独特属性吗?”

→ 将其放在类中

“多个对象共享的功能吗?”

→ 提取为模块

“这是这项服务的领域概念吗?”

→ 使用模块+命名空间来定义

在那一刻,

编码不再仅仅是“学习语法”

“我的头脑中的世界观

正以代码的形式实现”

这样的感觉。

一旦产生这种感觉,

真的会让人激动。

Comments

Add Comment

Your email won't be published and will only be used for reply notifications.

Get notified of new posts

We'll email you when Bamchi Blog publishes new content.

Your email will only be used for new post notifications.