常見的設計模式:工廠模式

  設計模式,是一個在面試當中很常聽到的詞,是一些大佬們在編程的過程中,總結出來的應用於不一樣場景的代碼編寫模版,那麼今天咱們就來學習一下一個最基礎的設計模式——工廠模式。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   當中的博客,而且再加之本身的理解和話進行從新表述,也許引用的例子會大部分相似,還請諒解。

相關文章
相關標籤/搜索