代码的工厂模式是一种设计模式,用于创建对象实例而无需直接调用构造函数。它提供了一种更加灵活和可维护的方式来创建对象,尤其是在需要根据不同情况创建不同类型的对象时非常有用。工厂模式隐藏了对象的创建细节,使代码更加模块化和可扩展。
工厂方法(Factory Method):这是一个方法或函数,负责创建对象实例。工厂方法通常接受一些参数,根据这些参数来确定应该创建哪种类型的对象。
产品(Product):产品是工厂方法创建的对象实例。产品通常是某个类的实例。
具体工厂(Concrete Factory):具体工厂是实际执行对象创建的类或函数。每个具体工厂通常负责创建特定类型的产品。
具体产品(Concrete Product):具体产品是由具体工厂创建的对象实例,它们是产品的具体实现。
封装对象创建过程:工厂模式将对象的创建逻辑封装在一个函数或类中,使客户端代码无需关心对象的具体创建方式。这可以减少代码的重复性,提高代码的可维护性和可读性。
灵活性:通过工厂模式,可以轻松地更改对象的创建方式,例如切换到不同的实现类或版本,而无需修改大量客户端代码。
解耦合:工厂模式有助于减少类之间的直接依赖关系。客户端代码不需要了解对象的具体类,只需与工厂接口或函数交互。这降低了耦合度,使系统更容易维护和扩展。
单一职责原则:工厂模式有助于遵循单一职责原则,因为它将对象的创建职责从客户端代码中分离出来,并将其委托给专门的工厂类或函数。
代码组织:工厂模式可以帮助组织代码,将对象创建逻辑集中在一个地方,使代码更加结构化和清晰。
测试和调试:工厂模式使得在单元测试中更容易替换模拟对象,从而更容易进行单元测试和调试。
总之,工厂模式是一种设计模式,有助于提高代码的可维护性、可扩展性和可测试性,同时降低了代码的耦合度,是面向对象编程中常用的一种设计方法之一。
- #include
-
- struct Animal
- {
- char name[128];
- int age;
- int sex;
- int others;
- void (*peat)();
- void (*pbeat)();
- void (*test)();
- };
-
- void dogEat()
- {
- printf("狗吃屎\n");
- }
- void catEat()
- {
- printf("猫吃鱼\n");
- }
- void personEat()
- {
- printf("人吃米\n");
- }
- /
- void dogBeat()
- {
- printf("狗咬你\n");
- }
- void catBeat()
- {
- printf("猫咬你\n");
- }
- void personBeat()
- {
- printf("人打你\n");
- }
- int main()
- {
- struct Animal dog = {
- .peat = dogEat,
- .pbeat = dogBeat,
- };
- struct Animal cat = {
- .peat = catEat,
- .pbeat = catBeat,
- };
- struct Animal person = {
- .peat = personEat,
- .pbeat = personBeat,
- };
- dog.peat();
- cat.peat();
- person.peat();
-
- dog.pbeat();
- cat.pbeat();
- person.pbeat();
-
- return 0;
- }
自行分开成一个个子文件
- #include
-
- // 定义动物结构体
- struct Animal
- {
- char name[128];
- int age;
- int sex;
- int others;
- void (*eat)();
- void (*beat)();
- };
-
- // 定义不同类型的吃函数
- void dogEat()
- {
- printf("狗吃屎\n");
- }
-
- void catEat()
- {
- printf("猫吃鱼\n");
- }
-
- void personEat()
- {
- printf("人吃米\n");
- }
-
- // 定义不同类型的打函数
- void dogBeat()
- {
- printf("狗咬你\n");
- }
-
- void catBeat()
- {
- printf("猫咬你\n");
- }
-
- void personBeat()
- {
- printf("人打你\n");
- }
-
- // 创建动物工厂函数
- struct Animal createAnimal(void (*eatFunc)(), void (*beatFunc)())
- {
- struct Animal animal;
- animal.eat = eatFunc;
- animal.beat = beatFunc;
- return animal;
- }
-
- int main()
- {
- // 使用工厂函数创建不同类型的动物对象
- struct Animal dog = createAnimal(dogEat, dogBeat);
- struct Animal cat = createAnimal(catEat, catBeat);
- struct Animal person = createAnimal(personEat, personBeat);
-
- // 调用动物对象的方法
- dog.eat();
- cat.eat();
- person.eat();
-
- dog.beat();
- cat.beat();
- person.beat();
-
- return 0;
- }
在上面的代码中,我们创建了一个createAnimal函数,它接受两个函数指针作为参数,并返回一个初始化好的动物对象。然后,在main函数中,我们使用createAnimal函数来创建不同类型的动物对象,然后调用它们的吃和打方法。这样就实现了工厂模式,使得创建和使用不同类型的动物对象更加灵活和可维护。
抽象对象类型:在代码中,抽象对象类型是struct Animal,它定义了动物对象的通用属性和行为。这个抽象类型充当了工厂模式中的产品。
具体对象类型:不同种类的动物(狗、猫、人)被表示为具体对象类型,每个具体对象类型都有不同的实现,包括吃和打两个行为。这些具体对象类型充当了工厂模式中的具体产品。
工厂函数:createAnimal函数是工厂函数,它接受不同的参数(吃和打的函数指针)来创建不同类型的动物对象。这个工厂函数充当了工厂模式中的工厂,它负责创建具体产品。
客户端代码:在main函数中,客户端代码使用工厂函数来创建不同类型的动物对象,而不需要知道如何构造这些对象的细节。客户端只关心如何使用这些对象,而不关心它们的创建过程。
用链表写法太麻烦,也发出来吧。
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
-
- // 定义动物结构体
- struct Animal
- {
- char name[128]; // 动物的名字
- void (*peat)(); // 吃的行为函数指针
- void (*pbeat)(); // 攻击的行为函数指针
- struct Animal *next; // 指向下一个动物的指针
- };
-
- // dog
- void dogEat()
- {
- printf("狗吃屎\n");
- }
- void dogBeat()
- {
- printf("狗咬你\n");
- }
- struct Animal dog = {
- .name = "Pike",
- .peat = dogEat,
- .pbeat = dogBeat,
- .next = NULL
- };
-
- // cat
- void catEat()
- {
- printf("猫吃鱼\n");
- }
- void catBeat()
- {
- printf("猫咬你\n");
- }
- struct Animal cat = {
- .name = "Tom",
- .peat = catEat,
- .pbeat = catBeat,
- .next = NULL
- };
-
- // person
- void personEat()
- {
- printf("人吃米\n");
- }
- void personBeat()
- {
- printf("人打你\n");
- }
- struct Animal person = {
- .name = "Lihua",
- .peat = personEat,
- .pbeat = personBeat,
- .next = NULL
- };
-
- // 向链表中添加动物
- struct Animal *putAnimal(struct Animal *phead, struct Animal *animal)
- {
- if (phead == NULL)
- {
- phead = animal;
- }
- else
- {
- animal->next = phead;
- phead = animal;
- }
- return phead;
- }
-
- // 根据名字查找动物
- struct Animal *findName(char *str, struct Animal *phead)
- {
- struct Animal *tmp = phead;
-
- if (phead == NULL)
- {
- return NULL;
- }
- else
- {
- while (tmp != NULL)
- {
- if (strcmp(tmp->name, str) == 0)
- {
- return tmp;
- }
- tmp = tmp->next;
- }
- }
- return NULL;
- }
-
- int main()
- {
- char buf[128] = {'\0'};
- struct Animal *phead = NULL;
- struct Animal *ptmp;
-
- // 向链表中添加动物
- phead = putAnimal(phead, &dog);
- phead = putAnimal(phead, &cat);
- phead = putAnimal(phead, &person);
-
- while (1)
- {
- printf("请输入:Pike、Tom、Lihua\n");
- scanf("%s", buf);
- struct Animal *ptmp = findName(buf, phead);
- if (ptmp != NULL)
- {
- printf("姓名:%s\n", ptmp->name);
- ptmp->peat();
- ptmp->pbeat();
- }
- memset(buf, '\0', sizeof(buf));
- }
- return 0;
- }