【C语言中的设计模式】:应用于飞机票订票系统的高级编程技巧
发布时间: 2024-12-16 10:57:30 订阅数: 5
简易C语言航空订票系统.rar
5星 · 资源好评率100%
![【C语言中的设计模式】:应用于飞机票订票系统的高级编程技巧](https://xerostory.com/wp-content/uploads/2024/04/Singleton-Design-Pattern-1024x576.png)
参考资源链接:[C语言实现的飞机票预订系统源代码](https://wenku.csdn.net/doc/6b90kokus9?spm=1055.2635.3001.10343)
# 1. 设计模式概述与C语言结合的重要性
设计模式是软件开发中的一组被广泛认可的解决方案,用于解决特定设计问题。它们是软件工程领域的一种“最佳实践”,帮助开发人员以可预测和高效的方式构建可维护、灵活的软件系统。C语言是一种高效的编程语言,广泛应用于系统编程、嵌入式开发和操作系统等领域。尽管它不是面向对象的,但将设计模式应用于C语言程序中,可以实现代码复用、提高系统可扩展性,并增强系统设计的清晰度。
设计模式在C语言中实现起来可能没有在Java或C#等面向对象的语言中那么直接,但通过对结构和函数指针的巧妙使用,仍然可以实现设计模式的核心原则。下一章节将深入探讨这些原则在C语言中的具体实现。
## 1.1 设计模式的基本分类
设计模式通常分为以下三大类:
- **创建型模式**:提供创建对象的最佳方式。例如:工厂模式、单例模式、建造者模式等。
- **结构型模式**:关注如何组合类和对象以获得更大的结构。例如:适配器模式、代理模式、装饰器模式等。
- **行为型模式**:涉及算法和对象间的职责分配。例如:观察者模式、策略模式、命令模式等。
在C语言中,实现这些模式需要对C语言的内存管理、函数指针等概念有深刻理解,这将在后续章节中详细讲解。
# 2. 面向对象的设计模式在C语言中的实现
在C语言中实现面向对象的设计模式可能会让人感到有些矛盾,因为C语言本身并不支持面向对象编程(OOP)的特性,如类和继承。但是,通过结构体(structs)、函数指针和其他高级编程技术,我们仍然能够以模拟面向对象的方式实现设计模式。
## 2.1 创建型设计模式
创建型模式主要关注对象的创建过程,它们帮助设计一个系统,让系统在不直接指定要创建对象的类的情况下创建对象。在C语言中,我们将探讨如何实现几种常见的创建型设计模式。
### 2.1.1 工厂模式的原理与C语言实现
工厂模式提供了一种创建对象的最佳方式。在工厂模式中,创建对象的代码从直接调用构造函数中分离出来,以便在程序运行时,可以根据需要创建对象。
#### C语言实现
在C中,我们可以使用函数指针来模拟工厂模式。下面的代码段创建了一个`create_shape`工厂函数,它根据传入的参数决定要创建的形状,并返回一个指向形状的指针。
```c
#include <stdio.h>
#include <stdlib.h>
// 定义形状的结构体
typedef struct Shape {
void (*draw)(struct Shape*); // 绘制形状的函数指针
} Shape;
// 绘制圆形的函数
void draw_circle(Shape* s) {
printf("Drawing circle\n");
}
// 绘制方形的函数
void draw_square(Shape* s) {
printf("Drawing square\n");
}
// 形状创建工厂
Shape* create_shape(const char* shape_type) {
Shape* shape = malloc(sizeof(Shape));
if (shape == NULL) {
exit(1); // 处理内存分配失败的情况
}
if (strcmp(shape_type, "circle") == 0) {
shape->draw = draw_circle;
} else if (strcmp(shape_type, "square") == 0) {
shape->draw = draw_square;
} else {
free(shape);
return NULL; // 无效的形状类型
}
return shape;
}
int main() {
Shape* circle = create_shape("circle");
Shape* square = create_shape("square");
if (circle != NULL) {
circle->draw(circle);
free(circle);
}
if (square != NULL) {
square->draw(square);
free(square);
}
return 0;
}
```
这个例子中,`create_shape`函数根据输入的类型("circle"或"square")来决定创建哪种类型的形状对象,并返回一个指向该形状的指针。每个形状都有一个`draw`方法,当调用这个方法时,它将绘制相应的形状。
### 2.1.2 单例模式的原理与C语言实现
单例模式保证一个类只有一个实例,并提供一个全局访问点。虽然C语言不支持类,但我们可以通过全局变量和静态函数来实现单例模式。
#### C语言实现
```c
#include <stdio.h>
#include <stdlib.h>
// 单例结构体
typedef struct Singleton {
int value;
static struct Singleton* instance; // 指向实例的静态指针
void (*set_value)(int); // 设置值的函数指针
} Singleton;
// 静态实例初始化
Singleton* Singleton::instance = NULL;
// 初始化单例
void Singleton_init(int value) {
if (instance == NULL) {
instance = (Singleton*)malloc(sizeof(Singleton));
if (instance == NULL) {
exit(1);
}
instance->value = value;
instance->set_value = &Singleton_set_value;
}
}
// 设置值的方法
void Singleton_set_value(int value) {
if (instance != NULL) {
instance->value = value;
}
}
// 获取单例实例
Singleton* Singleton_get_instance() {
return Singleton::instance;
}
int main() {
// 初始化单例对象
Singleton_init(42);
// 获取实例并设置值
Singleton* singleton = Singleton_get_instance();
singleton->set_value(100);
printf("Singleton value: %d\n", singleton->value);
// 释放单例对象的内存
free(singleton);
return 0;
}
```
这段代码定义了一个单例结构体`Singleton`,其中包含一个静态实例指针。通过`Singleton_init`函数可以初始化单例,而`Singleton_get_instance`可以获取已经创建的单例实例。这个单例实例将确保在程序运行期间只有一个。
### 2.1.3 建造者模式的原理与C语言实现
建造者模式将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。在C语言中,我们通常通过设置和获取结构体字段来构建复杂对象。
#### C语言实现
```c
#include <stdio.h>
#include <stdlib.h>
typedef struct Product {
char** parts;
size_t parts_count;
} Product;
typedef struct Builder {
Product* product;
void (*add_part)(struct Builder*, const char*);
} Builder;
void product_add_part(Product* p, const char* part) {
p->parts_count++;
p->parts = realloc(p->parts, p->parts_count * sizeof(char*));
p->parts[p->parts_count - 1] = strdup(part);
}
void builder_init(Builder* b) {
b->product = (Product*)malloc(sizeof(Product));
if (b->product == NULL) {
exit(1);
}
b->product->parts = NULL;
b->product->parts_count = 0;
b->add_part = &product_add_part;
}
Product* builder_build(Builder* b) {
return b->product;
}
int main() {
Builder builder;
builder_init(&builder);
builder.
```
0
0