設計模式,是一個在面試當中很常聽到的詞,是一些大佬們在編程的過程中,總結出來的應用於不一樣場景的代碼編寫模版,那麼今天咱們就來學習一下一個最基礎的設計模式——工廠模式。java
工廠模式屬於建立型的設計模式,顧名思義,所謂的工廠,就是專門用來生產的,那麼在編程當中,工廠模式的工廠,就是專門爲咱們生產 「實例」 的。在日常的使用當中,好比A類當中的某個方法須要使用到B類,則須要A類在本身的方法當中對B類進行new出一個實例,以後再進行應用,而這時候C類若是也須要在本身的方法當中使用B類,則也須要在本身的方法當中對B類實例化,這時候若是將B類實例化這個工做交與D類去作,而A類和C類都直接從D類去獲取B類的實例直接進行使用,那麼這時候的D類,就是咱們所說的工廠類。也許你會問,不就是一個new操做嘛,何須須要再弄一個D類來new,不是更麻煩嗎?若是咱們約定,對B類進行實例化後,須要對B類當中的100種變量進行從新賦值(這裏只是打個比方,實際上不會有那麼變態的場景,之因此這麼說,是爲了表述B的實例化變爲了一個複雜的過程)才能對B類的實例進行使用呢?這時候若是不引用D類(工廠類)那麼須要在A類當中的方法寫101行代碼,在C類當中的方法也寫相同的101行代碼,這就顯得很複雜了,因此這時候咱們的工廠類就登場了。面試
那麼接下來咱們先介紹工廠模式當中的最簡單的形式——靜態工廠模式(簡單工廠模式)編程
1.簡單工廠模式:在靜態工廠模式當中有這麼幾個概念:設計模式
1)工廠類:即要生產產品(實例)的類;ide
2)抽象產品:它通常是具體產品繼承的父類或者實現的接口。 學習
3)具體產品:工廠類所建立的對象就是此角色的實例。在Java中由一個具體類實現。 ui
首先咱們來設定這麼一個背景:想必你們對本田車(Honda車)有一點的瞭解,那麼假定如今有兩種型號的本田車,CRV和URV,用戶可能會對這兩種車進行使用。那麼在這裏例子當中呢,咱們的工廠類就是本田車廠,抽象產品爲Honda車,而具體產品爲:CRV和URV,接下來咱們看看代碼。this
public interface Honda { //抽象產品 public void CarVersion(); }
//具體產品 public class CRV implements Honda { @Override public void CarVersion() { System.out.println("this is CRV"); } } class URV implements Honda { @Override public void CarVersion() { System.out.println("this is URV"); } }
//工廠類 public class HondaFactory { public Honda createTheCar(String version) { switch (version) { case "CRV": return new CRV(); case "URV": return new URV(); default: break; } return null; } }
//客戶類、 public class Customer { public static void main(String[] args) { HondaFactory f=new HondaFactory(); Honda crv=f.createTheCar("CRV"); crv.CarVersion(); Honda urv=f.createTheCar("URV"); urv.CarVersion(); } }
//運行結果 this is CRV this is URV
能夠看到,客戶根本不關心這兩種車是怎麼實現的,客戶類所作的操做就是到工廠類提 「車」,這就是簡單的工廠模式,那麼這種簡單的工廠模式會有一個很大的侷限性,就是若是咱們再加一種車型叫作XRV,那麼咱們就須要對工廠類進行改造,添加switch當中的case,這是很不方便的,爲了解決這個問題,又提出了工廠方法模式。spa
2.工廠方法模式.net
工廠方法模式比起簡單的工廠模式來講,不一樣點就在於它將工廠類也分爲了抽象工廠和具體的工廠,抽象工廠呢,它是具體工廠角色必須實現的接口或者必須繼承的父類。在java中它由抽象類或者接口來實現。 在這個例子當中,咱們的抽象工廠就是Honda的造車廠,而具體的工廠,就分化出來了CRV的造車廠,URV的造車廠,用這樣的方法,在添加一種車型叫XRV的話,咱們只須要添加一個具體的XRV的造車廠就能夠,而不須要修改其餘任何已有的代碼。接下來看具體的代碼:
//抽象產品 public interface HondaCar { public void CarVersion(); }
//具體產品 public class CRV implements HondaCar { @Override public void CarVersion() { System.out.println("this is CRV"); } } class URV implements HondaCar { @Override public void CarVersion() { System.out.println("this is URV"); } } class XRV implements HondaCar { @Override public void CarVersion() { System.out.println("this is XRV"); } }
//抽象工廠 public interface HondaFactory { HondaCar buildTheCar(); }
//具體工廠 public class CRVFactory implements HondaFactory { @Override public HondaCar buildTheCar() { // TODO Auto-generated method stub return new CRV(); } } class URVFactory implements HondaFactory { @Override public HondaCar buildTheCar() { // TODO Auto-generated method stub return new URV(); } } class XRVFactory implements HondaFactory { @Override public HondaCar buildTheCar() { // TODO Auto-generated method stub return new XRV(); } }
//客戶 public class Customer { public static void main(String[] args) { HondaFactory c=new CRVFactory(); HondaCar crv=c.buildTheCar(); crv.CarVersion(); HondaFactory u=new URVFactory(); HondaCar urv=u.buildTheCar(); urv.CarVersion(); HondaFactory x=new XRVFactory(); HondaCar xrv=x.buildTheCar(); xrv.CarVersion(); } }
//運行結果 this is CRV this is URV this is XRV
經過工廠方法模式,咱們看似完美的解決了添加車型的問題,可是,若是因爲車型的不一樣,致使車上的配件的檔次也不相同,好比說:在URV上,咱們須要裝高級的空調和座椅,而CRV上咱們可能就裝中級的空調和座椅,那麼這時候咱們就須要採用抽象工廠的方法的形式來解決。這裏咱們來舉個例子來講明抽象工廠和工廠方法的區別:
咱們依然拿生產汽車的例子來講明他們之間的區別。
在上面的類圖中,兩廂車和三廂車稱爲兩個不一樣的等級結構;而2.0排量車和2.4排量車則稱爲兩個不一樣的產品族。再具體一點,2.0排量兩廂車和2.4排量兩廂車屬於同一個等級結構,2.0排量三廂車和2.4排量三廂車屬於另外一個等級結構;而2.0排量兩廂車和2.0排量三廂車屬於同一個產品族,2.4排量兩廂車和2.4排量三廂車屬於另外一個產品族。
明白了等級結構和產品族的概念,就理解工廠方法模式和抽象工廠模式的區別了,若是工廠的產品所有屬於同一個等級結構,則屬於工廠方法模式;若是工廠的產品來自多個等級結構,則屬於抽象工廠模式。在本例中,若是一個工廠模式提供2.0排量兩廂車和2.4排量兩廂車,那麼他屬於工廠方法模式;若是一個工廠模式是提供2.4排量兩廂車和2.4排量三廂車兩個產品,那麼這個工廠模式就是抽象工廠模式,由於他提供的產品是分屬兩個不一樣的等級結構。固然,若是一個工廠提供所有四種車型的產品,由於產品分屬兩個等級結構,他固然也屬於抽象工廠模式了。(參考:http://blog.csdn.net/zhengzhb/article/details/7359385/)
明白了以後咱們再回到咱們的本田車的例子當中,接下來咱們來看看本田車的抽象工廠去實現CRV使用中級座椅和空調,而URV使用高級座椅和空調的代碼:
//抽象產品接口 public interface HondaCar { public void CarVersion(); } public interface AirCondition { void AirconditionVersion(); } public interface Seat { void SeatLevel(); }
//具體產品類 class highAC implements AirCondition { @Override public void AirconditionVersion() { System.out.println("this is high AC"); } } class MiddleAC implements AirCondition { @Override public void AirconditionVersion() { System.out.println("this is middle AC"); } } class HighSeat implements Seat { @Override public void SeatLevel() { System.out.println("this is the High seat"); } } class MiddleSeat implements Seat { @Override public void SeatLevel() { System.out.println("this is the Middle seat"); } } class CRV implements HondaCar { @Override public void CarVersion() { System.out.println("this is CRV"); } } class URV implements HondaCar { @Override public void CarVersion() { System.out.println("this is URV"); } } class XRV implements HondaCar { @Override public void CarVersion() { System.out.println("this is XRV"); } }
//抽象工廠 public interface HondaFactory { HondaCar buildTheCar(); AirCondition getTheAirCondition(); Seat getTheSeat(); }
//具體工廠 public class CRVFactory implements HondaFactory { @Override public HondaCar buildTheCar() { // TODO Auto-generated method stub return new CRV(); } @Override public AirCondition getTheAirCondition() { // TODO Auto-generated method stub return new MiddleAC(); } @Override public Seat getTheSeat() { // TODO Auto-generated method stub return new MiddleSeat(); } } class URVFactory implements HondaFactory { @Override public HondaCar buildTheCar() { // TODO Auto-generated method stub return new URV(); } @Override public AirCondition getTheAirCondition() { // TODO Auto-generated method stub return new highAC(); } @Override public Seat getTheSeat() { // TODO Auto-generated method stub return new HighSeat(); } }
//客戶 public class Customer { public static void main(String[] args) { HondaFactory c=new CRVFactory(); HondaCar crv=c.buildTheCar(); crv.CarVersion(); HondaFactory u=new URVFactory(); HondaCar urv=u.buildTheCar(); urv.CarVersion(); } }
到此,工廠模式就介紹完畢了。
總結一下:
簡單工廠模式:對於增長新產品無能爲力
工廠方法模式:經過新增實現具體工廠類的方式,能夠增長新產品。
抽象工廠模式:對增長新產品無能爲力,可是能夠增長新產品族
本文參考了:http://blog.csdn.net/jason0539/article/details/23020989#comments 當中的博客,而且再加之本身的理解和話進行從新表述,也許引用的例子會大部分相似,還請諒解。