Photo by Lorem Ipsum
1133 words
6 minutes
设计模式系列(一):核心基石
设计模式系列
Posts in this series (7)AI 智能总结
设计模式 1 核心基石
设计模式不是玄学,是可复用的代码设计经验。所有设计模式的底层逻辑,都源于几套通用设计原则。掌握原则,就掌握了设计模式的核心精髓,无需死记硬背所有模式。
本文精简讲解SOLID五大原则+迪米特法则+组合优于继承+面向接口编程,搭配极简代码,易懂实用。
一、SOLID 五大核心原则
1. 单一职责原则(SRP)
定义:一个类/方法只负责一个职责,只有一个修改原因。
核心:杜绝臃肿类,拆分功能,降低耦合。
// 违背原则:一个类同时做用户保存和日志输出class User { public void save(){} public void log(){}}
// 遵循原则:职责拆分class User { public void save(){}}class UserLog { public void log(){}}2. 开闭原则(OCP)
定义:对扩展开放,对修改关闭。
核心:新增功能不改动原有代码,避免老代码出错。
// 违背:新增折扣功能需要修改原计算类class Cashier { public double calcPrice(double original) { return original; // 原价 // 新增折扣:需要在这里修改代码 }}
// 遵循:通过扩展实现新功能interface Discount { double apply(double original);}class NormalDiscount implements Discount { public double apply(double original) { return original * 0.9; }}class VipDiscount implements Discount { public double apply(double original) { return original * 0.8; }}3. 里氏替换原则(LSP)
定义:子类可以完全替换父类,且程序逻辑不受影响。
核心:子类不要重写父类非抽象方法,保证继承合法性。
// 违背:子类重写改变父类行为,无法替换class Bird { void fly() { System.out.println("飞起来了"); }}class Ostrich extends Bird { // 鸵鸟不会飞,重写改变行为 @Override void fly() { throw new RuntimeException(); }}
// 遵循:提取抽象,保证行为一致性interface Bird {}interface FlyableBird extends Bird { void fly();}class Ostrich implements Bird {} // 不继承飞行能力class Sparrow implements FlyableBird { public void fly() { System.out.println("飞起来了"); }}4. 接口隔离原则(ISP)
定义:客户端不依赖不需要的接口,接口越小越精准。
// 臃肿接口(违背)interface Animal { void run(); void fly();}
// 拆分细接口(遵循)interface RunAnimal { void run(); }interface FlyAnimal { void fly(); }5. 依赖倒置原则(DIP)
定义:依赖抽象接口,不依赖具体实现。
核心:解耦,实现代码灵活替换。
// 违背:依赖具体类class MySQL { void save(){} }class Service { MySQL db = new MySQL(); }
// 遵循:依赖抽象接口interface DB { void save(); }class MySQL implements DB { void save(){} }class Service { DB db; }二、三大补充黄金原则
1. 迪米特法则(最少知道原则)
定义:一个类尽量少依赖其他类,只和直接朋友通信。
核心:减少类之间的关联,降低代码牵一发动全身的风险。
// 违背:订单直接穿透多层,依赖仓库和商品class Order { void create() { Warehouse warehouse = new Warehouse(); Goods goods = warehouse.getGoods(); goods.reduceStock(); // 直接操作内部对象 }}
// 遵循:只和直接朋友通信,让仓库自己处理class Order { void create() { Warehouse warehouse = new Warehouse(); warehouse.reduceGoodsStock(); // 只调用直接方法 }}2. 组合优于继承
核心:优先使用对象组合/聚合,少用类继承。
原因:继承是强耦合,父类改动会影响所有子类;组合灵活、可动态替换。
// 组合替代继承class Engine { void start(){} }class Car { // 组合复用功能 private Engine engine = new Engine(); public void run(){ engine.start(); }}3. 面向接口编程
核心:定义抽象接口规范,实现类负责具体落地。
优势:屏蔽实现细节、统一调用规范、支持多实现动态切换,是Spring、多态的底层核心。
// 面向接口编程,灵活切换支付方式interface PayChannel { boolean pay(double amount);}
class AliPay implements PayChannel { public boolean pay(double amount) { // 支付宝实现 return true; }}
class WechatPay implements PayChannel { public boolean pay(double amount) { // 微信支付实现 return true; }}
// 调用方只依赖接口,不关心具体实现class OrderService { private PayChannel payChannel; public void setPayChannel(PayChannel payChannel) { this.payChannel = payChannel; // 动态注入 }}总结
所有设计模式都是以上原则的落地实现:
- SOLID 保证代码规范、可扩展、低耦合;
- 迪米特法则控制类的依赖范围;
- 组合+接口编程,实现代码高灵活、高复用。
熟练掌握这些原则,就能根据业务自己设计合理的代码结构,而不是生硬套用设计模式。