🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
## 一、单一职责原则(SRP) > 一个类应该只有一个引起它变化的原因。 ### ✅ 意义: 让类职责更清晰,降低耦合,增强可维护性。 ### ❌ 违反示例: ~~~ php复制编辑class User { public function create(array $data) { // 保存用户到数据库 } public function sendWelcomeEmail() { // 发送欢迎邮件 } } ~~~ 这违反了 SRP,因为一个类负责了两个职责:用户创建和邮件发送。 ### ✅ 遵守示例: ~~~ php复制编辑class User { public function create(array $data) { // 只负责创建用户 } } class WelcomeMailer { public function send(string $email) { // 只负责发送欢迎邮件 } } ~~~ * * * ## 二、开闭原则(OCP) > 软件实体应该对扩展开放,对修改关闭。 ### ✅ 意义: 不改动原有代码的前提下扩展功能。 ### ❌ 违反示例: ~~~ php复制编辑class Payment { public function pay($type) { if ($type == 'wechat') { // 微信支付逻辑 } elseif ($type == 'alipay') { // 支付宝逻辑 } } } ~~~ 新增一种支付方式时就得改动这个类。 ### ✅ 遵守示例(使用策略模式): ~~~ php复制编辑interface PayStrategy { public function pay(); } class WechatPay implements PayStrategy { public function pay() { echo "使用微信支付"; } } class Alipay implements PayStrategy { public function pay() { echo "使用支付宝支付"; } } class Payment { protected PayStrategy $payStrategy; public function __construct(PayStrategy $strategy) { $this->payStrategy = $strategy; } public function pay() { $this->payStrategy->pay(); } } ~~~ * * * ## 三、里氏替换原则(LSP) > 子类对象能够替换其父类对象,并保证程序行为不变。 ### ✅ 意义: 子类必须能够完全替代父类,不影响原有功能。 ### ❌ 违反示例: ~~~ php复制编辑class Bird { public function fly() { echo "会飞"; } } class Ostrich extends Bird { public function fly() { throw new Exception("鸵鸟不会飞"); } } ~~~ `Ostrich` 无法替代 `Bird` 使用,违背里氏替换原则。 ### ✅ 遵守示例: 将会飞的鸟和不会飞的鸟拆分为不同的抽象: ~~~ php复制编辑abstract class Bird {} interface Flyable { public function fly(); } class Sparrow extends Bird implements Flyable { public function fly() { echo "麻雀飞"; } } class Ostrich extends Bird { // 不实现 Flyable 接口 } ~~~ * * * ## 四、依赖倒置原则(DIP) > 高层模块不应该依赖低层模块,二者都应该依赖抽象。 ### ✅ 意义: 通过依赖接口(抽象)而不是具体类,使系统更可扩展和解耦。 ### ❌ 违反示例: ~~~ php复制编辑class MySQLDatabase { public function connect() { echo "连接 MySQL"; } } class UserRepository { protected $db; public function __construct() { $this->db = new MySQLDatabase(); // 依赖了具体类 } } ~~~ ### ✅ 遵守示例(使用依赖注入): ~~~ php复制编辑interface DatabaseInterface { public function connect(); } class MySQLDatabase implements DatabaseInterface { public function connect() { echo "连接 MySQL"; } } class UserRepository { protected DatabaseInterface $db; public function __construct(DatabaseInterface $db) { $this->db = $db; } } ~~~ * * * ## 五、接口隔离原则(ISP) > 客户端不应被迫依赖它不使用的接口。 ### ✅ 意义: 应将胖接口拆分为多个小接口,满足特定客户端的需求。 ### ❌ 违反示例: ~~~ php复制编辑interface Worker { public function work(); public function eat(); } class Robot implements Worker { public function work() { echo "机器人工作"; } public function eat() { // 机器人不会吃饭 throw new Exception("机器人不会吃饭"); } } ~~~ ### ✅ 遵守示例: ~~~ php复制编辑interface Workable { public function work(); } interface Eatable { public function eat(); } class Human implements Workable, Eatable { public function work() { echo "人工作"; } public function eat() { echo "人吃饭"; } } class Robot implements Workable { public function work() { echo "机器人工作"; } } ~~~ * * * ## 六、依赖注入(DI) > 是依赖倒置原则的实现方式之一。 ### ✅ 常见方式: 1. **构造函数注入** 2. **Setter 方法注入** 3. **接口注入(较少用)** ### 构造函数注入示例: ~~~ php复制编辑class Logger { public function log($msg) { echo $msg; } } class OrderService { protected Logger $logger; public function __construct(Logger $logger) { $this->logger = $logger; } public function placeOrder() { $this->logger->log("下单成功"); } } ~~~