来自:http://blog.csdn.net/ericzhong83/article/details/7604728

工厂方法模式(Factory Method Pattern):

定义了一个创建对象的接口,但由子类决定要实例化类的哪一个;即通过子类来创建对象。

原则:

要依赖抽象,不要依赖具体类。

案例:

先解释什么是工厂:
如果你开一家Pizza店(PizzaStore抽象类)卖各种风味的Pizza(Pizza子类),那么你需要根据客户要求准备相应的Pizza(创建Pizza对象),然后烘烤、切片、包装;
最简单的做法就是在PizzaStore中根据客户要求(类型判断)创建相应的Pizza对象,然后调用Pizza自身(由Pizza抽象类实现)的烘烤、切片和包装方法;
但这样的代码缺乏弹性,因为你让一个抽象类去依赖具体的对象;我们可以创建一个工厂来生产Pizza,根据传入的不同类型值返回不同Pizza对象,即从PizzaStore中将创建对象的代码挪到工厂中。但这只是一个编程技巧,并不算模式。

在工厂方法模式中,我们在PizzaStore中定义一个抽象接口(create_pizza)作为抽象的工厂,而order_pizza是它的客户;将Pizza对象的创建放到PizzaStore子类去解决。

现有Cheese和Clam两款Pizza,以及NY和Chicago两家分店,每家店的同款Pizza的口味不同——为迎合当地口味做了改进,主要差别来自不同的原材料,因此我们实现四个Pizza类型(NYStyleCheesePizza、NYStyleClamPizza、 ChicagoStyleCheesePizza和ChicagoStyleClamPizza),每种使用不同的原材料组合,根据客户所在城市和选择款式我们创建不同的对象;根据工厂方法,我们将对象创建的代码放到PizzaStore子类去实现。

代码:

#!/usr/bin/python

class Pizza:
name = ""
dough = ""
sauce = ""
toppings = [] def prepare(self):
print "Preparing %s" % self.name
print " dough: %s" % self.dough
print " sauce: %s" % self.sauce
print " add toppings:"
for n in self.toppings:
print " %s" % n def bake(self):
print "Bake for 25 minutes at 350." def cut(self):
print "Cutting into diagonal slices." def box(self):
print "Put into official box." def get_name(self):
return self.name class PizzaStore:
def order_pizza(self, pizza_type):
self.pizza = self.create_pizza(pizza_type)
self.pizza.prepare()
self.pizza.bake()
self.pizza.cut()
self.pizza.box()
return self.pizza def create_pizza(self, pizza_type):
pass class NYStyleCheesePizza(Pizza):
def __init__(self):
self.name = "NY Style Cheese Pizza"
self.dough = "NY Dough"
self.sauce = "NY Sauce"
self.toppings.append("NY toopping A")
self.toppings.append("NY toopping B") class ChicagoStyleCheesePizza(Pizza):
def __init__(self):
self.name = "Chicago Style Cheese Pizza"
self.dough = "Chicago Dough"
self.sauce = "Chicago Sauce"
sefl.toppings.append("Chicago toopping A") def cut(self):
print "Cutting into square slices." class NYStyleClamPizza(Pizza):
def __init__(self):
self.name = "NY Style Clam Pizza"
self.dough = "NY Dough"
self.sauce = "NY Sauce"
self.toppings.append("NY toopping A")
self.toppings.append("NY toopping B") class ChicagoStyleClamPizza(Pizza):
def __init__(self):
self.name = "Chicago Style Clam Pizza"
self.dough = "Chicago Dough"
self.sauce = "Chicago Sauce"
self.toppings.append("Chicago toopping A") def cut(self):
print "Cutting into square slices." class NYPizzaStore(PizzaStore):
def create_pizza(self, pizza_type):
if pizza_type == "cheese":
return NYStyleCheesePizza()
elif pizza_type == "clam":
return NYStyleClamPizza()
else:
return None class ChicagoPizzaStore(PizzaStore):
def create_pizza(self, pizza_type):
if pizza_type == "cheese":
return ChicagoStyleCheesePizza()
elif pizza_type == "clam":
return ChicagoStyleClamPizza()
else:
return None if __name__ == "__main__":
ny_store = NYPizzaStore()
chicago_store = ChicagoPizzaStore() pizza = ny_store.order_pizza("cheese")
print "Mike ordered a %s." % pizza.get_name()
print pizza = chicago_store.order_pizza("clam")
print "John ordered a %s." % pizza.get_name()
print

输出:

Preparing NY Style Cheese Pizza
dough: NY Dough
sauce: NY Sauce
add toppings:
NY toopping A
NY toopping B
Bake for 25 minutes at 350.
Cutting into diagonal slices.
Put into official box.
Mike ordered a NY Style Cheese Pizza. Preparing Chicago Style Clam Pizza
dough: Chicago Dough
sauce: Chicago Sauce
add toppings:
NY toopping A
NY toopping B
Chicago toopping A
Bake for 25 minutes at 350.
Cutting into square slices.
Put into official box.
John ordered a Chicago Style Clam Pizza.

设计模式:工厂方法模式(Python)的更多相关文章

  1. 4. 星际争霸之php设计模式--工厂方法模式

    题记==============================================================================本php设计模式专辑来源于博客(jymo ...

  2. C++设计模式——工厂方法模式

    本文版权归果冻说所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利.» 本文链接:http://www.jellythink.com/arch ...

  3. Python设计模式——工厂方法模式(FactoryMethod)

    需求:有一个学雷锋活动,有买米和扫地两个内容,参与的人有大学生和社区志愿者,他们各自的方法不一样. 如果用简单工厂模式实现: #encoding=utf-8 __author__ = 'kevinlu ...

  4. JAVA设计模式--工厂方法模式

    工厂方法设计模式 抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关.是具体工厂角色必须实现的接口或者必须继承的父类.在java中它由抽象类或者接口来实现.具体工厂角色:它含有和具体业务逻辑有关 ...

  5. 深入浅出设计模式——工厂方法模式(Factory Method)

    介绍在简单工厂模式中,我们提到,工厂方法模式是简单工厂模式的一个延伸,它属于Gof23中设计模式的创建型设计模式.它解决的仍然是软件设计中与创建对象有关的问题.它可以更好的处理客户的需求变化. 引入我 ...

  6. 设计模式--工厂方法模式(Factory method pattern)及应用

    面向对象的好处: 通过封装,继承,多态把程序的耦合度降低. 用设计模式可以使程序更加灵活,容易修改,且易于复用. 1. 工厂方法模式 Define an interface for creating ...

  7. 我的Java设计模式-工厂方法模式

    女朋友dodo闹脾气,气势汹汹的说"我要吃雪糕".笔者心里啊乐滋滋的,一支雪糕就能哄回来,不亦乐乎?! 但是,雪糕买回来了,她竟然说"不想吃雪糕了,突然想吃披萨" ...

  8. 设计模式 — 工厂方法模式(Factory Method)

    在开发系统中,经常会碰到一个问题.现在需要实现的一些功能,但是这个功能模块以后一定是需要扩展的,那么现在开发中就不仅要实现现在的功能,还要考虑以后的扩展.那么为了系统的健壮,扩展就要遵循开闭原则(简单 ...

  9. C#设计模式--工厂方法模式

    0.C#设计模式-简单工厂模式 设计模式: 工厂方法模式(Factory Method Pattern) 介绍:简单工厂模式是要在工厂类中通过数据来做个决策,在工厂类中的多个类中实例化出来其中一个要用 ...

  10. Java设计模式—工厂方法模式&抽象工厂模式

    工厂方法模式与抽象工厂模式都是设计模式中重要而且常见的模式.       工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类.工厂方法使一个类的实例化延迟到其子类. 通用类图如下: 在 ...

随机推荐

  1. hdu 1227(动态规划)

    Fast Food Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total S ...

  2. 构建maven动态web 工程

    项目构建 总体参考: http://www.java2blog.com/2015/09/how-to-create-dynamic-web-project-using.html https://sta ...

  3. Docker容器进入的4种方式(转)

    这个文章不错,几种方式及使用范围都讲得清楚. 另外,还有一个文章说了为什么docker中并不合适ssh服务安装的情况. 我现在也是用第四种方式, docker exec -it [docker容器ID ...

  4. svn泄漏敏感信息利用方式

    之前仅知道svn权限配置不当,会导致敏感信息泄漏,但是一直不知道具体利用方式. 今天测试svn dig时抓包分析才知道: http://www.xxx.com/路径/.svn/text-base/文件 ...

  5. Python练习——同时安装python2 与 python 3如何选择不同解释器运行脚本

    如果同时安装了python 2 和python 3 那么我们需要在运行时指定解释器 如下: 其中py -2 ex1.py指定了解释器的版本,以及打开的文件 如果使用 py-3 ex1.py则使用了py ...

  6. Python与数据结构[4] -> 散列表[1] -> 分离链接法的 Python 实现

    分离链接法 / Separate Chain Hashing 前面完成了一个基本散列表的实现,但是还存在一个问题,当散列表插入元素冲突时,散列表将返回异常,这一问题的解决方式之一为使用链表进行元素的存 ...

  7. openssl生成证书链多级证书

    操作系统CentOS6.6 注:windows版本的Openssl无法做这个实验,由于所有编译的window版本openssl没有对openssl目录重新定向,导致在windows下找不到pki目录 ...

  8. Django项目静态文件加载失败问题

    在我们平时的开发过程中,为了方便调试程序,我们都是打开开发者模式,即Debug=True,当我们正式上线的时候肯定就需要把开发者模式关掉,用uwsgi部署上去以后,突然发现我们平时辛苦做的项目的静态文 ...

  9. Tarjan求LCA总结

    Tarjan算法向上标记法:从x向上走到根节点,并标记所有经过的点从y向上走到根节点,当第一次遇到已标记的节点时,就找到了LCA(x, y)对于每个询问,向上标记法的时间复杂度最坏为O(n) 在深度遍 ...

  10. 【枚举约数】HackerRank - Week of Code 26 - Satisfactory Pairs

    题意:给你一个正整数n,问你存在多少个正整数对a,b(a<b),满足条件:存在正整数x,y,使得ax+by=n. 就预处理出n以内所有数的约数,然后暴力枚举a,暴力枚举x,然后枚举n-ax的所有 ...