python 设计模式之工厂模式 Factory Pattern (简单工厂模式,工厂方法模式,抽象工厂模式)
十一回了趟老家,十一前工作一大堆忙成了狗,十一回来后又积累了一大堆又 忙成了狗,今天刚好抽了一点空开始写工厂方法模式
我看了《Head First 设计模式》P109--P133 这25页,讲述了我们为什么要用工厂模式,里面用做pizza的例子讲的特别细腻。看完了就能很清楚的知道为什么要用工厂模式。
年龄越大越不喜欢一知半解,深刻的了解某些未知的事或物以后,它再出现就不怕了
#'New'有什么不对劲?
在技术上,new没有错,这是语言的基础部分。真正的犯人是我们的老朋友 ‘改变’, 以及它是如何影响new使用的。
如果代码是通过接口而写,通过多态,可以与任何新类实现该接口。
但是当代码使用大量的具体类时,那就麻烦了,因为一旦加入新的具体类,就必须改变代码。意思是代码没 " 对修改关闭"。想用新的具体类来扩展代码,必须重新打开它。
这可咋办? 只能改代码

很明显,如果实例化某些具体类,将使orderPizza()出问题,没办法让orderPizza()对修改关闭,
但是咱们还是能很明显的看出哪些会变,哪些不会变,这个时候就可以考虑封装了,

上面这些引出了下面的简单工厂模式
#简单工厂模式
1)算是定义吧
简单工厂模式其实并不是一个模设计模式,反而比较像一种编程习惯,还请不要把这个习惯认为是“工厂模式”。
不要因为简单工厂不是一个真正的模式,就忽略它的用法。
2)类图

3)举个例子(java)
public class PizzaStore {
SimplePizzaFactory factory;
public PizzaStore(SimplePizzaFactory factory){
this.factory=factory;
}
public Pizza orderPizza(String type){
Pizza pizza;
pizza=factory.createPizza(type);
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
}
############################
public class SimplePizzaFactory {
public Pizza createPizza(String type){
Pizza pizza=null;
if(type.equals("cheese")){
pizza=new CheesePizza();
}else if (type.equals("greek")){
pizza=new GreekPizza();
}else if(type.equals("pepperoni")){
pizza=new PepperoniPizza();
}else if (type.equals("clam")){
pizza=new ClamPizza();
}else if (type.equals("veggie")){
pizza=new VeggiePizza();
}
return pizza;
}
}
########################################################
public abstract class Pizza {
String name;
String dough;
String sauce;
void prepare(){
System.out.print("Preparing");
};
void bake(){
System.out.print("Baking");
};
void cut(){
System.out.print("cut");
};
void box(){
System.out.print("box");
};
}
public class VeggiePizza extends Pizza{
}
public class ClamPizza extends Pizza {
}
public class PepperoniPizza extends Pizza {
}
public class PepperoniPizza extends Pizza {
}
#################################
public static void main(String[] args) {
PizzaStore store=new PizzaStore();
Pizza pizza=store.orderPizza("cheese");
System.out.println("eat Pizza");
}
4)举个例子(python)
#工厂方法模式
#引入
#匹萨生意火爆,现在有很多人要开加盟店,不同地区的加盟店口味有差异。PizzaStore有个不错的订单系统,希望所有加盟店对订单的处理一致。
各区域匹萨店之间的差异在于他们制作匹萨的风味(比如 NYStyle 饼薄, ChicagoStyle 饼厚等),我们现在让createPizza()来应对这些变化负责创建正确种类的匹萨。
做法是让PizzaStore的各个子类负责定义自己的createPizza()方法。所以我们会得到PizzaStore的具体类。
#定义
定义了一个创建对象的接口,但有子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。
所有工厂模式都是用来封装对象的创建。工厂方法模式(Factory Method Pattern) 通过让子类决定该创建的对象是什么,来达到对象创建的过程封装的目的。
原本是由一个对象负责所有具体的实例化,现在变成一群子类负责实例化

#类图

#举个例子(java)
public abstract class PizzaStore {
public Pizza orderPizza(String type){
Pizza pizza;
pizza=createPizza(type);
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
abstract Pizza createPizza(String type);
}
###########################################################
public class NYPizzaStore extends PizzaStore{
Pizza createPizza(String item){
if(item.equals("cheese")){
return new NYStyleCheesePizza();
}else if (item.equals("greek")){
return new NYStyleGreekPizza();
}else if(item.equals("pepperoni")){
return new NYStylePepperoniPizza();
}else if (item.equals("clam")){
return new NYStyleClamPizza();
}else if (item.equals("veggie")){
return new NYStyleVeggiePizza();
}else return null
}
########
public class ChicagoPizzaStore extends PizzaStore {
Pizza createPizza(String item){
if(item.equals("cheese")){
return new ChicagoStyleCheesePizza();
}else if (item.equals("greek")){
return new ChicagoStyleGreekPizza();
}else if(item.equals("pepperoni")){
return new ChicagoStylePepperoniPizza();
}else if (item.equals("clam")){
return new ChicagoStyleClamPizza();
}else if (item.equals("veggie")){
return new ChicagoStyleVeggiePizza();
}else return null;
}
}
##########################################################
public abstract class Pizza {
String name;
String dough;
String sauce;
void prepare(){
}
void bake(){
}
void cut(){
}
void box(){
}
}
##############
public class NYStyleCheesePizza extends Pizza {
public NYStyleCheesePizza(){
name="NY Style Sauce and Cheese Pizza";
dough="Thin Crust Dough";
sauce="Marinara Sauce";
}
}
########
public class NYStyleClamPizza extends Pizza {
}
######
public class NYStyleGreekPizza extends Pizza{
}
####
public class NYStylePepperoniPizza extends Pizza {
}
#######
public class NYStyleVeggiePizza extends Pizza {
}
#########
public class ChicagoStyleCheesePizza extends Pizza {
public ChicagoStyleCheesePizza(){
name="Chicago Style Sauce and Cheese Pizza";
dough="Thick Crust Dough";
sauce="Plum Tomato Sauce";
}
}
#########
public class ChicagoStyleGreekPizza extends Pizza{
}
########
public class ChicagoStylePepperoniPizza extends Pizza {
}
#######
public class ChicagoStyleClamPizza extends Pizza{
}
######
public class ChicagoStyleVeggiePizza extends Pizza {
}
#####################################################################
public class javatest1 {
public static void main(String[] args) throws IOException,ClassNotFoundException{
PizzaStore nyStore=new NYPizzaStore();
PizzaStore chicagoStore=new ChicagoPizzaStore();
Pizza pizza=nyStore.orderPizza("cheese");
System.out.println("eat NYStylePizza");
pizza = chicagoStore.orderPizza("cheese");
System.out.println("eat ChicagoStylePizza");
}
}
#举个例子(python)
class Person(object):
def __init__(self,name):
self.name = name def work(self):
print(self.name+"工作开始了") axe = Stone_Factory().create_axe() axe.cut_tree() class Axe(object):
def __init__(self,name):
self.name = name def cut_tree(self):
print("使用%s斧头砍树"%self.name) class StoneAxe(Axe): def cut_tree(self):
print("使用石斧头砍树") class SteelAxe(Axe): def cut_tree(self):
print("使用铁斧头砍树") class Tree(object):
pass #工厂类
'''
class Factory(object):
@staticmethod
def create_axe(type):
if type == "stone":
return StoneAxe("花岗岩斧头")
if type == "steel":
return SteelAxe("铁斧头")
'''
class Factory(object): def create_axe(self):
pass class Stone_Factory(Factory):
def create_axe(self):
return StoneAxe("花岗岩斧头") class Steel_Factory(Factory):
def create_axe(self):
return SteelAxe("铁斧头")
code来自https://blog.csdn.net/Mr_Quiet/article/details/80998337
#抽象工厂模式
#引入
纽约匹萨店生意火爆,越来越好,需要开好多家纽约披萨店,芝加哥也是面临同样的情况。为了保证质量,就得控制原料。所以我们得建造原料工厂,来生产不同区域的原料。
#定义
抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。
允许客户用抽象的借口创建一组产品,不需要知道实际产出的具体产品是什么,这样客户就从具体的产品解耦了。
#结构图

#使用场景
)客户端不依赖于产品类实例如何被创建、实现等细节
)强调一系列相关的产品对象(属于统一产品族)一起使用创建对象需要大量重复的代码
)提供一个产品类的库,所以的产品以同样或者大部分相同的接口出现,从而使客户端不依赖具体实现
#优点
实现解耦
#缺点
)规定了所有可能被创建的产品集合,产品族扩展新的产品困难,需要修改抽象工厂的接口
)增加了系统的抽象性和理解难度
#举个例子(java)
public interface Cheese {
}
#############
public interface Pepperoni {
}
##########
public interface Sauce {
}
##################
public interface Clams {
}
public class BlackOlives implements Veggies {
}
#########
public interface Dough {
}
##########
public interface Veggies {
}
######################################################################
public class MozzarellaCheese implements Cheese{
}
########
public class ReggianoCheese implements Cheese {
}
#####
public class Eggplant implements Veggies {
}
#####
public class Garlic implements Veggies{
}
#######
public class Mushroom implements Veggies {
}
###########
public class RedPepper implements Veggies{
}
########
public class Spinach implements Veggies{
}
#####
public class FreshClams implements Clams{
}
######
public class FrozenClams implements Clams{
}
#######
public class MarinaraSauce implements Sauce {
}
#########
public class PlumTomatoSauce implements Sauce {
}
########
public class SlicedPepperoni implements Pepperoni{
}
#########
public class SlicePepperoni implements Pepperoni{
}
########
public class ThinCrustDough implements Dough {
}
########
public class ThickCrustDough implements Dough {
}
########################################################
public interface PizzaIngredientFactory {
public Sauce createSauce();
public Cheese createCheese();
public Veggies[] createVeggies();
public Pepperoni createPepperoni();
public Clams createClam();
public Dough createDough();
}
###################
public class NYPizzaIngredientFactory implements PizzaIngredientFactory {
public Dough createDough(){
return new ThinCrustDough();
}
public Sauce createSauce(){
return new MarinaraSauce();
}
public Cheese createCheese(){
return new ReggianoCheese();
}
public Veggies[] createVeggies(){
Veggies veggies[]={new Garlic(),new Mushroom(),new RedPepper()};
return veggies;
}
public Pepperoni createPepperoni(){
return new SlicePepperoni();
}
public Clams createClam(){
return new FreshClams();
}
}
#########
public class ChicagoPizzaIngredientFactory implements PizzaIngredientFactory {
public Dough createDough(){
return new ThickCrustDough();
}
public Sauce createSauce(){
return new PlumTomatoSauce();
}
public Cheese createCheese(){
return new MozzarellaCheese();
}
public Veggies[] createVeggies(){
Veggies veggies[]={new BlackOlives(),new Spinach(),new Eggplant()};
return veggies;
}
public Pepperoni createPepperoni(){
return new SlicedPepperoni();
}
public Clams createClam(){
return new FrozenClams();
}
}
#######
###############################################
public abstract class Pizza {
String name;
Dough dough;
Sauce sauce;
Veggies veggies[];
Cheese cheese;
Pepperoni pepperoni;
Clams clam;
abstract void prepare();
void bake(){
System.out.print("Baking");
};
void cut(){
System.out.print("cut");
};
void box(){
System.out.print("box");
};
void setName(String name){
this.name=name;
}
String getName(){
return name;
}
public String toString(){
return name;
}
}
###############
public class CheesePizza extends Pizza{
PizzaIngredientFactory ingreditentFactory;
public CheesePizza(PizzaIngredientFactory ingredientFactory){
this.ingreditentFactory=ingredientFactory;
}
void prepare(){
System.out.print("Preparing"+name);
dough=ingreditentFactory.createDough();
sauce=ingreditentFactory.createSauce();
cheese=ingreditentFactory.createCheese();
}
}
#############
public class ClamPizza extends Pizza {
PizzaIngredientFactory ingredientFactory;
public ClamPizza(PizzaIngredientFactory ingredientFactory){
this.ingredientFactory=ingredientFactory;
}
void prepare(){
System.out.print("Preparing"+name);
dough=ingredientFactory.createDough();
sauce=ingredientFactory.createSauce();
clam=ingredientFactory.createClam();
}
}
######################
public class PepperoniPizza extends Pizza {
PizzaIngredientFactory ingreditentFactory;
public PepperoniPizza(PizzaIngredientFactory ingredientFactory){
this.ingreditentFactory=ingredientFactory;
}
void prepare(){
System.out.print("Preparing"+name);
dough=ingreditentFactory.createDough();
sauce=ingreditentFactory.createSauce();
cheese=ingreditentFactory.createCheese();
}
}
################
public class VeggiePizza extends Pizza {
PizzaIngredientFactory ingreditentFactory;
public VeggiePizza(PizzaIngredientFactory ingredientFactory){
this.ingreditentFactory=ingredientFactory;
}
void prepare(){
System.out.print("Preparing"+name);
dough=ingreditentFactory.createDough();
sauce=ingreditentFactory.createSauce();
cheese=ingreditentFactory.createCheese();
}
}
###############################################################################################
public abstract class PizzaStore {
public Pizza orderPizza(String type){
Pizza pizza;
pizza=createPizza(type);
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
abstract Pizza createPizza(String type);
}
############################
public class NYPizzaStore extends PizzaStore{
protected Pizza createPizza(String item){
Pizza pizza=null;
PizzaIngredientFactory nyIngredientFactory=new NYPizzaIngredientFactory();
if(item.equals("cheese")){
pizza=new CheesePizza(nyIngredientFactory);
pizza.setName("New York Style Cheese Pizza");
}else if(item.equals("veggie")){
pizza=new VeggiePizza(nyIngredientFactory);
pizza.setName("New York Style Veggie Pizza");
}else if(item.equals("clam")){
pizza=new ClamPizza(nyIngredientFactory);
pizza.setName("New York Style Clam Pizza");
}else if(item.equals("pepperoni")){
pizza=new PepperoniPizza(nyIngredientFactory);
pizza.setName("New York Style Pepperoni Pizza");
}
return pizza;
}
}
###################
public class ChicagoPizzaStore extends PizzaStore{
protected Pizza createPizza(String item){
Pizza pizza=null;
PizzaIngredientFactory nyIngredientFactory=new ChicagoPizzaIngredientFactory();
if(item.equals("cheese")){
pizza=new CheesePizza(nyIngredientFactory);
pizza.setName("New York Style Cheese Pizza");
}else if(item.equals("veggie")){
pizza=new VeggiePizza(nyIngredientFactory);
pizza.setName("New York Style Veggie Pizza");
}else if(item.equals("clam")){
pizza=new ClamPizza(nyIngredientFactory);
pizza.setName("New York Style Clam Pizza");
}else if(item.equals("pepperoni")){
pizza=new PepperoniPizza(nyIngredientFactory);
pizza.setName("New York Style Pepperoni Pizza");
}
return pizza;
}
}
###########################################################################
public class javatest1 {
public static void main(String[] args) throws IOException,ClassNotFoundException{
PizzaStore nyPizzaStore=new NYPizzaStore();
nyPizzaStore.orderPizza("cheese");
System.out.print("\n");
PizzaStore chicagoPizzaStore=new ChicagoPizzaStore();
chicagoPizzaStore.orderPizza("clam");
}
}
#举个例子(python)
#!/usr/bin/env python
# -*- coding:utf-8 -*- __author__ = 'Andy'
"""
大话设计模式
设计模式——抽象工厂模式
抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们的类
"""
import sys #抽象用户表类
class User(object): def get_user(self):
pass def insert_user(self):
pass #抽象部门表类
class Department(object): def get_department(self):
pass def insert_department(self):
pass #操作具体User数据库类-Mysql
class MysqlUser(User): def get_user(self):
print 'MysqlUser get User' def insert_user(self):
print 'MysqlUser insert User' #操作具体Department数据库类-Mysql
class MysqlDepartment(Department): def get_department(self):
print 'MysqlDepartment get department' def insert_department(self):
print 'MysqlDepartment insert department' #操作具体User数据库-Orcal
class OrcaleUser(User): def get_user(self):
print 'OrcalUser get User' def insert_user(self):
print 'OrcalUser insert User' #操作具体Department数据库类-Orcal
class OrcaleDepartment(Department): def get_department(self):
print 'OrcalDepartment get department' def insert_department(self):
print 'OrcalDepartment insert department' #抽象工厂类
class AbstractFactory(object): def create_user(self):
pass def create_department(self):
pass class MysqlFactory(AbstractFactory): def create_user(self):
return MysqlUser() def create_department(self):
return MysqlDepartment() class OrcaleFactory(AbstractFactory): def create_user(self):
return OrcalUser() def create_department(self):
return OrcalDepartment() if __name__ == "__main__": db = sys.argv[1]
myfactory = ''
if db == 'Mysql':
myfactory = MysqlFactory()
elif db == 'Orcal':
myfactory = OrcaleFactory()
else:
print "不支持的数据库类型"
exit(0)
user = myfactory.create_user()
department = myfactory.create_department()
user.insert_user()
user.get_user()
department.insert_department()
department.get_department()
代码来自https://www.cnblogs.com/onepiece-andy/p/python-abstract-factory-pattern.html
#工厂方法模式与抽象工厂模式对比
)都是负责创建对象,工厂方法模式 用的方法是通过继承,抽象工厂模式 用的方法是对象的组合
)工厂方法模式 通过子类来创建对象,客户只需要知道所使用的抽象类型,右子类来负责决定具体类型。换句话说 工厂方法模式只负责将客户从具体类型中解耦。
)抽象工厂模式 用来创建一个产品家族的抽象类型,也可以把客户从所使用的具体产品中解耦。可以把一组相关的产品集合起来。
如果需要扩展这组相关产品,就必须改变接口,这是抽象工厂的缺点。工厂方法模式只涉及一个产品。
)抽象工厂模式经常使用工厂方法模式来实现它(抽象工厂模式)的具体工厂,纯粹是用来创建产品。
参考
《Head First设计模式》
https://blog.csdn.net/qq_28859325/article/details/60580578
https://www.jianshu.com/p/610a26d9d958
python 设计模式之工厂模式 Factory Pattern (简单工厂模式,工厂方法模式,抽象工厂模式)的更多相关文章
- 设计模式3---工厂模式(Factory Pattern简单工厂、工厂方法、抽象工厂)
工厂模式:主要用来实例化有共同接口的类,工厂模式可以动态决定应该实例化那一个类.工厂模式的形态工厂模式主要用一下几种形态:1:简单工厂(Simple Factory).2:工厂方法(Factory M ...
- 设计模式(Python)-简单工厂,工厂方法和抽象工厂模式
本系列文章是希望将软件项目中最常见的设计模式用通俗易懂的语言来讲解清楚,并通过Python来实现,每个设计模式都是围绕如下三个问题: 为什么?即为什么要使用这个设计模式,在使用这个模式之前存在什么样的 ...
- 设计模式 - 工厂模式(factory pattern) 具体解释
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/u012515223/article/details/27081511 工厂模式(factory pa ...
- Java设计模式---工厂模式(简单工厂、工厂方法、抽象工厂)
工厂模式:主要用来实例化有共同接口的类,工厂模式可以动态决定应该实例化那一个类.工厂模式的形态工厂模式主要用一下几种形态:1:简单工厂(Simple Factory).2:工厂方法(Factory M ...
- 设计模式 - 出厂模式(factory pattern) 详细说明
出厂模式(factory pattern) 详细说明 本文地址: http://blog.csdn.net/caroline_wendy/article/details/27081511 工厂方法模式 ...
- 工厂模式(factory pattern) ------创造型模式
创建型模式 简单工厂模式的缺点是: 当我们引入新产品时,由于静态工厂方法通过所传入参数的不同来创建不同的产品,需要修改工厂类的方法,违反了“开闭原则”. 工厂模式提供了一个抽象工厂接口来声明抽象工厂方 ...
- 工厂模式(factory pattern)
工厂模式主要用来封装对象的创建,有3种分类:简单工厂(simple factory).工厂方法(factory method).抽象工厂(abstract factory). 简单工厂包括3种组成元素 ...
- Java设计模式之简单工厂、工厂方法和抽象工厂
在前面的学习中(参见前面的博客),我们学到了很多OO原则: 封装变化 多用组合,少用继承 针对接口/超类编程,不针对实现编程 松耦合 开闭原则 让我们从一个简单的类开始,看看如何将之改造成符合OO原则 ...
- c# 设计模式 之:简单工厂、工厂方法、抽象工厂之小结、区别
很多时候,我发现这三种设计模式难以区分,常常会张冠李戴闹了笑话.很有必要深入总结一下三种设计模式的特点.相同之处和不同之处. 1 本质 三个设计模式名字中都含有“工厂”二字,其含义是使用工厂(一个或一 ...
随机推荐
- APC (Asynchronous Procedure Call)
系统创建新线程时,会同时创建与这个线程相关联的队列,即异步过程调用(APC)的队列. 一些异步操作可以通过加入APC来实现,比如我现在学习的IO请求/完成. BOOL ReadFileEx( HAND ...
- 使用Cloudera Manager搭建MapReduce集群及MapReduce HA
使用Cloudera Manager搭建MapReduce集群及MapReduce HA 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.通过CM部署MapReduce On ...
- 在DEV c++ 中如何设置默认的代码模板
/*菜单,工具=>编辑器选项(弹出对话框)=>代码(属性页)=>缺省源(属性页),写入一些代码确定即可(勾选“向项目初始源文件插入代码”).版本是5.11,中文版 */ #inclu ...
- P2149 [SDOI2009]Elaxia的路线[最长公共路径]
题目描述 最近,Elaxia和w**的关系特别好,他们很想整天在一起,但是大学的学习太紧张了,他们 必须合理地安排两个人在一起的时间. Elaxia和w**每天都要奔波于宿舍和实验室之间,他们 希望在 ...
- 深度学习算法 之DCGAN(写得不系统,后期再总结,大家可简单阅览一下)
目录 1.基本介绍 2.模型 3.优缺点/其他 参考 1.基本介绍 DCGAN是生成对抗网络GAN中一种常见的模型结构.其中的生成器和判别器都是神经网络模型. GAN是一种生成式对抗网络,即通过对抗的 ...
- 04 c++中的友元
c++中的类具有封装性,类中的私有数据只有该类的成员函数可以访问,程序中访问类中的私有成员,必须通过对象来调用成员函数,但是频繁的调用会使运行效率降低. 为了解决上述问题,c++中加入友元机制,友元可 ...
- 《奋斗吧!菜鸟》 第九次作业:Beta冲刺 Scrum meeting 1
项目 内容 这个作业属于哪个课程 任课教师链接 作业要求 https://www.cnblogs.com/nwnu-daizh/p/11056511.html 团队名称 奋斗吧!菜鸟 作业学习目标 掌 ...
- Oracle中修改某个字段可以为空
待修改字段假定为:shuifen 1.当该字段为空时,可直接修改: alter table reportqymx modify shuifen null; 2.当待修改字段不为空时:新增一列把要改变的 ...
- GITHUB添加SSH内容
首先,你需要注册一个 github账号,最好取一个有意义的名字,比如姓名全拼,昵称全拼,如果被占用,可以加上有意义的数字. 本文中假设用户名为 chuaaqiCSDN(我的博客名的全拼) 一.gihu ...
- python - django (logging 日志配置和简单使用)
1. settings 配置 # 配置日志 LOGGING = { 'version': 1, 'disable_existing_loggers': True, 'formatters': { 's ...