2025/9/24日 每日总结 设计模式实践:双向适配器模式之"猫狗互学技能"案例解析

设计模式实践:双向适配器模式之"猫狗互学技能"案例解析

在软件开发中,经常会遇到两个已存在的接口因设计不同而无法直接协作的问题。适配器模式作为一种经典的结构型设计模式,能够在不修改原有代码的前提下,让不兼容的接口相互配合。本文将通过"猫学狗叫、狗学猫抓老鼠"的趣味案例,详细拆解双向适配器模式的实现逻辑与应用场景。

一、实验背景与需求

本次实践的核心需求是构建一个双向适配器,实现两种不同动物接口的技能互通:

  1. 猫(Cat)接口原有行为:叫(cry)、抓老鼠(catchMouse)

  2. 狗(Dog)接口原有行为:叫(wang)、行动(action)

  3. 适配目标:让猫能学狗叫,让狗能学猫抓老鼠

  4. 约束:不修改Cat和Dog的原有接口及实现类,保持原有功能不变

二、双向适配器模式核心结构

双向适配器模式的关键在于适配器类同时实现两个目标接口,并持有两个接口的实例引用,通过转发调用实现双向适配。本次案例的结构设计如下:

1. 核心组件划分

组件类型 具体实现 职责描述
目标接口A Cat 定义猫的行为规范(cry、catchMouse)
目标接口B Dog 定义狗的行为规范(wang、action)
具体实现类A ConcreteCat 实现Cat接口的原生行为
具体实现类B ConcreteDog 实现Dog接口的原生行为
双向适配器 Adapter 同时实现Cat和Dog接口,持有两个接口实例,实现行为转发

2. 类图结构

┌───────────────┐ ┌───────────────┐
│ Cat │ │ Dog │
├───────────────┤ ├───────────────┤
│ + cry() │ │ + wang() │
│ + catchMouse()│ │ + action() │
└───────────────┘ └───────────────┘
▲ ▲
│ │
└───────────┬───────────┘
│
┌───────────────┐
│ Adapter │
├───────────────┤
│ - cat: Cat │
│ - dog: Dog │
│ + setCat() │
│ + setDog() │
│ + cry() │ // 适配Cat接口,转发为Dog的wang()
│ + catchMouse()│ // 保留Cat原生行为
│ + wang() │ // 保留Dog原生行为
│ + action() │ // 适配Dog接口,转发为Cat的catchMouse()
└───────────────┘
│
┌─────────┴─────────┐
▼ ▼
┌───────────────┐ ┌───────────────┐
│ConcreteCat │ │ConcreteDog │
├───────────────┤ ├───────────────┤
│ + cry() │ │ + wang() │
│ + catchMouse()│ │ + action() │
└───────────────┘ └───────────────┘

三、完整实现代码

1. 核心接口定义

Cat接口(猫行为规范)

/**
* 猫接口,定义猫的基础行为
*/
public interface Cat {
// 猫叫
void cry();

// 猫抓老鼠
void catchMouse();
}

#### Dog接口(狗行为规范)
```java
/**
 * 狗接口,定义狗的基础行为
 */
public interface Dog {
 // 狗叫
 void wang();

// 狗行动
 void action();
}

2. 接口实现类(原生行为)

具体猫类:ConcreteCat.java

/**
 * 猫接口的具体实现,实现猫的原生行为
 */
public class ConcreteCat implements Cat {
 @Override
 public void cry() {
 System.out.println("猫叫");
 }

@Override
 public void catchMouse() {
 System.out.println("猫抓老鼠");
 }
}

具体狗类:ConcreteDog.java

/**
 * 狗接口的具体实现,实现狗的原生行为
 */
public class ConcreteDog implements Dog {
 @Override
 public void wang() {
 System.out.println("狗叫");
 }

@Override
 public void action() {
 System.out.println("狗行动");
 }
}

3. 双向适配器类:Adapter.java

/**
 * 双向适配器,同时实现Cat和Dog接口,实现技能互通
 */
public class Adapter implements Dog, Cat {
 // 持有Cat和Dog的实例引用
 private Cat cat;
 private Dog dog;

// Getter和Setter方法
 public Cat getCat() {
 return cat;
 }

public void setCat(Cat cat) {
 this.cat = cat;
 }

public Dog getDog() {
 return dog;
 }

public void setDog(Dog dog) {
 this.dog = dog;
 }

// 实现Cat接口的cry():猫学狗叫
 @Override
 public void cry() {
 System.out.print("猫学");
 dog.wang(); // 转发为Dog的wang()方法
 }

// 实现Cat接口的catchMouse():保留猫的原生行为
 @Override
 public void catchMouse() {
 cat.catchMouse();
 }

// 实现Dog接口的wang():保留狗的原生行为
 @Override
 public void wang() {
 dog.wang();
 }

// 实现Dog接口的action():狗学猫抓老鼠
 @Override
 public void action() {
 System.out.print("狗学");
 cat.catchMouse(); // 转发为Cat的catchMouse()方法
 }
}

4. 测试类:Test.java

/**
 * 测试类,验证双向适配器的功能
 */
public class Test {
 public static void main(String args[]) {
 // 创建原生实例
 Cat cat1 = new ConcreteCat();
 Dog dog1 = new ConcreteDog();

// 创建双向适配器并设置适配对象
 Adapter adapter = new Adapter();
 adapter.setCat(cat1);
 adapter.setDog(dog1);

System.out.println("=== 猫的行为测试 ===");
 // 猫的原生行为:抓老鼠
 cat1 = (Cat) adapter;
 cat1.catchMouse();
 // 猫的适配行为:学狗叫
 cat1.cry();

System.out.println("\n=== 狗的行为测试 ===");
 // 狗的适配行为:学猫抓老鼠
 dog1 = (Dog) adapter;
 dog1.action();
 // 狗的原生行为:叫
 dog1.wang();
 }
}

四、运行结果

=== 猫的行为测试 ===
猫抓老鼠
猫学狗叫
=== 狗的行为测试 ===
狗学猫抓老鼠
狗叫

从运行结果可以看出:

  1. 猫保留了原生的"抓老鼠"行为,同时通过适配器获得了"学狗叫"的新能力

  2. 狗保留了原生的"狗叫"行为,同时通过适配器获得了"学猫抓老鼠"的新能力

  3. 原有接口和实现类的代码未做任何修改,完全符合开闭原则

五、双向适配器模式核心优势

  1. 双向兼容:一个适配器同时解决两个接口的兼容性问题,实现双向通信

  2. 低耦合:无需修改原有接口和实现类,将适配逻辑集中在适配器中,降低系统耦合

  3. 透明性:客户端可以像使用原生接口一样使用适配器,无需关注适配细节

  4. 高复用:适配器可以在多个场景中重复使用,提高代码复用率

  5. 符合开闭原则:扩展新的适配功能时,只需修改适配器,无需改动原有系统

六、适用场景总结

双向适配器模式特别适合以下场景:

  • 两个已存在的接口需要相互协作,但接口设计不兼容
  • 希望在不修改原有代码的前提下,为两个接口添加互通功能
  • 系统需要同时支持两种不同的接口规范,且要求客户端透明使用
  • 需复用两个接口的实现类,且希望它们能协同工作
    通过本次"猫狗互学技能"的实践案例,深刻体会到双向适配器模式在解决接口兼容性问题时的灵活性。它不仅能让原本不相关的接口相互协作,还能在不破坏原有系统设计的前提下扩展功能,是软件设计中不可或缺的重要模式。在实际开发中,当遇到遗留系统接口适配、第三方组件集成等场景时,双向适配器模式会是一个非常理想的解决方案。
posted @ 2025-12-29 14:31  Moonbeamsc  阅读(28)  评论(0)    收藏  举报
返回顶端