C语言面向对象设计
一、什么是设计模式
- 设计模式就是软件工程的基石,对于庞大的代码体系结构,都需要通过不同的设计模式来对应。
- 使用设计模式是为了重用代码、让代码更容易被他人理解、保证代码可靠性。特别是对于非常庞大的代码体系结构,也能够更加方便的维护。
- 算法不是设计模式,因为算法致力于解决问题而非设计问题。
- 有23种设计模式,我在智能家居系统设计中使用的是工厂设计模式。
二、什么是类和对象
- 类是一个抽象概念:当我们说到人类,猫类,犬类的时候我们是无法具体到某一个实体的。
- 对象是某一个类的实体,当有对象之后,这些属性就有了属性值,这些行为就有了相应的意义。
三、工厂模式
- 工厂模式(Factory Pattern)是最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
- 在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
- 工厂模式的意图:
3.1 工厂可以理解成最大的企业,是用来创建不同的对象工厂,每个对象在自己内部去实现创建类,并自己可以定义实现不同的类,这些类的创建过程是在各自对象内部实现的,不会对客户暴露创建逻辑。 - 应用实例:
4.1 您需要一辆汽车,可以直接从工厂里面提货,而不用去管这辆汽车是怎么做出来的,以及这个汽车里面的具体实现。 - 工厂模式的优点:
5.1 一个调用者想创建一个对象,只要知道其名称就可以了,因为创建一个对象后,其内部会自动实现类。
5.2 扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。
5.3 屏蔽产品的具体实现,调用者只关心产品的接口。 - 工厂模式缺点:
6.1 每次增加一个产品时,都需要增加一个具体类和对象工厂,对象用于实现具体类,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,这并不是什么好事。 - 注意事项:
7.1 作为一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂方法模式。
7.2 有一点需要注意的地方就是复杂对象适合使用工厂模式,而简单对象,特别是只需要通过 new 就可以完成创建的对象,无需使用工厂模式。
7.3 如果使用工厂模式,就需要引入一个工厂类,会增加系统的复杂度。
四、智能家居中工厂模式的设计
- 创建的工厂:
1.1 指令工厂:包括语音类、tcp类。
1.2 控制工厂:包括灯、火灾报警、串口、红外、人脸锁。
五、代码实现
- mainpro.c:通过工厂对象创建不同的类。
#include "animal.h"
int main(void)
{
struct Animal *phead;
phead = Cat_Insert_Put(phead);
phead = Per_Insert_Put(phead);
phead = Dog_Insert_Put(phead);
printf("phead->name=%s\n" ,phead->name);
return 0;
}
- animal.h:一个工厂对象:
#include <stdio.h>
struct Animal {
char *name;
int age;
void (*eat)();
struct Animal *next;
};
struct Animal *Dog_Insert_Put(struct Animal *head);
struct Animal *Per_Insert_Put(struct Animal *head);
struct Animal *Cat_Insert_Put(struct Animal *head);
- person.c:第一个类。
#include "animal.h"
void per_eat()
{
printf("per eat chiken\n");
}
struct Animal per1 = {
.name = "hei",
.age = 20,
.eat = per_eat,
.next = NULL
};
struct Animal *Per_Insert_Put(struct Animal *head)
{
struct Animal *phead = head;
if(phead == NULL) {
return &per1;
}
else {
per1.next = phead;
return &per1;
}
}
- cat.c:第二个类:
#include "animal.h"
void cat_eat()
{
printf("cat eat fish\n");
}
struct Animal cat1 = {
.name = "hei",
.age = 5,
.eat = cat_eat,
.next = NULL
};
struct Animal *Cat_Insert_Put(struct Animal *head)
{
struct Animal *phead = head;
if(phead == NULL) {
return &cat1;
}
else {
cat1.next = phead;
return &cat1;
}
}
- dog.c:第三个类。
#include "animal.h"
void dog_eat()
{
printf("dog eat baba\n");
}
struct Animal dog1 = {
.name = "huang",
.age = 3,
.eat = dog_eat,
.next = NULL
};
struct Animal *Dog_Insert_Put(struct Animal *head)
{
struct Animal *phead = head;
if(phead == NULL) {
return &dog1;
}
else {
dog1.next = phead;
return &dog1;
}
}