抽象
什么是“抽象”?
“抽象”是软件开发中的一个核心思想,它指的是:
屏蔽细节、保留本质,从而建立简洁清晰的模型来解决复杂问题。
换句话说,我们不是去关注“所有事”,而是关注这些事中最本质的特征,从而写出可扩展、可维护、可复用的功能模块。
抽象的作用
-
简化系统复杂度
我们不可能在脑海中同时处理一个完整系统的所有细节,抽象可以让我们分层思考,只关注每一层的职责。 -
增强代码的可复用性和扩展性
比如写一个“动物”类是对所有动物的抽象,子类(如狗、猫)只需要实现具体细节。这样我们可以在不改动原始结构的基础上扩展更多动物。 -
提升沟通效率
抽象出的模型(如类、接口、服务)是一种约定,方便团队成员之间更高效地协作,比如根据接口的参数,返回值就知道该如何对接。 -
便于模块化开发
如果模块A依赖模块B,通过抽象接口依赖,而不是直接依赖具体类
代码层的抽象:“改得少、复用多”
-
接口和抽象类:目的就是定义行为,而不是实现细节
// 定义一个抽象的“通知”行为 public interface INotifier { void Send(string message); }
你可以有很多实现方式:
public class EmailNotifier implements INotifier { public void Send(string message) { // 发送邮件 } } public class SmsNotifier implements INotifier { public void Send(string message) { // 发送短信 } }
调用者只关心
INotifier.Send()
,不用知道是发邮件还是发短信只需要新增实现类,不动原有代码(这就是“开闭原则”)
设计模式的抽象:让复杂行为“可组合、可替换”
每一个设计模式,背后几乎都有一个“抽象”的核心思想在支撑。比如:
-
策略模式:抽象出行为的“可变部分”
-
工厂模式:抽象出对象的创建逻辑
-
观察者模式(Observer Pattern):抽象出依赖关系,在事件触发时,统一通知所有观察者,而这些观察者实现统一接口
协议上的抽象:定义一组规范
通过定义一组规范,让通信双方共同遵守从而达到互相通信的目的,比如AI中的mcp概念就是一套协议,开发者可以基于这套协议去实现一些工具,即MCP Server。这样在MCP Client只需要做一些基本配置就能让大模型自己去调用对应的工具。
抽象与 SOLID 原则
原则 | 与抽象的关系 |
---|---|
S 单一职责 | 抽象出的类只做一件事 |
O 开闭原则 | 对扩展开放(通过新增实现类),对修改封闭(不改抽象层) |
L 里氏替换 | 抽象出的父类或接口能被任何子类安全替换,通过"组合优于继承"来保证这一点,比如:不在Bird类中定义一个Fly方法,而是在Flyable接口中定义Fly方法,而子类去继承Bird类后再根据逻辑决定是否实现Flyable接口。 |
I 接口隔离 | 一个类 不继承或实现 另一个有它不需要的方法 的抽象类/接口 |
D 依赖倒置 | 高层模块依赖于抽象,而不是具体实现 |
抽象是 SOLID 原则的“执行基础”,SOLID 原则是抽象的“落地细节”。
何时抽象?
- 行为经常发生变化
- 多个地方都需要复用
- 未来需要不断扩展