封装与模块化不是一回事:封装是面向对象中通过访问修饰符控制类内成员可见性的语法机制,解决“怎么藏”;模块化是工程层面按职责划分功能的设计策略,解决“怎么分”,二者需协同实现高内聚低耦合。

不是一回事,但模块化常依赖封装来实现。封装是面向对象的语法机制,模块化是工程层面的设计策略。
封装解决的是“怎么藏”
封装关注类内部如何控制属性和方法的可见性,核心是 public、private、protected 这三个访问修饰符。它不关心代码物理怎么组织,只管“谁可以调用、谁不能直接碰”。
-
private属性只能在本类中读写,连子类都不行 -
protected允许子类继承访问,但外部对象仍不可见 - 没有修饰符默认是
public,等同于完全暴露——这其实已经破坏了封装意图
比如一个 User 类把 $passwordHash 设为 private,再提供 changePassword() 方法做校验逻辑,这就是典型的封装:你不能绕过规则直接改哈希值。
模块化解决的是“怎么分”
模块化是把功能按职责切开,各自独立开发、测试、复用。PHP 里落地方式不止一种:
立即学习“PHP免费学习笔记(深入)”;
- 用命名空间(
namespace App\Services)归类相关类,避免全局命名冲突 - 用 Composer 管理包(如
monolog/monolog),把日志逻辑抽成可替换的模块 - 按 MVC 或领域分层(
App\Models/App\Http\Controllers),目录即契约
模块化不要求一定用类——一个纯函数文件 helpers/string.php 也可以是模块;但一旦涉及状态管理或行为聚合,就自然需要封装来守住边界。
两者混用时最容易踩的坑
实际项目里,很多人以为“用了类就是封装”,或者“建了 namespace 就算模块化”,结果代码还是泥球一团:
- 类里全是
public属性,外部直接$user->name = 'hacker'—— 封装形同虚设 - 所有类塞进
App根命名空间,没按功能分层 —— 模块化只是目录名而已 - 一个
UserService类既连数据库、又发邮件、还写日志 —— 违反单一职责,模块边界模糊
真正有效的组合是:用封装约束每个类的接口粒度,再用模块化把类们组织成高内聚、低耦合的单元。比如 App\Auth\PasswordValidator 是个封装严密的小类,而整个 Auth 命名空间才是模块。
复杂点在于:封装是语法强制的,模块化靠约定和工具链支撑。没有自动检查说“你这个命名空间结构不合理”,但 private 写错会直接报错。所以模块化设计更依赖团队对业务边界的共识,而不是语言特性。



















