设计模式读书笔记2-简单工厂模式

本文深入讲解简单工厂模式,一种常用创建型设计模式。通过女娲造人的故事生动诠释模式原理,详细剖析模式结构,包括工厂角色、抽象产品角色及具体产品角色。探讨模式优点如良好的封装性和扩展性,以及缺点和适用场景。

简单工厂模式是最常用的一种创建型模式,通常所说的工厂模式一般是指工厂方法模式。本篇是是工厂方法模式的“小弟”,我们可以将其理解为工厂方法模式的预备知识,它不属于GoF23种设计模式,但在软件开发中却也应用地比较频繁。此外,工厂方法模式还有一位“大哥”—抽象工厂模式,会在后面进行介绍。

简单工厂模式(Simple Factory)  学习难度:★★☆☆☆  使用频率:★★★☆☆

1 简单工厂模式概述

1.1 定义

简单工厂(Simple Factory)模式:定义一个工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类。因为在简单工厂模式中用于创建实例的方法是静态(static)方法,因此简单工厂模式又被称为静态工厂方法模式,它属于创建型模式。

简单工厂模式的要点在于:当你需要什么,只需要传入一个正确的参数,就可以获取你所需的对象,而无须知道其创建细节

1.2 通用类方法

381412-20170408225050738-2041684665.png
简单工厂模式包含3个角色:

1. Factory - 工厂角色:该模式的核心,负责实现创建所有产品实例的内部逻辑,提供一个静态的工厂方法GetProduct(),返回抽象产品类型Product的实例。
2. Product - 抽象产品角色:所有产品类的父类,封装了各种产品对象的共有方法,它的引入将提高系统的灵活性,使得在工厂类中只需要定义一个通用的工厂方法,因为所有创建的具体产品对象都是其子类对象。
3. ConcreteProduct -具体产品角色:简单工厂模式的创建目标,所有被创建的对象都充当这个角色的某个具体类的实例。

  在简单工厂模式中,客户端通过工厂类来创建一个产品类的实例,而无须直接使用new关键字来创建对象。(可以看出,它是工厂模式家族中最简单的一员)

2 从女蜗造人说起

  女蜗采用黄图捏成人的形状,然后放入八卦炉中烧制,最后放置到大地上生长,工艺过程没有错,但是意外发生了:

  1. 第一次烤泥人,感觉应该熟了,往大地上一放,哇,没有熟!于是一个白人诞生了!
  2. 第二次烤泥人,上一次没烤熟,这次多烤了一会,放到世间一看,嘿,熟过头了,于是黑人诞生了!
  3. 第三次烤泥人,一边烧一边看,知道表皮微黄,嘿,真正好,于是黄种人诞生了

我们定义每个人都有两个方法:getColor(获取人的皮肤颜色)和talk(交谈),其简化结构图如下
789

抽象产品角色:Human接口

typedef struct _Human Human;
struct _Human
{
    void (*getColor)(void);
    void (*talk)(void);
};

具体产品角色:接口Human是对人类的总称,每个人种都至少有两种方法,黑色人种,白色人种,黄色人种,其代码清单

typedef struct _BlackHuman BlackHuman;
struct _BlackHuman
{
    Human human;
    void (*BlackGetColor)(void);
    void (*BlackTalk)(void);
    void (*BlackHumanDelete)(BlackHuman *pBlackHuman);
};
void BlackGetColor(void)
{
    printf("black get color\n");
}

void BlackTalk(void)
{
    printf("black talk\n");
}

void BlackHumanDelete(BlackHuman *pBlackHuman)
{
    if(!pBlackHuman)
    {
        free(pBlackHuman);
        pBlackHuman = NULL;
    }

    return;
}

BlackHuman *CreateBlackHuman(void)
{
    BlackHuman *pBlackHuman       = (BlackHuman *)malloc(sizeof(BlackHuman));
    pBlackHuman->BlackGetColor    = BlackGetColor;
    pBlackHuman->BlackTalk        = BlackTalk;
    pBlackHuman->BlackHumanDelete = BlackHumanDelete;
    pBlackHuman->human.getColor   = pBlackHuman->BlackGetColor;
    pBlackHuman->human.talk       = pBlackHuman->BlackTalk;

    return pBlackHuman;
}

黄种人,白种人方法如上,所有的人种定义完毕后,下一步就是定义一个八卦炉,然后烧制人类,女蜗下达的命令

给我一个黄种人,而不是给我一个会走,会跑,会说话,皮肤是黄色的人种

工厂角色:作为生产的管理者,只需要知道生产的是什么,不需要食物的具体信息,那么八卦炉生产人类的方法就可以抽象一个Human的接口

typedef struct _AbstractFactory AbstractFactory;
struct _AbstractFactory
{
    Human *(*CreateHuman)(char *pString);
    void (*DeleteHumanFactory)(AbstractFactory *pHumanFactory);
};

其抽象类实现过程

Human *CreateHuman(char *pString)
{
    Human *pHuman = NULL;
    if(0 == strcmp(pString, "Whiteman"))
    {
        pHuman = (Human *)CreateWhiteHuman();
    }
    else if(0 == strcmp(pString, "Blackman"))
    {
        pHuman = (Human *)CreateBlackHuman();
    }
    else if(0 ==  strcmp(pString, "Yellowman"))
    {
        pHuman = (Human *)CreateYellowHuman();
    }
    else
    {
        printf("not support\n");
    }

    
    return pHuman;
}

void DeleteHumanFactory(AbstractFactory *pHumanFactory)
{
    if(NULL != pHumanFactory)
    {
        free(pHumanFactory);
        pHumanFactory = NULL;
    }

    return;
}

AbstractFactory *CreateHumanFactory(void)
{
    AbstractFactory *pAbstractFactory = (AbstractFactory *)malloc(sizeof(AbstractFactory));
    if(!pAbstractFactory)
    {
        return NULL;
    }

    pAbstractFactory->CreateHuman        = CreateHuman;
    pAbstractFactory->DeleteHumanFactory = DeleteHumanFactory;
    
    return pAbstractFactory;
}

客户端代码

int main(void)
{
        Human *pwhiteHuman  = NULL;
        Human *pblackHuman = NULL;
        AbstractFactory *AbstractFactory = CreateHumanFactory();

        pwhiteHuman = AbstractFactory->CreateHuman("Whiteman");
        pwhiteHuman->getColor();
        pwhiteHuman->talk();

        
        pwhiteHuman = AbstractFactory->CreateHuman("Blackman");
        pwhiteHuman->getColor();
        pwhiteHuman->talk();
}

3 简单工厂模式的应用

3.1 简单工厂模式的优点

  1. 良好的封装性,代码结构清晰,一个对象创建时有条件约束的,调用者需要一个具体的产品对象,只需要知道这个产品类名,不需要知道具体的实现细节,降低了代码耦合性
  2. 工厂模式具体良好的扩展性,在新增产品类的情况下,只要适当修改具体的工厂类和扩展一个工厂类
  3. 屏蔽产品类,产品如何实现,如何变化,调用者不需要关心,只需要关系产品接口,只要接口保持不变,系统中的上层模块就不要发生改变
  4. 工厂模式是典型的解耦框架

3.2 简单工厂模式的缺点

  1. 由于工厂类集中了所有产品的创建逻辑,职责过重,一旦不能正常工作,整个系统都要受影响

3.3 简单工厂模式使用场景

  1. 工厂模式是new一个对象替代品,在所有需要生产对象的地方都可以使用
  2. 需要灵活可扩展的框架时,可以考虑采用工厂模式

4 参考资料

秦晓波, 《设计模式之禅》
刘伟,《设计模式的艺术—软件开发人员内功修炼之道》

转载于:https://www.cnblogs.com/pingchangxin2018/p/9913230.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值