这本儿童地理启蒙书,让我重新理解了"模块化编程":从"认识家乡"到"系统设计"的思维跃迁

3 阅读1分钟

有时候,最好的技术启蒙书不是讲代码的那本。

2026 年初,我在给 5 岁侄子选书时,翻到一套《写给儿童的地理百科》。翻开第一页,我愣住了——这套书讲"认识家乡"的方式,竟然和软件工程里的"模块化设计"完全同构。

那一刻我意识到:儿童教育的认知框架,往往比技术书籍更接近第一性原理

今天想聊聊,这本看似不相关的地理启蒙书,如何帮我重构了对模块化编程的理解。


一、从"家乡"到"模块":认知起点的相似性

这套地理书的编排逻辑是:

1. 我家住在哪个村/小区
2. 村上面是镇,镇上面是县
3. 县组成市,市组成省
4. 省组成国家,国家组成大洲

这不就是软件系统的层级依赖关系吗?

# 地理层级 vs 模块层级
地理:  村 → 镇 → 县 → 市 → 省 → 国家 → 大洲
模块:  函数 → 类 → 包 → 子系统 → 系统 → 平台 → 生态

儿童学地理时,没有一上来就背"亚洲有 48 个国家",而是从"我家门口那条街"开始。但很多技术教程一上来就是"微服务架构最佳实践",跳过了从"一个函数"到"一个服务"的认知阶梯。

启发 1:模块化设计的第一步,是找到最小的"可命名单元"

就像孩子先学会"我家"这个概念,再理解"社区",最后理解"城市"。模块化编程也应该从"这个函数只做一件事"开始,而不是直接上"领域驱动设计"。


二、边界感:地理边界 vs 模块边界

这套书里有个细节让我印象深刻:

"每个省都有自己的省会,省与省之间有明确的分界线。"

模块设计的核心,正是边界感。

错误示范:没有"省界"的代码

# ❌ 全局变量到处飞,模块之间随意访问
user_data = {}
config = {}
db_connection = None

def process_user():
    global user_data, config, db_connection
    # 直接修改全局状态
    
def send_notification():
    global user_data, config, db_connection
    # 也直接修改全局状态

这就好比中国没有省界,北京可以直接管理海南的街道——结果就是混乱。

正确写法:明确"省界"和"省会"

# ✅ 每个模块有自己的"省会"(导出接口)
# user_module.py
class UserService:
    def __init__(self, db):
        self._db = db  # 私有依赖
        self._cache = {}  # 私有状态
    
    def get_user(self, user_id: int) -> dict:
        """对外提供的唯一接口"""
        if user_id not in self._cache:
            self._cache[user_id] = self._db.query(user_id)
        return self._cache[user_id]

# 其他模块不能直接访问 UserService 的内部状态
# 必须通过 get_user() 这个"省会城市"进行交互

启发 2:好模块像省份,有清晰的边界和唯一的"省会城市"(公共接口)


三、依赖关系:地理相邻性 vs 模块耦合度

地理书里有个概念:"相邻省份经济往来更频繁"。

模块设计同理:相邻模块可以耦合,跨层模块必须解耦。

用代码实现"地理相邻原则"

# ✅ 相邻层之间可以有依赖
# controller 层可以依赖 service 层
# service 层可以依赖 repository 层
# 但 controller 不能直接依赖 repository

# 使用依赖注入实现"省界检查"
from typing import Protocol

class IUserService(Protocol):
    """定义接口契约(相当于省界)"""
    def get_user(self, user_id: int) -> dict: ...

class OrderController:
    def __init__(self, user_service: IUserService):
        # 只能通过接口访问,不能直接访问实现
        self._user_service = user_service
    
    def get_order_detail(self, order_id: int):
        # 需要用户信息时,通过"省界"申请
        user = self._user_service.get_user(user_id=123)
        return {"order": order_id, "user": user}

启发 3:模块间的依赖应该像"省际交通"——有固定通道,不能随意越界


四、实战:用"地理思维"重构一个混乱模块

重构前:没有"省界"的系统

# ❌ 所有功能混在一起,像没有省界的国家
import requests
from datetime import datetime

# 全局配置
API_KEY = "xxx"
DB_HOST = "localhost"

# 用户相关
def get_user(user_id):
    # 直接访问数据库
    pass

# 订单相关
def create_order(user_id, items):
    # 直接调用用户函数
    user = get_user(user_id)
    # 直接发送通知
    send_email(user['email'], "订单创建成功")
    pass

# 通知相关
def send_email(to, subject):
    # 直接使用全局配置
    pass

重构后:有"省界"的系统

# ✅ 每个模块有自己的"省界"和"省会"

# === user_province/user_service.py ===
class UserService:
    """用户省的省会"""
    def __init__(self, db):
        self._db = db
    
    def get_user(self, user_id: int) -> dict:
        return self._db.query("users", user_id)

# === order_province/order_service.py ===
class OrderService:
    """订单省的省会"""
    def __init__(self, user_service: UserService, notification_service: NotificationService):
        # 通过"省界"依赖其他省
        self._user_service = user_service
        self._notification_service = notification_service
    
    def create_order(self, user_id: int, items: list) -> dict:
        # 通过正式通道访问其他省
        user = self._user_service.get_user(user_id)
        order = self._save_order(user, items)
        self._notification_service.send_order_created(user, order)
        return order

# === notification_province/notification_service.py ===
class NotificationService:
    """通知省的省会"""
    def __init__(self, email_client):
        self._email_client = email_client
    
    def send_order_created(self, user, order):
        self._email_client.send(
            to=user['email'],
            subject=f"订单{order['id']}创建成功"
        )

# === main.py(中央政府) ===
# 由最外层统一组装依赖
db = Database(DB_HOST)
email_client = EmailClient(API_KEY)

user_service = UserService(db)
notification_service = NotificationService(email_client)
order_service = OrderService(user_service, notification_service)

# 各模块边界清晰,依赖关系明确

五、适合人群

这篇文章适合:

  • ✅ 写过代码但没做过模块设计的初级开发者
  • ✅ 被"高内聚低耦合"困扰的技术人员
  • ✅ 需要给团队讲解模块设计的架构师
  • ✅ 对教育方法论感兴趣的产品经理

不@适合

  • ❌ 期待"5 分钟学会微服务"的速成派
  • ❌ 认为"模块划分就是多建几个文件"的开发者

六、总结:从儿童认知到系统设计

这套地理书让我明白:

地理思维模块设计
从家乡开始从最小功能单元开始
省界清晰模块边界清晰
省会城市公共接口
相邻省份相邻层依赖
中央政府依赖注入容器

最好的设计原则,往往藏在最朴素的认知框架里。

儿童学地理,不会一上来就背"中国有 34 个省级行政区",而是从"我家在哪个村"开始。模块化设计也一样——先找到最小的"可命名单元",再考虑如何组合。


👉 【全 8 册】写给儿童的中国地理科普百科 ¥23.8 ← 京东直达(券后价,原价¥88.8)

声明:本文部分链接为联盟推广链接,不影响价格。


互动话题:你从哪些"非技术书"中获得过技术启发?欢迎在评论区分享~