前言
在前面两篇,我介绍了自己实现的Buffer类,Buffer类是双端的缓冲区,两头都可以加入或取出元素。而在实际使用中可能两头都需要取和放元素的需求并不多。更多的情况是FIFO和LIFO的缓冲区,即队列和栈这两种数据结构。
当然,想要把Buffer类当做FIFO或LIFO只需要自己规定好分别使用Front还是Back来当In或Out用就行了。但是如果你是要和别人合作之类的还是有些不方便,毕竟还要有些先验知识,要是搞错了方向就尴尬了。所以专门为其写一个接口还是蛮有必要的。
下面给出FIFO缓冲区 Queue模块的接口:
模块类图
模块设计思路简介
Queue类同样是使用面向对象的方式,用了一个虚表实现的多态。其方法包括入队In、出队Out和清空Cleanup。因为它也是一个容器,所以也继承自Container类。
实现方面,当然我可以重新写一个实现。但是为了重用现有代码,当然也是因为懒的写。于是直接实验了一下对象适配器,BufferToQueueAdapter类将Buffer实例适配为了Queue实例,即将Buffer实例的BackIn适配为了Queue的In,Buffer实例的FrontOut适配为了Queue的Out,getCount和getCapacity就直接映射,创建时传递的Buffer实例会托管给适配器实例,在适配器被销毁时其会负责销毁适配者。当然会增加一点开销,但是用起来就更得心应手了。
本例可以视作在适配器模式在C语言中的一个示例,可能后面出一个博客专门讲解一下,现在就直接拿着用就好。
编程约定同第一篇,不再说明。
由于直接适配的,类很少,所以相对Buffer系列来说,文件也很少。
示例代码
#include <stdio.h>
#include "BufferMallocArray.h"
#include "BufferToQueueAdapter.h"
static void QueueTest(QueueUINT32 que){
int i;
printf("sizeof que:%u\nIn: 20000000 to 20000009\nOut: ",QueueUINT32_getCapacity(que));
for(i = 0; i < 10; i++)
QueueUINT32_In(que,(i + 20000000));
for(i = 0; i < 10; i++)
printf(" %lu",QueueUINT32_Out(que));
printf("\n");
}
void main(void) {
BufferUINT32 buf;
QueueUINT32 que;
buf = (BufferUINT32)BufferUINT32MallocArray_Create(30);
if(buf != NULL){
que = BufferToQueueAdapter_CreateUINT32(buf);
if(que == NULL){
Buffer_Destroy(buf);
printf("memory run out!\n");
}else{
QueueTest(que);
Queue_Destroy(que);
}
}else{
printf("memory run out!\n");
}
for(;;) {
// 接收字符并回显
c = getchar();
putchar(c);
} /* loop forever */
}
具体代码详见下一篇。