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图

总结

  • 适配器使用场景?
    想使用一个已经存在的类,但如果它的接口,也就是它的方法和你的要求不相同时,就应该考虑用适配器模式。即两个类所做的事情相同或相似,但是具有不同的接口时要使用它。使客户代码可以统一调用同一接口。但注意要在双方都不太容易修改的时候再使用适配器模式适配,而不是一有不同时就使用它。
相关推荐
码匠许师傅16 小时前
【设计模式精讲】15.享元模式(Flyweight)
c++·设计模式·享元模式·uml
事圆则缓17 小时前
Android 常用设计模式速查
android·设计模式
码匠许师傅1 天前
【设计模式精讲】14.外观模式(Facade)
c++·设计模式·uml·外观模式
evans在进步1 天前
Java 常用设计模式(二):装饰器、适配器、责任链、模板方法、策略与观察者
java·开发语言·设计模式
码匠许师傅2 天前
【设计模式精讲】13.装饰器模式(Decorator)
c++·设计模式·uml·装饰器模式
evans在进步2 天前
Java 常用设计模式入门:建造者、工厂、单例、外观与代理
java·python·设计模式
字节跳动开源3 天前
VisActor全新图可视化开源项目:VGraph
前端·设计模式·开源
码匠许师傅3 天前
【设计模式精讲】11.桥接模式(Bridge)
c++·设计模式·桥接模式·uml
学习星球4 天前
AI Agent 成本工程实战:从 OpenAI Codex 的 8 个“烧 Token“Bug 学起
人工智能·设计模式·微信小程序
AI人工智能+电脑小能手4 天前
大白话说Java设计模式-46-责任链模式(业务实战篇)
java·设计模式·责任链模式·风控校验·servlet filter·spring interceptor·链式处理