python 設計模式之工廠模式 Factory Pattern (簡單工廠模式,工廠方法模式,抽象工廠模式)

十一回了趟老家,十一前工做一大堆忙成了狗,十一回來後又積累了一大堆又 忙成了狗,今天恰好抽了一點空開始寫工廠方法模式html

 

我看了《Head First 設計模式》P109--P133 這25頁,講述了咱們爲何要用工廠模式,裏面用作pizza的例子講的特別細膩。看完了就能很清楚的知道爲何要用工廠模式。java

年齡越大越不喜歡只知其一;不知其二,深入的瞭解某些未知的事或物之後,它再出現就不怕了python

 

 

 #'New'有什麼不對勁?

在技術上,new沒有錯,這是語言的基礎部分。真正的犯人是咱們的老朋友 ‘改變’, 以及它是如何影響new使用的。sql

 

若是代碼是經過接口而寫,經過多態,能夠與任何新類實現該接口。數據庫

可是當代碼使用大量的具體類時,那就麻煩了,由於一旦加入新的具體類,就必須改變代碼。意思是代碼沒 " 對修改關閉"。想用新的具體類來擴展代碼,必須從新打開它。編程

 

這可咋辦?  只能改代碼設計模式

 

 

 

 很明顯,若是實例化某些具體類,將使orderPizza()出問題,沒辦法讓orderPizza()對修改關閉,ui

可是我們仍是能很明顯的看出哪些會變,哪些不會變,這個時候就能夠考慮封裝了,this

 

 

   

 上面這些引出了下面的簡單工廠模式.net

 

#簡單工廠模式

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

相關文章
相關標籤/搜索