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图

总结

  • 适配器使用场景?
    想使用一个已经存在的类,但如果它的接口,也就是它的方法和你的要求不相同时,就应该考虑用适配器模式。即两个类所做的事情相同或相似,但是具有不同的接口时要使用它。使客户代码可以统一调用同一接口。但注意要在双方都不太容易修改的时候再使用适配器模式适配,而不是一有不同时就使用它。
相关推荐
看山是山_Lau10 小时前
建造者模式:复杂对象如何一步步构建
设计模式·建造者模式
霸道流氓气质10 小时前
业务链路追踪日志设计模式 — 从原理到实践
设计模式
nnsix1 天前
设计模式 - 建造者模式 笔记
笔记·设计模式·建造者模式
cui17875681 天前
矩阵拼团 + 复购拼团:新零售最稳的复购模式,规则简单
大数据·人工智能·设计模式·零售
百珏1 天前
[灰度发布]:全链路透传组件:APM、自研方案与 Java Agent 的实现取舍
后端·设计模式·架构
likerhood1 天前
设计模式 · 享元模式(Flyweight Pattern)java
java·设计模式·享元模式
AI大法师1 天前
从 Adobe 焕新看品牌系统升级:Logo、主色、字体与产品体验如何重新对齐
大数据·人工智能·adobe·设计模式
贵慜_Derek1 天前
《从零实现 Agent 系统》连载 03|控制循环:感知—决策—行动—反思
人工智能·设计模式·架构
nnsix1 天前
设计模式 - 原型模式 笔记
笔记·设计模式·原型模式
nnsix1 天前
设计模式 - 适配器模式 笔记
笔记·设计模式·适配器模式