1. 程式人生 > >完整案例分析再加知識整合——艾特抽象工廠模式,超詳細的

完整案例分析再加知識整合——艾特抽象工廠模式,超詳細的

抽象工廠模式

模式動機與定義

模式動機

  • 產品等級結構:產品等級結構即產品的繼承結構,例如一個抽象類是電視機,其子類有海爾電視機、海信電視機、TCL電視機,則抽象電視機與具體品牌的電視機之間構成了一個產品等級結構,抽象電視機是父類,而具體品牌的電視機是其子類。
  • 產品族:在抽象工廠模式中,產品族是指由同一個工廠生產的,位於不同產品等級結構中的一組產品,例如海爾電器工廠生產的海爾電視機、海爾電冰箱,海爾電視機位於電視機產品等級結構中,海爾電冰箱位於電冰箱產品等級結構中。

 

 

模式定義

  • 抽象工廠模式(Abstract Factory Pattern):提供一個建立一系列相關或相互依賴物件的介面,而無需指定它們具體的類。抽象工廠模式又稱為Kit模式,屬於物件建立型模式。

 

 

模式結構與分析

模式結構

 

 

抽象工廠模式包含如下角色:

  • AbstractFactory:抽象工廠
  • ConcreteFactory:具體工廠
  • AbstractProduct:抽象產品
  • ConcreteProduct:具體產品

模式分析

 

 

 

 

 

 

模式例項與解析

模式例項

電器工廠:例項說明

  • 一個電器工廠可以生產多種型別的電器,如海爾工廠可以生產海爾電視機、海爾空調等,TCL工廠可以生產TCL電視機、TCL空調等,相同品牌的電器構成一個產品族,而相同型別的電器構成了一個產品等級結構,現使用抽象工廠模式模擬該場景。

電器工廠:參考類圖

 

 

電器工廠:參考程式碼

程式碼結構

 

 

Television介面

package abstractfactory;

public interface Television {
    public void play();
}

HaierTelevision類

package abstractfactory;

public class HaierTelevision implements Television {
    @Override
    public void play() {
        System.out.println("海爾電視機播放中···");
    }
}

TCLTelevision類

package abstractfactory;

public class TCLTelevision implements Television {
    @Override
    public void play() {
        System.out.println("TCL電視機播放中···");
    }
}

AirConditioner介面

package abstractfactory;

public interface AirConditioner {
    public void changeTemperature();
}

HaierAirConditioner類

package abstractfactory;

public class HaierAirConditioner implements AirConditioner {
    @Override
    public void changeTemperature() {
        System.out.println("海爾空調溫度改變中···");
    }
}

TCLAirConditioner類

package abstractfactory;

public class TCLAirConditioner implements AirConditioner {
    @Override
    public void changeTemperature() {
        System.out.println("TCL空調溫度改變中···");
    }
}

EFactory介面

package abstractfactory;

public interface EFactory {
    public Television produceTelevision();
    public AirConditioner produceAirConditioner();
}

HaierFactory類

package abstractfactory;

public class HaierFactory implements EFactory {
    @Override
    public Television produceTelevision() {
        return new HaierTelevision();
    }

    @Override
    public AirConditioner produceAirConditioner() {
        return new HaierAirConditioner();
    }
}

TCLFactory類

package abstractfactory;

public class TCLFactory implements EFactory {
    @Override
    public Television produceTelevision() {
        return new TCLTelevision();
    }

    @Override
    public AirConditioner produceAirConditioner() {
        
        return new TCLAirConditioner();
    }
}

AbstractFactoryconfig.xml

<?xml version="1.0" encoding="UTF-8"?>
<config>
<className>abstractfactory.HaierFactory</className>

</config>

XMLUtil類

package abstractfactory;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;

public class XMLUtil {

    //該方法用於從XML配置檔案中提取具體類類名,並返回一個例項物件
    public static Object getBean(){
        try {
            //建立文件物件
            DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = dFactory.newDocumentBuilder();
            Document doc;

            doc = builder.parse(new File("D:\\MyNewWorld\\Study_JAVA\\MyHome\\Write_java\\My_Maven\\src\\main\\resources\\AbstractFactoryconfig.xml"));


            //獲取包含類名的文字節點
            NodeList n1 = doc.getElementsByTagName("className");
            Node classNode = n1.item(0).getFirstChild();

            String cName = classNode.getNodeValue();

            //通過類名生成例項物件並將其返回
            Class c = Class.forName(cName);
            Object obj = c.newInstance();
            return obj;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}

Client類

package abstractfactory;

public class Client {
    public static void main(String[] args) {
        try{

            EFactory factory;
            Television tv;
            AirConditioner ac;

            factory = (EFactory) XMLUtil.getBean();
            tv = factory.produceTelevision();
            tv.play();

            ac = factory.produceAirConditioner();
            ac.changeTemperature();
        }catch (Exception e){
            System.out.println(e.getMessage());
        }
    }
}

執行結果

 

 

模式效果與應用

抽象工廠模式優點:

  • 隔離了具體類的生成,使得客戶端並不需要知道什麼被建立
  • 當一個產品族中的多個物件被設計成一起工作時,它能夠保證客戶端始終只使用同一個產品族中的物件
  • 增加新的產品族很方便,無需修改已有系統,符合開閉原則

抽象工廠模式缺點:

  • 增加新的產品等級結構麻煩,需要對原有系統進行較大的修改,甚至需要修改抽象層程式碼,這顯然會帶來較大的不便,違背了開閉原則。

在以下情況下可以使用抽象工廠模式:

  • 一個系統不應當依賴於產品類例項如何被建立、組合和表達的細節
  • 系統中有多於一個的產品族,但每次只使用其中某一產品族
  • 屬於同一個產品族的產品將在一起使用,這一約束必須在系統的設計中體現出來。
  • 產品等級結構穩定,在設計完成之後不會向系統中增加新的產品等級結構或者刪除已有的產品等級結構。

&n