设计模式之抽象工厂模式

171 阅读1分钟

介绍:

​ 抽象工厂模式是一种创建型设计模式,相比工厂模式来说会稍微复杂一点,工厂模式是对产品进行抽象,而抽象工厂模式不仅仅是对产品进行抽象,同时也对工厂进行了抽象,相当于实现了一个创建其他工厂的超级工厂;


作用:

  • 当需要产品族时,可以保证客户端始终只使用同一个产品的产品族;
  • 增强了程序的可扩展性,当增加一个新的产品族时,不需要修改原来代码;

类比:

​ 一个制造家具的工厂,可以根据用户不同的诉求,制造出不同风格的家具,而家具又分成不同种类,比如说桌子,椅子等;


代码示例:

首先定义出不同类型的家具以供生产:

void modern_chair(void)
{
	printf("A modern chair\r\n");
}

void modern_desk(void)
{
    printf("A modern desk\r\n");
}

void victorian_chair(void)
{
    printf("A victorian chair\r\n");
}

void victorian_desk(void)
{
    printf("A victorian desk\r\n");
}

其次定义出工厂要制作的家具:

typedef struct
{
    void (*chair)(void);
}Chair_t;
 
typedef struct
{
    void (*desk)(void);
}Desk_t;

设计出工厂的具体生产内容:

Chair_t* make_modern_chair(void)
{
    Chair_t* pChair = (Chair_t*)malloc(sizeof(Chair_t));
    assert(pChair != NULL);
    pChair->chair = modern_chair;
    return pChair;
}

Chair_t* make_victorian_chair(void)
{
    Chair_t* pChair = (Chair_t*)malloc(sizeof(Chair_t));
    assert(pChair != NULL);
    pChair->chair = victorian_chair;
    return pChair;
}

Desk_t* make_modern_desk(void)
{
    Desk_t* pDesk = (Desk_t*)malloc(sizeof(Desk_t));
    assert(pDesk != NULL);
    pDesk->desk = modern_desk;
    return pDesk;
}

Desk_t* make_victorian_desk(void)
{
    Desk_t* pDesk = (Desk_t*)malloc(sizeof(Desk_t));
    assert(pDesk != NULL);
    pDesk->desk = victorian_desk;
    return pDesk;
}

接下来将工厂定义出来:

typedef struct
{
	Chair_t (*make_chair)(void);
    Desk_t (*make_desk)(void);
}Furniture_factory;

创建工厂:

Furniture_factory* Creat_furniture_factory(char* type)
{
	Furniture_factory* pFurniture_factory = (Furniture_factory*)malloc(sizeof(Furniture_factory));
    assert(pFurniture_factory != NULL);
    if (memcmp(type, "modern") == 0)
    {
        pFurniture_factory->make_chair = make_modern_chair;
        pFurniture_factory->make_desk = make_modern_desk;
    }
    else if(memcmp(type, "victorian") == 0)
    {
        pFurniture_factory->make_chair = make_victorian_chair;
        pFurniture_factory->make_desk = make_victorian_desk;
    }
    else
    {
        printf("type is invalid\r\n");
    }
}