工廠模式主要是爲建立對象提供過渡接口,以便將建立對象的具體過程屏蔽隔離起來,達到提升靈活性的目的。
工廠模式能夠分爲三類: java
1)簡單工廠模式(Simple Factory)
2)工廠方法模式(Factory Method)
3)抽象工廠模式(Abstract Factory) 編程
這三種模式從上到下逐步抽象,而且更具通常性。 設計模式
GOF在《設計模式》一書中將工廠模式分爲兩類:工廠方法模式(Factory Method)與抽象工廠模式(Abstract Factory)。將簡單工廠模式(Simple Factory)看爲工廠方法模式的一種特例,二者歸爲一類。ide
(1)簡單工廠模式spa
背景:一個用戶要生產不一樣類型的車,如寶馬、奧迪、奔馳等,用戶不用在本身的類中直接new,而是經過簡單的工廠進行生產,可是成產的車輛強依賴於用戶的傳參需求。類圖以下設計
/** * Open Free. * Code for Open Community, free to use! */ package designpattern.simpefactory; /** * @author admin * @version $Id Car.java, v 0.1 2015-10-18 下午1:02 admin Exp $$ */ public class Car { } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.simpefactory; /** * @author admin * @version $Id Audi.java, v 0.1 2015-10-18 下午1:06 admin Exp $$ */ public class Audi extends Car { public Audi() { System.out.println("Product AudiBusiness!"); } } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.simpefactory; import com.sun.tools.doclets.internal.toolkit.util.SourceToHTMLConverter; /** * @author admin * @version $Id Benz.java, v 0.1 2015-10-18 下午1:04 admin Exp $$ */ public class Benz extends Car { public Benz() { super(); System.out.println("Product BenzBusiness!"); } } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.simpefactory; /** * @author admin * @version $Id Bmw.java, v 0.1 2015-10-18 下午1:03 admin Exp $$ */ public class Bmw extends Car { public Bmw() { super(); System.out.println("Product BmwBusiness!"); } } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.simpefactory; /** * @author admin * @version $Id CarFactory.java, v 0.1 2015-10-18 下午1:06 admin Exp $$ */ public class CarFactory { public static Car createCar(String type){ if (type.equals("AudiBusiness")){ return new Audi(); }else if (type.equals("BenzBusiness")){ return new Benz(); }else if (type.equals("BmwBusiness")){ return new Bmw(); } return null; } } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.simpefactory; /** * @author admin * @version $Id Customer.java, v 0.1 2015-10-18 下午1:16 admin Exp $$ */ public class Customer { public static void main(String[] args) { //生產一個寶馬 Car car = CarFactory.createCar("BmwBusiness"); if (car == null) { System.out.println("Procuct BmwBusiness failed!"); } //生產一個奧迪 Car car1 = CarFactory.createCar("AudiBusiness"); if (car1 == null) { System.out.println("Product AudiBusiness failed!"); } //生產一個奔馳 Car car2 = CarFactory.createCar("BenzBusiness"); if (car2 == null) { System.out.println("Product BenzBusiness failed!"); } //生產一個大衆 Car car3 = CarFactory.createCar("dazhong"); if (car3 == null) { System.out.println("Product 大衆 failed!"); } } }
運行結果:code
Product BmwBusiness! Product AudiBusiness! Product BenzBusiness! Product 大衆 failed!
(2)工廠模式對象
對於簡單的工廠強依賴於用戶輸入,並且當增長了一個新的車輛種類時,對於工廠須要進行修改容易破壞原來的代碼邏輯,不符合開閉原則。以下是工廠模式blog
每一種車型都已一種對應的工廠,當新增車型時只用擴展,不用修改就可以完成新的車型工廠生產。接口
/** * Open Free. * Code for Open Community, free to use! */ package designpattern.factorymethod; /** * @author admin * @version $Id Car.java, v 0.1 2015-10-18 下午1:02 admin Exp $$ */ public class Car { } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.factorymethod; /** * @author admin * @version $Id Audi.java, v 0.1 2015-10-18 下午1:06 admin Exp $$ */ public class Audi extends Car { public Audi() { System.out.println("Product AudiBusiness!"); } } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.factorymethod; /** * @author admin * @version $Id Benz.java, v 0.1 2015-10-18 下午1:04 admin Exp $$ */ public class Benz extends Car { public Benz() { super(); System.out.println("Product BenzBusiness!"); } } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.factorymethod; /** * @author admin * @version $Id Bmw.java, v 0.1 2015-10-18 下午1:03 admin Exp $$ */ public class Bmw extends Car { public Bmw() { super(); System.out.println("Product BmwBusiness!"); } } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.factorymethod; /** * @author admin * @version $Id CarFactory.java, v 0.1 2015-10-18 下午1:06 admin Exp $$ */ public interface CarFactory { public Car createCar(); } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.factorymethod; /** * @author admin * @version $Id AudiFactory.java, v 0.1 2015-10-18 下午1:35 admin Exp $$ */ public class AudiFactory implements CarFactory { @Override public Car createCar() { return new Audi(); } } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.factorymethod; /** * @author admin * @version $Id BenzFactory.java, v 0.1 2015-10-18 下午1:36 admin Exp $$ */ public class BenzFactory implements CarFactory { @Override public Car createCar() { return new Benz(); } } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.factorymethod; /** * @author admin * @version $Id BmwFactory.java, v 0.1 2015-10-18 下午1:36 admin Exp $$ */ public class BmwFactory implements CarFactory { @Override public Car createCar() { return new Bmw(); } } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.factorymethod; /** * @author admin * @version $Id Customer.java, v 0.1 2015-10-18 下午1:16 admin Exp $$ */ public class Customer { public static void main(String[] args) { //生產一個寶馬 CarFactory carFactory = new BmwFactory(); Car car = carFactory.createCar(); if (car == null) { System.out.println("Procuct BmwBusiness failed!"); } //生產一個奧迪 carFactory = new AudiFactory(); Car car1 = carFactory.createCar(); if (car1 == null) { System.out.println("Product AudiBusiness failed!"); } //生產一個奔馳 carFactory = new BenzFactory(); Car car2 = carFactory.createCar(); if (car2 == null) { System.out.println("Product BenzBusiness failed!"); } } }
運行結果:
Product BmwBusiness! Product AudiBusiness! Product BenzBusiness!
(3)抽象工廠模式
抽象工廠使用的時候主要是業務比較複雜的時候纔會考慮,好比當車的種類已經不單單是一個維度了,除了車的品牌,還要涉及到車的類型,如跑車、商務車等。此時車也要拆分到多個維度、跑車,商務車等。
/** * Open Free. * Code for Open Community, free to use! */ package designpattern.abstractfactory; /** * @author admin * @version $Id BusinessCar.java, v 0.1 2015-10-18 下午2:00 admin Exp $$ */ public class BusinessCar { } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.abstractfactory; /** * @author admin * @version $Id SportsCar.java, v 0.1 2015-10-18 下午2:01 admin Exp $$ */ public class SportsCar { } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.abstractfactory; /** * @author admin * @version $Id AudiBusiness.java, v 0.1 2015-10-18 下午1:06 admin Exp $$ */ public class AudiBusiness extends BusinessCar { public AudiBusiness() { System.out.println("Product AudiBusiness!"); } } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.abstractfactory; /** * @author admin * @version $Id BenzBusiness.java, v 0.1 2015-10-18 下午1:04 admin Exp $$ */ public class BenzBusiness extends BusinessCar { public BenzBusiness() { super(); System.out.println("Product BenzBusiness!"); } } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.abstractfactory; /** * @author admin * @version $Id BmwBusiness.java, v 0.1 2015-10-18 下午1:03 admin Exp $$ */ public class BmwBusiness extends BusinessCar { public BmwBusiness() { super(); System.out.println("Product BmwBusiness!"); } } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.abstractfactory; /** * @author admin * @version $Id AudiBusiness.java, v 0.1 2015-10-18 下午1:06 admin Exp $$ */ public class AudiSports extends SportsCar { public AudiSports() { System.out.println("Product AudiSports!"); } } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.abstractfactory; /** * @author admin * @version $Id BenzSports.java, v 0.1 2015-10-18 下午1:04 admin Exp $$ */ public class BenzSports extends SportsCar { public BenzSports() { super(); System.out.println("Product BenzSports!"); } } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.abstractfactory; /** * @author admin * @version $Id BmwSports.java, v 0.1 2015-10-18 下午1:03 admin Exp $$ */ public class BmwSports extends SportsCar { public BmwSports() { super(); System.out.println("Product BmwSports!"); } } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.abstractfactory; /** * @author admin * @version $Id CarFactory.java, v 0.1 2015-10-18 下午1:06 admin Exp $$ */ public interface CarFactory { public SportsCar createSportsCar(); public BusinessCar createBusinessCar(); } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.abstractfactory; /** * @author admin * @version $Id AudiFactory.java, v 0.1 2015-10-18 下午2:15 admin Exp $$ */ public class AudiFactory implements CarFactory { @Override public SportsCar createSportsCar() { return new AudiSports(); } @Override public BusinessCar createBusinessCar() { return new AudiBusiness(); } } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.abstractfactory; /** * @author admin * @version $Id BenzFactory.java, v 0.1 2015-10-18 下午2:17 admin Exp $$ */ public class BenzFactory implements CarFactory { @Override public SportsCar createSportsCar() { return new BenzSports(); } @Override public BusinessCar createBusinessCar() { return new BenzBusiness(); } } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.abstractfactory; /** * @author admin * @version $Id BmwFactory.java, v 0.1 2015-10-18 下午2:18 admin Exp $$ */ public class BmwFactory implements CarFactory { @Override public SportsCar createSportsCar() { return new BmwSports(); } @Override public BusinessCar createBusinessCar() { return new BmwBusiness(); } } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.abstractfactory; /** * @author admin * @version $Id Customer.java, v 0.1 2015-10-18 下午1:16 admin Exp $$ */ public class Customer { public static void main(String[] args) { /**生產寶馬*/ CarFactory carFactory = new BmwFactory(); //跑車 SportsCar sportsCar = carFactory.createSportsCar(); //商務車 BusinessCar businessCar = carFactory.createBusinessCar(); /**生產奧迪*/ carFactory = new AudiFactory(); //跑車 sportsCar = carFactory.createSportsCar(); //商務車 businessCar = carFactory.createBusinessCar(); /**生產一個奔馳*/ carFactory = new BmwFactory(); //跑車 sportsCar = carFactory.createSportsCar(); //商務車 businessCar = carFactory.createBusinessCar(); } }
1.一個系統不該當依賴於產品類實例如何被建立、組合和表達的細節,這對於全部形態的工廠模式都是重要的。
2.這個系統的產品有多於一個的產品族,而系統只消費其中某一族的產品。
3.同屬於同一個產品族的產品是在一塊兒使用的,這一約束必須在系統的設計中體現出來。
4.系統提供一個產品類的庫,全部的產品以一樣的接口出現,從而使客戶端不依賴於實現。
分離接口和實現
客戶端使用抽象工廠來建立須要的對象,而客戶端根本就不知道具體的實現是誰,客戶端只是面向產品的接口編程而已。也就是說,客戶端從具體的產品實現中解耦。