设计模式(简单工厂模式)

设计模式(简单工厂模式)

1.什么是设计模式

从建筑设计领域引入到计算机科学中

设计模式一共有23种

代码设计经验的总结,稳定,拓展性更强。一系列编程思想

作用:代码更容易被他人理解、保证代码可靠性、程序的重用性。

详细介绍:[https://www.runoob.com/design-pattern/design-pattern-tutorial.html]:

学习简单工厂模式的目的:为了代码不那么混乱。让代码更稳定,添加功能更方便

算法:致力于解决问题而非设计问题。

设计模式通常描述了一组相互紧密作用的类与对象。

很多人说,c是一门面向过程的语言,java是一门面向对象的语言;其实这种说法不太对,因为面向过程与面向对象只是一种代码编辑的思想。c也可以面向对象。

2.类和对象

  • 类是一种用户自定义的数据类型,也称为类类型。

  • (C语言中用户自定义的数据类型是结构体。)

  • 对象:类的具象

例子说明:

struct Animal
{
   int age;
   int sex;   //成员属性
   void (*peat)();
   void (*pbeat)(); //成员方法(一些具体的行为:比如某某人做了某某事)
};

struct Animal dog;
struct Animal cat;
struct Animal person; //对上述一种类的具象(即:对象)

一个简单的面向对象例子

OOP1.c

#include

//类:抽象
struct Animal
{
   char name[32];
   int  age;
   int  sex;
   void (*peat)();
   void (*pbeat)();
};

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 cat;   //对象:事物的具象
    struct Animal dog;
    struct Animal person;

    dog.peat=dogEat;  //对象具体的行为
    cat.peat=catEat;
    person.peat=personEat;

    dog.pbeat=dogBeat;
    cat.pbeat=catBeat;
    person.pbeat=personBeat;


    dogEat();
    catEat();
    personEat();

    dogBeat();
    catBeat();
    personBeat();

    return 0; 
}

总结:

类是用户自定义的数据类型。在C语言中是结构体。
类是抽象的,对象能把事物具象化
成员方法是对象的具体行为。做到了事务的具象,每一个对象都有具体的行为

在这里回顾一下函数指针的知识:

每一个函数都有一个入口地址,函数指针是函数的入口地址,而函数名就是函数的地址。
所以把函数指针指向函数名就指向了这个函数。这里说的有点不好,即:声明了这个函数,然后直接调用。

在回顾一下回调函数

定义:
使用者自己定义一个函数,实现这个函数的程序内容,然后把这个函数(入口地址)作为参数传入别人(或系统)的函数中,由别人(或系统)的函数在运行时来调用的函数。

函数是你实现的,但由别人(或系统)的函数在运行时通过参数传递的方式调用,这就是所谓的回调函数。

简单来说,当发生某种事件时,系统或其他函数将会自动调用你定义的一段函数。

示例:

回调函数主要结构有三部分组成:主函数、调用函数和被调函数。C语言中,被调函数通常以函数指针(指向对应函数的入口地址)的形式出现。

//定义回调函数
void PrintfText() 
{
    printf("Hello World!\n");
}
 
//定义实现回调函数的"调用函数"
// 参数为函数指针,无参数返回void
void CallPrintfText(void (*callfuct)())
{
    callfuct();
}
 
//实现函数回调
int main(int argc,char* argv[])
{
    CallPrintfText(PrintfText);
    return 0;
}

2.2C结构体新玩法

2.2.1常用的方法

struct Animal
{
   char name[32];
   int age;
   int sex;
   int others;
   void (*peat)();
   void (*pbeat)();
};

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 cat={"阿黄",18,‘b’,100,dogeat,dogBeat};
    
    return 0;
}

2.2.2新玩法(内核常用)

struct Animal
{
   char name[32];
   int age;
   int sex;
   int others;
   void (*peat)();
   void (*pbeat)();
};

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 cat={
     .peat=catEat;
     .pbeat=catBeat
    };
    
     struct Animal dog={
     .peat=dogEat;
     .pbeat=dogBeat
    };
    
    struct Animal person={
     .peat=personEat;
     .pbeat=personBeat
    };
    
    return 0;
}

3.工厂模式

3.1.什么是工厂模式

工厂模式是最常用的设计模式之一。这种类型的设计模式属于创建型模式,他提供了一种创建对象的最佳方式。

在工厂模式中,我们创建对象时不会对客户端暴露创建逻辑,并且时通过使用一个共同的接口来指向新创建的对象

暴露创建逻辑是:暴露了对象的具体指向和 函数的实现方式。

不在业务中暴露,不在文件中暴露,在其他地方做好,调用。

共同的接口:做好API放到工厂里面,然后mian函数里调用

示例:

dog.c

#include "animal.h"

void dogEat()
{
    printf("狗吃屎\n");
}

void dogBeat()
{
    printf("咬你\n");
}

struct Animal dog={
     .name="huang", 
     .peat=dogEat,
     .pbeat=dogBeat
};

struct Animal* putDogInLink(struct Animal *phead)
{
       if(phead==NULL)
       {
             return &dog;
       }
       else
       {
            dog.next=phead;
            phead=&dog;
            return phead;
       }  
}

cat.c

#include "animal.h"

void catEat()
{
    printf("猫吃鱼\n");
}

void catBeat()
{
    printf("抠你\n");
}

struct Animal cat={
     .name="Tom", 
     .peat=catEat,
     .pbeat=catBeat
};

struct Animal* putCatInLink(struct Animal *phead)
{
       if(phead==NULL)
       {
             return &cat;
       }
       else
       {
            cat.next=phead;
            phead=&cat;
            return phead;
       }  
}

fish.c

#include "animal.h"

void fishEat()
{
    printf("鱼吃料\n");
}

void fishBeat()
{
    printf("瞪你\n");
}

struct Animal fish={
     .name="fish", 
     .peat=fishEat,
     .pbeat=fishBeat
};

struct Animal* putFishInLink(struct Animal *phead)
{
       if(phead==NULL)
       {
             return &fish;
       }
       else
       {
            fish.next=phead;
            phead=&fish;
            return phead;
       }  
}

ma.c

#include "animal.h"

void maEat()
{
    printf("马吃草\n");
}

void maBeat()
{
    printf("踢你\n");
}

struct Animal ma={
     .name="ma", 
     .peat=maEat,
     .pbeat=maBeat
};

struct Animal* putMaInLink(struct Animal *phead)
{
       if(phead==NULL)
       {
             return &ma;
       }
       else
       {
            ma.next=phead;
            phead=&ma;
            return phead;
       }  
}

person.c

#include "animal.h"

void personEat()
{
    printf("人吃米\n");
}

void personBeat()
{
    printf("打你\n");
}

struct Animal person={
     .name="xiaoming", 
     .peat=personEat,
     .pbeat=personBeat
};

struct Animal* putPersonInLink(struct Animal *phead)
{
       if(phead==NULL)
       {
             return &person;
       }
       else
       {
            person.next=phead;
            phead=&person;
            return phead;
       }  
}

mianPro.c

#include "animal.h"

struct Animal* findUtilName(char *str,struct Animal *phead)
{
      struct Animal *ptmp=phead;

      if(phead==NULL)
      {
          printf("链表为空,无法查找\n");
          return NULL;
      }

      while(ptmp!=NULL)
      {    
          // printf("哥,你输的指令是正确的\n");
           if(strcmp(ptmp->name,str)==0)
           {
               return ptmp; 
           }
           ptmp=ptmp->next;         
      }

      printf("你输错了,大哥,指令不对\n");
      return NULL;
}

int main()
{
    char buf[128]={0};
    struct Animal *phead=NULL;
    struct Animal *ptmp=NULL;

    phead=putCatInLink(phead);
    phead=putDogInLink(phead);
    phead=putPersonInLink(phead);
    phead=putMaInLink(phead);
    phead=putFishInLink(phead);

    while(1)
    { 
        memset(buf,0,sizeof(buf));
        printf("please input Tom,huang,xiaoming,ma,fish;quit exit\n");
        scanf("%s",buf);
        ptmp=findUtilName(buf,phead);
        if(ptmp!=NULL)
        {
            ptmp->peat();
            ptmp->pbeat();
        }
        if(strcmp(buf,"quit")==0)
        {
             printf("你已退出\n");
             exit(-1); 
        }
    }


    return 0;
}

animal.h

#include
#include
#include

struct Animal
{
   char name[32];
   int age;
   int sex;
   int others;
   void (*peat)();
   void (*pbeat)();

   struct Animal *next;
};

struct Animal* putCatInLink(struct Animal *phead);
struct Animal* putDogInLink(struct Animal *phead);
struct Animal* putPersonInLink(struct Animal *phead);
struct Animal* putMaInLink(struct Animal *phead);
struct Animal* putFishInLink(struct Animal *phead);

工厂里有猫狗鱼人马,用链表串起来,业务逻辑放在mianpro.c,animal.h暴露出来,然后mianpro调用,这样代码会很稳定,也不乱,一个功能放一个文件

你可能感兴趣的:(设计模式,简单工厂模式)