13.设计模式-适配器模式

适配器模式:将一个类的接口转换成客户希望的另外一个接口

需求

实现火箭队的比赛,教练叫暂停时给后卫、中锋、前锋分配进攻和防守任务的代码。还能通过翻译给不懂语言的外籍球员指令。

代码

业务类

c 复制代码
#include <stdio.h>
#include <stdlib.h>


typedef struct Player {
    char *name;
    void (*attack)(struct Player *);
    void (*defense)(struct Player *);
} Player;
// 前锋
typedef struct Forward {
    Player base;
} Forward;
typedef struct Center {
    Player base;
} Center;
typedef struct Guard {
    Player base;
} Guard;

void ForwardAttack(Player *obj) {
    printf("前锋 %s 进攻\n", obj->name);
}
void ForwardDefense(Player *obj) {
    printf("前锋 %s 防守\n", obj->name);
}
void CenterAttack(Player *obj) {
    printf("中锋 %s 进攻\n", obj->name);
}
void CenterDefense(Player *obj) {
    printf("中锋 %s 防守\n", obj->name);
}
void GuardAttack(Player *obj) {
    printf("后卫 %s 进攻\n", obj->name);
}
void GuardDefense(Player *obj) {
    printf("后卫 %s 防守\n", obj->name);
}

Forward *InitForward(char *name) {
    Forward *obj = (Forward *)malloc(sizeof(Forward));
    obj->base.name = name;
    obj->base.attack = ForwardAttack;
    obj->base.defense = ForwardDefense;
    return obj;
}

Center *InitCenter(char *name) {
    Center *obj = (Center *)malloc(sizeof(Center));
    obj->base.name = name;
    obj->base.attack = CenterAttack;
    obj->base.defense = CenterDefense;
    return obj;
}

Guard *InitGuard(char *name) {
    Guard *obj = (Guard *)malloc(sizeof(Guard));
    obj->base.name = name;
    obj->base.attack = GuardAttack;
    obj->base.defense = GuardDefense;
    return obj;
}

typedef struct ForeignCenter {
    char *name;
    void (*jingong)(struct ForeignCenter *);
    void (*fangshou)(struct ForeignCenter *);
} ForeignCenter;

void ForeignCenterAttack(ForeignCenter *obj) {
    printf("中锋 %s 进攻\n", obj->name);
}
void ForeignCenterDefense(ForeignCenter *obj) {
    printf("中锋 %s 防守\n", obj->name);
}

ForeignCenter *InitForeignCenter(char *name) {
    ForeignCenter *obj = (ForeignCenter *)malloc(sizeof(ForeignCenter));
    obj->name = name;
    obj->jingong = ForeignCenterAttack;
    obj->fangshou = ForeignCenterDefense;
    return obj;
}

适配器类

将外籍球员的jingong,fangshou借口转换为attack,defense接口。

c 复制代码
typedef struct Translator {
    Player base;
    ForeignCenter *fc;
} Translator;

void TranslatorAttack(Player *obj) {
    ((Translator *)obj)->fc->jingong(((Translator *)obj)->fc);
}
void TranslatorDefense(Player *obj) {
    ((Translator *)obj)->fc->fangshou(((Translator *)obj)->fc);
}

Translator *InitTranslator(char *name, char *fcName) {
    Translator *obj = (Translator *)malloc(sizeof(Translator));
    obj->base.name = name;
    obj->base.attack = TranslatorAttack;
    obj->base.defense = TranslatorDefense;
    obj->fc = InitForeignCenter(fcName);
    return obj;
}

客户端

c 复制代码
int main() {
    Forward *kuli = InitForward("kuli");
    kuli->base.attack((Player *)kuli);
    Translator *xiaotiancai = InitTranslator("xiaotiancai", "yaoming");
    xiaotiancai->base.attack((Player *)xiaotiancai);
    return 0;
}

UML图

总结

  • 适配器使用场景?
    想使用一个已经存在的类,但如果它的接口,也就是它的方法和你的要求不相同时,就应该考虑用适配器模式。即两个类所做的事情相同或相似,但是具有不同的接口时要使用它。使客户代码可以统一调用同一接口。但注意要在双方都不太容易修改的时候再使用适配器模式适配,而不是一有不同时就使用它。
相关推荐
J_liaty1 天前
23种设计模式一代理模式
设计模式·代理模式
苏渡苇1 天前
优雅应对异常,从“try-catch堆砌”到“设计驱动”
java·后端·设计模式·学习方法·责任链模式
短剑重铸之日1 天前
《设计模式》第十一篇:总结
java·后端·设计模式·总结
feasibility.1 天前
AI 编程助手进阶指南:从 Claude Code 到 OpenCode 的工程化经验总结
人工智能·经验分享·设计模式·自动化·agi·skills·opencode
BD_Marathon1 天前
七大设计原则介绍
设计模式
YigAin2 天前
Unity23种设计模式之 享元模式
设计模式·享元模式
范纹杉想快点毕业2 天前
实战级ZYNQ中断状态机FIFO设计
java·开发语言·驱动开发·设计模式·架构·mfc
茂桑2 天前
DDD领域驱动设计-基础设施层
设计模式·架构
小温冲冲2 天前
通俗且全面精讲工厂设计模式
设计模式
进击的小头2 天前
设计模式与C语言高级特性的结合
c语言·设计模式