zoukankan      html  css  js  c++  java
  • 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("
    ");
    		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

  • 相关阅读:
    高并发时,使用Redis应注意的问题 及 Redis缓存帮助类
    NetCore3.1 如何添加带有JWT Token 验证的Swagger
    CSS 技巧一则 -- 不定宽溢出文本适配滚动
    ROS costmap_2d局部障碍物无法清除和机器人到点摇摆
    ROS OccupancyGrid使用说明
    ROS RVIZ显示点云地图的二维投影
    Linux 文档生成器doxygen
    高翔博士 资源索引
    SLAM中的数学基础 第四篇 李群与李代数2
    shell(8):循环
  • 原文地址:https://www.cnblogs.com/baxianhua/p/11648485.html
Copyright © 2011-2022 走看看