设计模式和设计原则-中高级架构思路-面向接口编程

作者:自由生长2024日期:2025/12/31

历史文章参见

设计模式-23种设计模式的说法-掘金

每日知识-设计模式-状态机模式-掘金

每日知识-设计模式-观察者模式 - 掘金

cpp笔记第3篇-C++多线程单例模式单例模式 - 掘金


今天讲讲面向接口编程的核心思想,它可以看到各种设计模式的一种杂糅。

面向接口编程的核心思想

以实际的代码举例子,我最近在写一个安卓的笔记程序,使用到了面向接口的编程方法,下面我以具体的类举例来说明面向接口编程的思想,以及后文解释,面向接口编程可以体现哪些设计模式。

一、依赖接口,而不是具体实现

1//  面向具体类(耦合)
2public class NoteListManager {
3    private MainActivity activity; // 直接依赖 MainActivity
4}
5
6//  面向接口(解耦)
7public class NoteListManager {
8    private INoteListCallback callback; // 依赖接口
9    // 优势:只要接口不变,实现类怎么变都行
10}
11

二、在这个场景中的体现

1. 定义接口(契约)
1// INoteListCallback.java - 定义"契约"
2public interface INoteListCallback {
3    // 定义需要什么方法,不关心怎么实现
4    String formatTimestamp(long timestamp);
5    int dpToPx(int dp);
6    NoteDbHelper getDbHelper();
7}
8
2. 实现接口(具体实现)
1// MainActivity.java - 实现接口
2public class MainActivity implements INoteListCallback {
3    // 提供具体实现
4    @Override
5    public String formatTimestamp(long timestamp) {
6        // 具体怎么格式化,MainActivity 自己决定
7    }
8}
9
3. 使用接口(依赖抽象)
1// NoteListManager.java - 只依赖接口
2public class NoteListManager {
3    private INoteListCallback callback; // 只依赖接口,不依赖具体类
4    
5    public void displayNote(Note note) {
6        // 通过接口调用,不知道具体是哪个类实现的
7        String time = callback.formatTimestamp(note.getTimestamp());
8    }
9}
10

三、面向接口编程的优势

1. 解耦
1// NoteListManager 不知道 MainActivity 的存在
2// 它只知道有一个对象实现了 INoteListCallback 接口
3// 可以是 MainActivity,也可以是 TestActivity,也可以是 MockActivity
4
2. 可测试性
1// 测试时,可以用 Mock 实现
2class MockCallback implements INoteListCallback {
3    @Override
4    public String formatTimestamp(long timestamp) {
5        return "Mock时间"; // 测试用的简单实现
6    }
7}
8
9// 测试 NoteListManager
10NoteListManager manager = new NoteListManager();
11manager.initialize(listView, new MockCallback()); //  Mock 测试
12
3. 可扩展性
1// 以后可以有不同的实现
2class AnotherActivity implements INoteListCallback {
3    @Override
4    public String formatTimestamp(long timestamp) {
5        return "另一种格式"; // 不同的实现方式
6    }
7}
8
9// NoteListManager 不需要改,只需要传入不同的实现
10manager.initialize(listView, new AnotherActivity());
11

四、设计原则体现

1. 依赖倒置原则(DIP)
1高层模块(NoteListManager)不应该依赖低层模块(MainActivity)
2两者都应该依赖抽象(INoteListCallback)
3
2. 开闭原则(OCP)
1对扩展开放:可以添加新的实现类
2对修改关闭:NoteListManager 不需要修改
3

五、优点总结

1面向接口编程 = 定义接口(契约)
2            = 实现接口(具体实现)
3            = 使用接口(依赖抽象)
4            = 解耦、可测试、可扩展
5

Callback 就是面向接口编程思想的实际体现。下面我们看看哪些具体的设计模式都跟面向接口编程有关。

与面向接口编程有关的设计模式

常见的一种是策略模式。当然,面向接口编程不仅体现在策略模式中,还贯穿于多种行为型和结构型模式

一、在行为型模式中的体现

1. 观察者模式(Observer) ⭐️ 高度体现

1// 定义接口
2interface Observer {
3    void update(String message);
4}
5
6interface Subject {
7    void registerObserver(Observer o);
8    void removeObserver(Observer o);
9    void notifyObservers();
10}
11
12// 实现接口
13class User implements Observer {
14    @Override
15    public void update(String message) {
16        System.out.println("收到消息: " + message);
17    }
18}
19
20// 使用接口
21NewsPublisher publisher = new NewsPublisher();
22publisher.registerObserver(new User());  // 依赖接口,不依赖具体类
23

接口思维:Observer是观察者的抽象,Subject是主题的抽象。双方通过接口通信。

2. 命令模式(Command) ⭐️ 核心就是接口

1// 定义命令接口
2interface Command {
3    void execute();
4    void undo();
5}
6
7// 不同实现
8class SaveCommand implements Command {
9    @Override
10    public void execute() {
11        // 保存逻辑
12    }
13}
14
15class DeleteCommand implements Command {
16    @Override
17    public void execute() {
18        // 删除逻辑
19    }
20}
21
22// 使用命令
23Button saveBtn = new Button(new SaveCommand());  // 传入接口
24

接口思维:将请求封装为对象,所有命令都实现Command接口,调用者只依赖接口。

3. 状态模式(State)

每日知识-设计模式-状态模式- 掘金

1interface State {
2    void handle(Context context);
3}
4
5class ConcreteStateA implements State {
6    @Override
7    public void handle(Context context) {
8        context.setState(new ConcreteStateB());  // 切换到另一个状态
9    }
10}
11

接口思维:状态抽象为接口,上下文对象依赖State接口而不是具体状态。

4. 模板方法模式(Template Method)

1abstract class DataProcessor {
2    // 模板方法 - 定义算法骨架
3    public final void process() {
4        readData();      // 固定步骤
5        transformData(); // 抽象方法,子类实现
6        saveData();      // 固定步骤
7    }
8    
9    // 抽象方法 - 通过实现来变化
10    protected abstract void transformData();
11}
12

接口思维:虽然用抽象类,但思想一致 - 定义算法框架,具体步骤由子类实现。

二、在结构型模式中的体现

1. 适配器模式(Adapter) - 核心是统一接口

1// 目标接口(期望的接口)
2interface MediaPlayer {
3    void play(String audioType, String fileName);
4}
5
6// 已有的类,接口不兼容
7class Mp4Player {
8    public void playMp4(String fileName) { /*...*/ }
9}
10
11// 适配器 - 实现目标接口,包装已有类
12class Mp4Adapter implements MediaPlayer {
13    private Mp4Player mp4Player;
14    
15    @Override
16    public void play(String audioType, String fileName) {
17        if (audioType.equals("mp4")) {
18            mp4Player.playMp4(fileName);  // 适配
19        }
20    }
21}
22

接口思维:通过适配器统一不同系统的接口,客户端只依赖MediaPlayer接口。

2. 桥接模式(Bridge) - 抽象与实现分离

1// 抽象部分
2abstract class Shape {
3    protected Color color;  // 桥接 - 组合Color接口
4    
5    public Shape(Color color) {
6        this.color = color;
7    }
8    
9    abstract void draw();
10}
11
12// 实现部分接口
13interface Color {
14    String fill();
15}
16
17// 具体实现
18class Red implements Color {
19    @Override
20    public String fill() {
21        return "红色";
22    }
23}
24
25// 使用
26Shape circle = new Circle(new Red());  // 通过接口组合
27

接口思维:将抽象(Shape)与实现(Color)解耦,通过接口组合。

3. 代理模式(Proxy)

1interface Image {
2    void display();
3}
4
5class RealImage implements Image {
6    @Override
7    public void display() {
8        // 实际加载图片
9    }
10}
11
12class ProxyImage implements Image {  // 代理类也实现相同接口
13    private RealImage realImage;
14    
15    @Override
16    public void display() {
17        if (realImage == null) {
18            realImage = new RealImage();  // 延迟加载
19        }
20        realImage.display();
21    }
22}
23

接口思维:代理类和真实类实现相同的接口,客户端无感知。

三、在创建型模式中的体现

1. 工厂方法模式(Factory Method)

1interface Product {
2    void use();
3}
4
5interface Creator {
6    Product createProduct();  // 工厂方法 - 返回接口
7}
8
9class ConcreteCreator implements Creator {
10    @Override
11    public Product createProduct() {
12        return new ConcreteProduct();  // 返回具体产品,但声明为Product接口
13    }
14}
15

接口思维:工厂返回接口类型,客户端不依赖具体产品类。

2. 抽象工厂模式(Abstract Factory)

1interface GUIFactory {
2    Button createButton();
3    Checkbox createCheckbox();
4}
5
6interface Button {
7    void paint();
8}
9
10// 客户端代码
11class Application {
12    private Button button;
13    
14    public Application(GUIFactory factory) {  // 依赖工厂接口
15        button = factory.createButton();
16    }
17}
18

接口思维:整套产品族通过接口定义,具体工厂实现接口。

四、面向接口编程的层次

第一层:技术实现

1// 简单的接口定义与实现
2interface A { void doSomething(); }
3class B implements A { ... }
4

第二层:设计模式

1// 模式级别的接口应用
2// 1. 策略模式:定义算法族,使其可以互换
3// 2. 观察者模式:定义发布-订阅的通信机制
4// 3. 命令模式:将请求封装为对象
5// 4. 状态模式:将状态抽象为接口
6

第三层:架构思想

1// 系统架构层面的接口
2// - 依赖倒置:高层模块不依赖低层模块,都依赖抽象
3// - 接口隔离:多个专用接口优于一个通用接口
4// - 六边形架构:通过端口(接口)与外部世界通信
5

五、实际项目中的应用启示

何时选择哪种模式?

场景适合的模式接口的作用
算法可互换策略模式定义算法接口
对象状态变化状态模式定义状态接口
请求需要封装命令模式定义命令接口
解耦通知机制观察者模式定义观察者接口
统一不同接口适配器模式定义目标接口
延迟/控制访问代理模式定义主体接口

一个综合示例:电商订单系统

1// 策略模式:不同的折扣策略
2interface DiscountStrategy {
3    double calculateDiscount(Order order);
4}
5
6// 状态模式:订单状态
7interface OrderState {
8    void next(Order order);
9    void previous(Order order);
10    void process(Order order);
11}
12
13// 观察者模式:订单状态通知
14interface OrderObserver {
15    void update(Order order);
16}
17
18// 命令模式:订单操作
19interface OrderCommand {
20    void execute();
21    void undo();
22}
23

总结

面向接口编程是贯穿所有设计模式的灵魂思想

  1. 策略模式:最直接的体现,但远不止于此
  2. 行为型模式中大部分都基于接口:
    • 观察者、命令、状态、策略等核心都是接口抽象
  3. 结构型模式通过接口实现结构解耦:
    • 适配器统一接口,桥接分离抽象与实现
  4. 创建型模式通过接口隐藏创建细节

核心思想:面向接口编程不仅仅是写一个interface,而是:

  • 依赖抽象,而不是具体
  • 定义契约,而不是实现
  • 关注能做什么,而不是怎么做

这在GoF的23种设计模式中都有深刻体现,是面向对象设计的精髓所在。


设计模式和设计原则-中高级架构思路-面向接口编程》 是转载文章,点击查看原文


相关推荐


你以为 Props 只是传参? 不,它是 React 组件设计的“灵魂系统”
白兰地空瓶2025/12/22

90% 的 React 初学者,都低估了 Props。 他们以为它只是“从父组件往子组件传点数据”。 但真正写过复杂组件、设计过通用组件的人都知道一句话: Props 决定了一个组件“好不好用”,而不是“能不能用”。 这篇文章,我们不讲 API 清单、不背概念, 而是围绕 Props 系统的 5 个核心能力,一次性讲透 React 组件化的底层逻辑: Props 传递 Props 解构 默认值(defaultProps / 默认参数) 类型校验(PropTypes) children 插


前端跨页面通讯终极指南⑥:SharedWorker 用法全解析
一诺滚雪球2025/12/14

前言 前面的文章已经介绍了postMessage、localStorage、messageChannel、broadcastChannel以及window.name。今天要介绍一种“多页面协同”场景的工具——SharedWorker。 不同于普通Worker只能被单个页面独占,SharedWorker能被同一域名下的多个页面共享,实现高效的“多页面数据中枢”。本文就带你了解SharedWorker跨页面通讯的核心用法。 1. 什么是SharedWorker? 在介绍SharedWorker之前,


智能家政系统架构设计与核心模块解析
小码哥0682025/12/5

一、开发背景           上班族家庭:由于工作繁忙,无暇顾及家务,对日常保洁、家电清洗等便捷高效的家政服务需求强烈,希望能够通过简单的操作,在合适的时间预约到专业的家政人员上门服务,并且对服务质量和服务人员的专业性有较高要求         一些企业为员工提供福利,会定期采购家政服务,如办公室清洁、企业食堂后勤服务等;同时,医疗机构、学校、酒店等也需要专业的家政服务来保障环境清洁和卫生维护,对服务的标准化、规模化有较高要求。 二、家政服务平台技术分析 前端展示层      


HarmonyOS一杯冰美式的时间 -- FullScreenLaunchComponent
猫猫头啊2026/1/9

一、前言 最近在开发中,我们的元服务需要被其他应用通过FullScreenLaunchComponent拉起,我只能说当时上了5.0的当,FullScreenLaunchComponent也是Beta版本的!在实际开发中作为碰了几次灰,踩了不少坑,觉得有必要分享下,故有了此篇文章。 该系列依旧会带着大家,了解,开阔一些不怎么热门的API,也可能是偷偷被更新的API,也可以是好玩的,藏在官方文档的边边角角~当然也会有一些API,之前是我们辛辛苦苦的手撸代码,现在有一个API能帮我们快速实现的,希望


Monorepo入门
Hyyy2026/1/17

1. Monorepo 介绍 核心价值:把“需要一起演进的一组项目”放在同一个版本空间里,从而让跨项目改动(API 变更、重构、升级)能在一次提交里完成并验证 Monorepo 是把多个相关项目/包放在同一个 Git 仓库中管理的策略,有助于跨项目联动修改、内部包共享更顺畅、统一规范与 CI、版本控制、构建和部署等方面的复杂性,并提供更好的可重用性和协作性。 Monorepo 提倡了开放、透明、共享的组织文化,这种方法已经被很多大型公司广泛使用,如 Google、Facebook 和 Mic


Linux软件安装 —— Flink集群安装(集成Zookeeper、Hadoop高可用)
吱唔猪~2026/1/25

文章目录 一、节点说明二、配置节点间免密登录三、JDK安装四、Zookeeper安装五、Hadoop安装六、Flink安装1、基础环境准备(1)下载安装包(2)上传并解压 2、修改配置(1)配置zookeeper(2)配置flink-conf.yaml(3)配置workers(4)创建必要的目录(5)配置环境变量 3、分发flink 七、集群测试1、启动zookeeper,hadoop2、Yarn Session测试(1)模式介绍(2)准备测试资源

首页编辑器站点地图

本站内容在 CC BY-SA 4.0 协议下发布

Copyright © 2026 XYZ博客