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图

总结

  • 适配器使用场景?
    想使用一个已经存在的类,但如果它的接口,也就是它的方法和你的要求不相同时,就应该考虑用适配器模式。即两个类所做的事情相同或相似,但是具有不同的接口时要使用它。使客户代码可以统一调用同一接口。但注意要在双方都不太容易修改的时候再使用适配器模式适配,而不是一有不同时就使用它。
相关推荐
咖啡八杯1 天前
GoF设计模式——中介者模式
java·后端·spring·设计模式
胡萝卜术2 天前
从“分数打架”到“排名投票”:为什么你的ChatBI必须用RRF?
算法·设计模式·面试
亦暖筑序3 天前
Java 8老系统Browser Agent实战:三层拦截把AI操作后台变成可审计流程
java·后端·设计模式
青禾网络5 天前
Web 前端如何接入 AI 音效生成:从零到可用的完整方案
人工智能·设计模式
ZJPRENO6 天前
吃透软件开发六大设计原则,告别烂代码
设计模式
咖啡八杯6 天前
GoF设计模式——命令模式
java·设计模式·架构
花椒技术6 天前
HJPusher / HJPlayer SDK 实践:我们为什么把直播推播链路拆成一套可复用能力
设计模式·harmonyos·直播
艺艺生辉7 天前
迭代器模式-"我也想被增强for循环"
设计模式
咖啡八杯8 天前
GoF设计模式——策略模式
java·后端·spring·设计模式