1. 程式人生 > >2.java設計模式-抽象工廠模式

2.java設計模式-抽象工廠模式

抽象工廠模式簡介:

      每一個模式都是針對某一種問題的解決方案。抽象工廠模式與工廠模式最大的區別在於,工廠模式針對的是一個產品等級結構,而抽象工廠模式面對的是多個產品等級結構,即產品族的概念。

     這裡講解一下產品等級與產品族:Cpu屬於一種產品,Cpu有多種型號,比如Intel的、AMD的,它們都屬於同一個產品等級,即同一類產品下邊的不同系列或者品牌;而產品族是指位於不同產品等級結構中,功能相關聯的產品組成的家族。比如對於Intel公司,這家公司生產的Cpu,也生產主機板,記憶體,晶片組等相關聯產品組成一個產品族。所以我們只要知道某個產品所屬的產品族,以及這個產品在產品族中的產品等級結構,就可以唯一確定這個產品。

    顯然,每一個產品族中含有產品的數目,與產品等級結構的數目是相等的。而在工廠模式中,需要建立的工廠類數量等於產品等級結構數目。由於這三個產品等級結構的相似性,會導致三個平行的工廠等級結構。隨著產品等級結構的數目的增加,工廠方法模式所給出的工廠等級結構的數目也會隨之增加。如下圖:

造成大量重複性程式碼,這樣違背了軟體設計初衷。

那麼是否可以將這些極為相似的產品等級工廠程式碼用同一個產品等級工廠代替呢?當然可以,這就是產品族的概念,之前是縱向構建了多個產品等級工廠,那麼我們改為橫向的使用產品族來構建一個產品族工廠,這個與我們現實世界的工廠更為相似。如圖:

顯然,這種工廠模式更有效率。

抽象工廠模式詳解:

     抽象工廠模式是物件的建立模式,它是工廠模式的進一步推廣。假設一個子系統需要多個產品物件,而這些產品物件又不處於同一個產品等級,為了將消費這些產品物件的責任與建立這些產品物件的責任分隔開,可以引入抽象工廠模式。這樣消費產品的一方不必參與產品的建立工作,只需要向一個工廠介面請求生產產品即可。

    由於上述兩個產品族的產品等級結構相同,所以可以繼續將兩個產品族抽象為同一個工廠族,這就是抽象工廠概念。

 

原始碼:

       前面示例實現的CPU介面和CPU實現物件,主機板介面和主機板實現物件,都不需要變化。

  工廠類需要全部重寫,新加入的抽象工廠類和實現類:

package com.itheima.factory.factory;

import com.itheima.factory.entity.CPU;
import com.itheima.factory.entity.Mainboard;
/**
 * 抽象工廠類,定義規範
 * @author Administrator
 *
 */
public interface AbstractFactory {
    /**
     * 建立CPU
     * @return
     */
    public CPU createCpu();
    /**
     * 建立主機板物件
     * @return
     */
    public Mainboard createMainboard();
}

//具體的實現類工廠
package com.itheima.factory.factory;

import com.itheima.factory.entity.CPU;
import com.itheima.factory.entity.IntelCpu;
import com.itheima.factory.entity.IntelMainboard;
import com.itheima.factory.entity.Mainboard;
/**
 * Intel工廠
 * @author Administrator
 *
 */
public class IntelFactory implements AbstractFactory {
    @Override
    public CPU createCpu() {
        // TODO Auto-generated method stub
        return new IntelCpu(755);
    }
    @Override
    public Mainboard createMainboard() {
        // TODO Auto-generated method stub
        return new IntelMainboard(755);
    }
}

package com.itheima.factory.factory;

import com.itheima.factory.entity.AmdCpu;
import com.itheima.factory.entity.AmdMainboard;
import com.itheima.factory.entity.CPU;
import com.itheima.factory.entity.Mainboard;
/**
 * AMD工廠
 * @author Administrator
 *
 */
public class AmdFactory implements AbstractFactory {

    @Override
    public CPU createCpu() {
        // TODO Auto-generated method stub
        return new AmdCpu(938);
    }
    @Override
    public Mainboard createMainboard() {
        // TODO Auto-generated method stub
        return new AmdMainboard(938);
    }
}
View Code

       組裝工程師程式碼與之前的主要區別是:現在不在需要客戶傳入Cpu與主機板的型別,而是直接傳入已經選擇後的產品物件,且產品物件已經被限制,客戶無法選擇Intel與Amd的組合了。客戶要選就是一套,一個組合。

package com.itheima.factory.engineer;

import com.itheima.factory.entity.CPU;
import com.itheima.factory.entity.Mainboard;
import com.itheima.factory.factory.AbstractFactory;

public class ComputerEngineer {
    //需要Cpu
    private CPU cpu;
    //需要主機板
    private Mainboard mainboard;
    //組裝電腦
    public void makeComputer(Class<?> c) {
        AbstractFactory factory=null;
        try {
             factory=(AbstractFactory) Class.forName(c.getName()).newInstance();
        } catch (InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        cpu=factory.createCpu();
        mainboard=factory.createMainboard();
        cpu.calculate();
        mainboard.installCpu();
        System.out.println("電腦組裝完成");
    }
}
View Code

      客戶端程式碼:

package com.itheima.factory.client;

import com.itheima.factory.engineer.ComputerEngineer;
import com.itheima.factory.factory.IntelFactory;

public class Client {
    public static void main(String[] args) {
        ComputerEngineer computerEngineer = new ComputerEngineer();
        computerEngineer.makeComputer(IntelFactory.class);
    }
}
View Code

抽象工廠的功能是為一系列相關物件或相互依賴的物件(跨產品等級)建立一個介面。一定注意介面內的方法不是任意堆砌的,而是一系列相關的或相互依賴的方法。