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图

总结

  • 适配器使用场景?
    想使用一个已经存在的类,但如果它的接口,也就是它的方法和你的要求不相同时,就应该考虑用适配器模式。即两个类所做的事情相同或相似,但是具有不同的接口时要使用它。使客户代码可以统一调用同一接口。但注意要在双方都不太容易修改的时候再使用适配器模式适配,而不是一有不同时就使用它。
相关推荐
博风14 小时前
8、设计模式应用举例:适配器模式:Iterator接口与Enumeration接口
设计模式·适配器模式
高晶16 小时前
ARM 嵌入式 Linux 系统 U-Boot 开发与移植实战M
设计模式·程序员
geovindu21 小时前
rust: Chain of Responsibility Pattern
开发语言·后端·设计模式·rust·责任链模式·行为模式
拆房老料1 天前
【第四部分:Agentic 智能体设计模式】15.为什么 Agent 也需要设计模式
人工智能·设计模式·ai·ai-native
geovindu1 天前
rust: Chain of Responsibility Pattern (续)
开发语言·后端·设计模式·rust·责任链模式·行为模式
Lost of 程序猿1 天前
责任链模式实战:审批流里“层层把关“的艺术
后端·设计模式·asp.net·责任链模式
希洛兔2 天前
状态模式详解:让对象随内部状态自动改变行为
java·设计模式·状态模式
博风2 天前
7、设计模式应用举例:策略模式:加密、解密文件
设计模式·策略模式
4SAPI2 天前
Provider Adapter设计模式:如何让AI应用支持多个模型
网络·人工智能·设计模式
geovindu2 天前
rust: pool Pattern
开发语言·后端·设计模式·rust·对象池简写模式