大话设计模式C语言之适配器模式

适配器模式

适配器模式 (AdapterPattern) 适配器模式是一种结构型设计模式,可以将一个类的接口转换成客户希望的另外一个接口,它能使接口不兼容的对象能够相互合作。

案例代码

客户端接口 logger.h

客户端接口(Client Interface)描述了其他类与客户端代码合作时必须遵循的协议。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#ifndef LOGGER_H
#define LOGGER_H

typedef struct Logger Logger;

/* 统一接口 */
void logger_write(Logger *logger, const char *message);

/* 统一销毁 */
void logger_destroy(Logger *logger);

/* 工厂方法 */
Logger *console_logger_create(void);
Logger *legacy_logger_adapter_create(void);


#endif

某个新服务具体实现 console_logger.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <stdio.h>
#include <stdlib.h>
#include "logger.h"

struct Logger {
void (*write)(Logger *, const char *);
void (*destroy)(Logger *);
};

/* ---------------- Console 实现 ---------------- */

static void console_write(Logger *self, const char *msg) {
(void)self;
printf("[Console] %s\n", msg);
}

static void console_destroy(Logger *self) {
free(self);
}

Logger *console_logger_create(void) {
Logger *logger = malloc(sizeof(*logger));
if (!logger) return NULL;

logger->write = console_write;
logger->destroy = console_destroy;

return logger;
}

/* ---------------- 通用接口 ---------------- */

void logger_write(Logger *logger, const char *message) {
if (logger && logger->write) {
logger->write(logger, message);
}
}

void logger_destroy(Logger *logger) {
if (logger && logger->destroy) {
logger->destroy(logger);
}
}

旧服务接口 legacy_logger.h

服务 (Service)中有一些功能类(通常来自第三方或遗留系统)。客户端与其接口不兼容,因此无法直接调用其功能。

1
2
3
4
5
6
7
#ifndef LEGACY_LOGGER_H
#define LEGACY_LOGGER_H

void legacy_log_output(const char *text);

#endif

模拟旧服务实现 legacy_logger.c

1
2
3
4
5
6
7
#include <stdio.h>
#include "legacy_logger.h"

void legacy_log_output(const char *text) {
printf("[Legacy System] >>> %s <<<\n", text);
}

适配器实现 legacy_logger_adapter.c

适配器(Adapter)是一个可以同时与客户端和服务交互的类:它在实现客户端接口的同时封装了服务对象。适配器接受客户端通过适配器接口发起的调用,并将其转换为适用于被封装服务对象的调用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <stdlib.h>
#include "logger.h"
#include "legacy_logger.h"

/* Logger 抽象结构必须与 console_logger.c 一致 */
struct Logger {
void (*write)(Logger *, const char *);
void (*destroy)(Logger *);
};

/* ---------------- Adapter 实现 ---------------- */

typedef struct {
struct Logger base; /* 继承 */
} LegacyLoggerAdapter;

static void adapter_write(Logger *self, const char *msg) {
(void)self;
legacy_log_output(msg); /* 转换调用 */
}

static void adapter_destroy(Logger *self) {
free(self);
}

Logger *legacy_logger_adapter_create(void) {
LegacyLoggerAdapter *adapter =
malloc(sizeof(*adapter));
if (!adapter) return NULL;

adapter->base.write = adapter_write;
adapter->base.destroy = adapter_destroy;

return (Logger *)adapter;
}

测试客户端代码 main.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include "logger.h"

int main(void) {
Logger *console = console_logger_create();
Logger *legacy = legacy_logger_adapter_create();

logger_write(console, "Hello Console");
logger_write(legacy, "Hello Legacy");

logger_destroy(console);
logger_destroy(legacy);

while (1);
return 0;
}

总结

   适配器模式允许你创建一个中间层类, 其可作为代码与遗留类、 第三方类或提供怪异接口的类之间的转换器。