设计模式—工厂模式

  今天难道有比较充裕的时间,忙里偷闲梳理一下工厂模式。

  说起工厂模式,这可是一个很经典的模式。也是发展种类比较多的一种设计模式。单单在课上我们老师就给我们讲了三种不同的演化。而且这种设计模式的实用性非常好,也算简单易懂,可以说是程序猿入门必备的一种设计模式。

 

  首先先说一个生活中的案例,也是工厂模式的一个经典的例子。

 

  相比我们大多数的人都吃过西式的快餐,例如,KFC,麦当劳,汉堡王,赛百味之类的。这些快餐有一些类似的特点,就是它给提供单人套餐,双人套餐,家庭套餐之类的。比如leo在下和同学们中午玩累了,随便去一个KFC点一个全家桶,对于我们这种选择困难户来说显得既方便又简单。

 

  然而给我们上课的老师喜欢云游四方,经常去外国去开会。在他眼中,外国快餐店给用户的选择性就非常的大。他给我们讲外国的赛百味,里面放多少奶油,放什么蔬菜,放什么肉,甚至烤成什么样子都是可以让顾客去选择的。

 

  那么问题浮出水面,在程序设计中。我们做的最多的就是实例对象。试想一下,在一个快餐店里,如果来一个客人我们就new一个对象,那么客人一多我们岂不是要创建很多很多的对象。而且正如例子中的快餐店,如果都像外国Subway一样,什么东西都可以上客人去选择,那么情况肯定会变得更加的复杂。所以这个时候工厂模式就能解决这一个问题。

 

  首先,工厂模式有三种版本的演化,分别是简单工厂,工厂模式,工厂方法。这里给出三种版本的简单解释:

 1 简单工厂:对创建对象的代码进行简单的封装。

 2 工厂方法:定义一个创建对象的接口,但是子类决定实例化哪一个,工厂方法让实例化推迟到子类去实现。

 3 抽象工厂: 提供一个接口用于创建或依赖对象的家族而不需要明确指出具体类。

  Then,我们怎么去一步一步的实现它呢?

   首先我们先看简单工厂,这个方法和策略模式很像。精髓是:对创建对象的代码进行简单的封装。怎么做呢? 就是在程序中,我们要设计一个pizza的类,然后各式各样的具体的pizza去继承pizza。还要设计一个pizza的工厂,这个工厂可以实现order pizza的功能。然后呢在orderpizza中设定不同的场景,比如客人喜欢cheesepizza,你就给他new一个cheesepizza,客人喜欢clampizza,你就给他做一个clampizza就好了。

  这种简单模式的类图和代码如下:

<span style="font-size:12px;">class pizza:

    def prepare(self):
        print 'prepare pizza'

    def bake(self):
        print'bake pizza'

    def box(self):
        print 'box pizza'

class cheesepizza(pizza):

    def __init__(self):
        self.name='cheesepizza'

    def prepare(self):
        print 'prepare '+ str(self.name)

    def bake(self):
        print'bake '+ str(self.name)

    def box(self):
        print 'box '+str(self.name)

class veggiepizza(pizza):

    def __init__(self):
        self.name='veggiepizza'

    def prepare(self):
        print 'prepare '+ str(self.name)

    def bake(self):
        print'bake '+ str(self.name)

    def box(self):
        print 'box '+str(self.name)


class clampizza(pizza):

    def __init__(self):
        self.name='clampizza'

    def prepare(self):
        print 'prepare '+ str(self.name)

    def bake(self):
        print'bake '+ str(self.name)

    def box(self):
        print 'box '+str(self.name)

class pepperoinpizza(pizza):

    def __init__(self):
        self.name='pepperoinpizza'

    def prepare(self):
        print 'prepare '+ str(self.name)

    def bake(self):
        print'bake '+ str(self.name)

    def box(self):
        print 'box '+str(self.name)


class pizzafactory:

    def orderpizza(self,pizzaname):
        
        if pizzaname=='cheesepizza':
            
            pizza=cheesepizza()
            pizza.prepare()
            pizza.bake()
            pizza.box()

        elif pizzaname=='veggiepizza':

            pizza=veggiepizza()
            pizza.prepare()
            pizza.bake()
            pizza.box()

        elif pizzaname=='clampizza':

            pizza=clampizza()
            pizza.prepare()
            pizza.bake()
            pizza.box()

        elif pizzaname=='pepperoinpizza':

            pizza=pepperoinpizza()
            pizza.prepare()
            pizza.bake()
            pizza.box()

        else:
            print 'please order again'

if __name__=='__main__':

    factory=pizzafactory()

    factory.orderpizza('pepperoinpizza')
    factory.orderpizza('clampizza')
    factory.orderpizza('cheesepizza')
    factory.orderpizza('veggiepizza')
    </span>
    


*******************************************************************************************************************************

  好了,这么一来有了一个最基本的版本了。那么看它是如何演进的。于是乎,我再抛出一个问题。像KFC呀,麦当劳呀,他们不可能只有一家对不对,像济南这种城市就有N家这种西式快餐店,那么说来,不同的门店,虽然标准相同,但是总会有一些例如味道不同。显然,一家简单工厂已经不能解决这些问题了。既然如此我们需要从工厂模式找寻这个问题的解决之道。

  定义一个创建对象的接口,但是子类决定实例化哪一个,工厂方法让实例化推迟到子类去实现。这一段话怎么去理解,其实也是很简单的,就是工厂我也一开始不将它定义的这么死板,像pizza一样,我编一个pizzafactory的父类,然后呢,让真正的不同的pizzafactory去继承pizzafactory比如济南的KFC or 广东的KFC。这样,北方人口味比较重,当地会做一些偏咸的口味。南方人口味比较清淡,这样他们会做一些比较淡一点的口味。这样问题再一次得到了解决。

  具体的类图和代码如下:

 

<span style="font-size:12px;">class pizza:

    def prepare(self):
        print 'prepare pizza'

    def bake(self):
        print'bake pizza'

    def box(self):
        print 'box pizza'

class beijingcheesepizza(pizza):

    def __init__(self):
        self.name='beijing cheesepizza'

    def prepare(self):
        print 'prepare '+ str(self.name)

    def bake(self):
        print'bake '+ str(self.name)

    def box(self):
        print 'box '+str(self.name)

class beijingveggiepizza(pizza):

    def __init__(self):
        self.name='beijing veggiepizza'

    def prepare(self):
        print 'prepare '+ str(self.name)

    def bake(self):
        print'bake '+ str(self.name)

    def box(self):
        print 'box '+str(self.name)


class beijingclampizza(pizza):

    def __init__(self):
        self.name='beijing clampizza'

    def prepare(self):
        print 'prepare '+ str(self.name)

    def bake(self):
        print'bake '+ str(self.name)

    def box(self):
        print 'box '+str(self.name)

class beijingpepperoinpizza(pizza):

    def __init__(self):
        self.name='beijing pepperoinpizza'

    def prepare(self):
        print 'prepare '+ str(self.name)

    def bake(self):
        print'bake '+ str(self.name)

    def box(self):
        print 'box '+str(self.name)

class jinancheesepizza(pizza):

    def __init__(self):
        self.name='jinan cheesepizza'

    def prepare(self):
        print 'prepare '+ str(self.name)

    def bake(self):
        print'bake '+ str(self.name)

    def box(self):
        print 'box '+str(self.name)

class jinanveggiepizza(pizza):

    def __init__(self):
        self.name='jinan veggiepizza'

    def prepare(self):
        print 'prepare '+ str(self.name)

    def bake(self):
        print'bake '+ str(self.name)

    def box(self):
        print 'box '+str(self.name)

class jinanclampizza(pizza):

    def __init__(self):
        self.name='jinan clampizza'

    def prepare(self):
        print 'prepare '+ str(self.name)

    def bake(self):
        print'bake '+ str(self.name)

    def box(self):
        print 'box '+str(self.name)

class jinanpepperoinpizza(pizza):

    def __init__(self):
        self.name='jinan pepperoinpizza'

    def prepare(self):
        print 'prepare '+ str(self.name)

    def bake(self):
        print'bake '+ str(self.name)

    def box(self):
        print 'box '+str(self.name)

class pizzafactory:

    def  orderpizza(self,pizzaname):
        pass


class jinanpizzafactory(pizzafactory):

    def orderpizza(self,pizzaname):
        
        if pizzaname=='cheesepizza':
            
            pizza=jinancheesepizza()
            pizza.prepare()
            pizza.bake()
            pizza.box()

        elif pizzaname=='veggiepizza':

            pizza=jinanveggiepizza()
            pizza.prepare()
            pizza.bake()
            pizza.box()

        elif pizzaname=='clampizza':

            pizza=jinanclampizza()
            pizza.prepare()
            pizza.bake()
            pizza.box()

        elif pizzaname=='pepperoinpizza':

            pizza=jinanpepperoinpizza()
            pizza.prepare()
            pizza.bake()
            pizza.box()

        else:
            print 'please order again'

class beijingpizzafactory(pizzafactory):

    def orderpizza(self,pizzaname):
        
        if pizzaname=='cheesepizza':
            
            pizza=beijingcheesepizza()
            pizza.prepare()
            pizza.bake()
            pizza.box()

        elif pizzaname=='veggiepizza':

            pizza=beijingveggiepizza()
            pizza.prepare()
            pizza.bake()
            pizza.box()

        elif pizzaname=='clampizza':

            pizza=beijingclampizza()
            pizza.prepare()
            pizza.bake()
            pizza.box()

        elif pizzaname=='pepperoinpizza':

            pizza=beijingpepperoinpizza()
            pizza.prepare()
            pizza.bake()
            pizza.box()

        else:   
            print 'please order again'

if __name__=='__main__':

    factory=jinanpizzafactory()

    factory.orderpizza('pepperoinpizza')
    factory.orderpizza('clampizza')
    factory.orderpizza('cheesepizza')
    factory.orderpizza('veggiepizza')

    factory=beijingpizzafactory()

    factory.orderpizza('pepperoinpizza')
    factory.orderpizza('clampizza')
    factory.orderpizza('cheesepizza')
    factory.orderpizza('veggiepizza')</span>
    


*******************************************************************************************************************************

  根据上面的做法,我们已经能够成功创造出来各个地方的不同口味的pizza了。是不是有一点小小的激动。不过这还不是最终极的解决方案。Leo平时呢喜欢看武侠小说,最近小笼包版的神雕侠侣也是让Leo羞耻地吐了一阵老血。感叹的同时我想起来金庸老先生的原著,故事剧情到了是杨过在山洞中发现了独孤求败前辈的藏剑。一开始是一把锋利的好剑,之后呢是一把“宝剑不锋,大巧不工”的玄铁剑,最后居然是一把木剑。意思大体是,如果修炼到上乘,招式已在心中。花草树木皆可为剑,已经不因为外部的变化而改变战场的形式。

  多么高深的境界~这和工厂模式的抽象工厂简直是异曲同工。那么我们根据金庸老先生的指点领会一下“提供一个接口用于创建或依赖对象的家族而不需要明确指出具体类”这一句话吧,23333!

  感觉扯远了,咱们接上pizza的例子。虽然能这么设计,但是还是不自由。正如Leo的老师所见,外国的快餐店可以决定自己的汉堡里放几片肉,放几片菜。那么说来,所有的口味我们都可以让客户自己去点单。他们完全决定他们要吃什么东西。这也就是工厂模式的究极形式。

  在这一个套路中,我们连原料都给大家暴露出来,客户在这里想放什么就给你放什么,想放多少我们就给你放多少,没有特定的口味,一切用户定义。这样实现完全自由选择的方式,实现对不同口味的客户进行最贴心的服务,而我们只给你们做好每一个地区不同风味的原料。这就是传说中的产品族,这里引用Leo老师上课说的一个很有意思的话,“如果你去找KFC的总店,你会很有意思的发现KFC总店并不是负责炸鸡的,也不是研究原料的,它真正做的事情就是做了一个肯德基的牌子,并且制定了一些看似非常非常简单的标准。但是当回过头来想肯德基怎么盈利的时候,又一个惊喜的发现是,钱就这么被他们赚过去了~”

  最终的套路的类图和实现的代码如下:

 

<span style="font-size:12px;">class pizza:
    
    def __init__(self,ingredientFactory):
        self.ingredientFactory=ingredientFactory

    def prepare(self):
        pass

    def bake(self):
        print'bake pizza'

    def box(self):
        print 'box pizza'

class mypizza(pizza):
    
    def __init__(self,ingredientFactory):
        self.ingredientFactory=myingredientFactory()  

    def prepare(self):
        self.ingredientFactory.createcheese(mycheese())
        self.ingredientFactory.createclam(myclam())
        self.ingredientFactory.createveggie(myveggie())
        self.ingredientFactory.createpepperoin(mypepperoin())
        

class ingredientFactory:

    def createcheese(self,cheese):
        pass
    def createclam(self,clam):
        pass
    def createveggie(self,veggie):
        pass
    def createpepperoin(self,pepperoin):
        pass

class myingredientFactory(ingredientFactory):

    def createcheese(self,cheese):
        pass
    
    def createclam(self,clam):
        pass
    
    def createveggie(self,veggie):
        pass
    
    def createpepperoin(self,pepperoin):
        pass

class cheese:

    def __init__(self):
        pass

class mycheese(cheese):

    def __init__(self):
        self.name='leo\'s cheese'
        print 'leo\'s cheese'

class clam:

    def __init__(self):
        pass
    
class myclam(clam):

    def __init__(self):
        self.name='leo\'s clam'
        print 'leo\'s clam'
        
class veggie:

    def __init__(self):
        pass

class myveggie(veggie):

    def __init__(self):
        self.name='leo\'s veggie'
        print 'leo\'s veggie'
        
class pepperoin:

    def __init__(self):
        pass
    
class mypepperoin(pepperoin):

    def __init__(self):
        self.name='leo\'s pepperoin'
        print 'leo\'s pepperoin'

if __name__=='__main__':

    pizza=mypizza(myingredientFactory())
    pizza.prepare()
    pizza.bake()
    pizza.box()</span>
    

诶诶~写了好多呀~那么大家慢慢看吧~

*******************************************************************************************************************************

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值