JAVA抽象工廠模式·
抽象工廠模式
通過本文將學習到
1、總結
今天來個不一樣的!工廠模式三部曲,簡單工廠模式、工廠方法模式、抽象工廠模式。可謂是一個比一個強。但是各自也有各自的缺點!其實我認為工廠方法模式就非常好了。但是了,抽象工廠方式又有自己的一個優勢。哎,魚和熊掌不可兼得,看不同的專案不同的需求具體來呼叫。今天又看到一個程式設計師小哥24歲。猝死,我得媽嚇得我。以後要做自己覺得有意思的,還有要多運動運動。別一天到晚呆家裡。我得媽!
2、抽象工廠模式的概念
抽象工廠模式:提供一個建立一系列相關或者相互依賴物件的介面,而無需指定生成具體的類。
產品等級,和產品族是抽象工廠模式中非常重要的兩個概念!
產品族:在抽象工廠模式中一個具體工廠可以生產一組相關的具體產品,這樣的一組產品稱之為產品族。
產品等級:產品族中的每一個產品偶分屬於某以產品繼承等級結構。
海爾這個品牌就是一個產品族,空調可以看成是一個產品等級,或者說是一個產品型別。
如果用工廠方法建立這些工廠的話,一個產品就要一個具體的工廠來建立。3*3就要9個,但是如果用抽象工廠模式就只要建立三個。海爾,海信,TCL三個工廠。
3、抽象工廠模式的UML圖
UML
抽象工廠模式總共由
Abstractactory(抽象工廠):它聲明瞭建立一組建立產品族的方法,每一種對應一種產品。比如冰箱,洗衣機。
ConcreteFactory(具體工廠):它實現了抽象工廠中申明的一系列方法,生產一組具體的產品,這些產品構成一個產品族。每個產品都在一個產品等級結構中。
AbstractProduct(抽象產品類):它為每種產品申明介面,在抽象產品中申明瞭產品的所有業務方法。
ConcreteProduct(具體產品):具體的產品。
4、抽象工廠模式的實現
軟體公司開發一套面板庫,有按鈕,文字框,組合框。兩套型別春天型,夏天型。
抽象產品類:按鈕類。
package abstractFactoryPattern; /** * * <p>Title: Button</p> * <p>Description:abstract product class </p> * @author HAND_WEILI * @date 2018年8月30日 */ public abstract class Button { private String style; private int width; private int height; public String getStyle() { return style; } public void setStyle(String style) { this.style = style; } public int getWidth() { return width; } public void setWidth(int width) { this.width = width; } public int getHeight() { return height; } public void setHeight(int height) { this.height = height; } public Button(int h,int w ,String s) { this.style=s; this.width=w; this.height=h; } public abstract void show(); }
具體產品類:春天按鈕。
package abstractFactoryPattern;
public class SpringButton extends Button {
public SpringButton() {
super(20,30,"微軟風格");
}
@Override
public void show() {
// TODO Auto-generated method stub
System.out.println("春天風格的"+this.getHeight()+"高"+this.getWidth()+"寬"+this.getStyle()+"按鈕");
}
}
具體產品類:夏天按鈕。
package abstractFactoryPattern;
public class SummerButton extends Button {
public SummerButton(int h, int w, String s) {
super(h, w, s);
// TODO Auto-generated constructor stub
}
@Override
public void show() {
// TODO Auto-generated method stub
System.out.println("夏天風格的"+this.getHeight()+"高"+this.getWidth()+"寬"+this.getStyle()+"按鈕");
}
}
抽象產品類:文字框
package abstractFactoryPattern;
/**
*
* <p>Title: TextField</p>
* <p>Description: 文字框抽象產品</p>
* @author HAND_WEILI
* @date 2018年8月30日
*/
public abstract class TextField {
public abstract void show();
}
具體產品類:春天文字框。
package abstractFactoryPattern;
public class SpringTextField extends TextField {
public SpringTextField() {
// TODO Auto-generated constructor stub
}
@Override
public void show() {
// TODO Auto-generated method stub
System.out.println("春天型別的文字框");
}
}
具體產品類:夏天文字框
package abstractFactoryPattern;
public class SummerTextField extends TextField {
public SummerTextField() {
// TODO Auto-generated constructor stub
}
@Override
public void show() {
// TODO Auto-generated method stub
System.out.println("夏天風格的文字框");
}
}
核心,抽象工廠類:面板抽象工廠。
package abstractFactoryPattern;
/**
*
* <p>Title: SkinFactory</p>
* <p>Description: 面板抽象工廠 兩個方法,就是一個產品族。建立按鈕和文字框
* 缺點:在加一個產品等級就很麻煩
* </p>
* @author HAND_WEILI
* @date 2018年8月30日
*/
public abstract class SkinFactory {
//兩個工廠 ,兩個產品等級 ,加一個就升一級
public abstract Button buttonFactory();
public abstract TextField textFieldFactory();
//public abstract xxxx xxxFactory();
}
具體工廠:春天面板工廠。
package abstractFactoryPattern;
public class SpringSkinFactory extends SkinFactory {
@Override
public Button buttonFactory() {
// TODO Auto-generated method stub
//呼叫這個工廠方法就是生產一個對應的春天的button
return new SpringButton();
}
@Override
public TextField textFieldFactory() {
// TODO Auto-generated method stub
//同理
return new SpringTextField();
}
}
具體工廠:夏天面板工廠。
package abstractFactoryPattern;
public class SummerSkinFactory extends SkinFactory {
@Override
public Button buttonFactory() {
// TODO Auto-generated method stub
return new SummerButton(20, 20, "夏天下,");
}
@Override
public TextField textFieldFactory() {
// TODO Auto-generated method stub
return new SummerTextField();
}
}
通過XMLUtils讀取配置檔案來建立相對應得xml配置檔案。首先你要建立xml檔案。
<?xml version ="1.0"?>
<config>
<className>abstractFactoryPattern.SpringSkinFactory</className>
</config>
XMLUtils工具類,用來讀取。xml檔案得資訊,並通過反射得方式獲取具體得工廠。比如春天面板工廠。
package abstractFactoryPattern;
import java.io.File;
import java.io.IOException;
import javax.xml.*;
import org.w3c.*;
import org.xml.sax.SAXException;
/**
*
* <p>Title: XMLUtils</p>
* <p>Description:此方法用來讀取xml中工廠的配置檔案,同過射進行建立對應的工廠 </p>
* @author HAND_WEILI
* @date 2018年8月30日
*/
public class XMLUtils {
public static Object getClassname() {
//獲取xml檔案,獲取檔案都是用w3c這個類的文件建造者工廠來獲得
try {
DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dFactory.newDocumentBuilder();
//同故dbuilder強轉成doc w3c的類。
Document doc ;
//對應的配置檔案的
doc = dBuilder.parse(new File("src//abstractFactoryPattern//config.xml"));
//接下來獲取對應的工廠類名
NodeList nl =doc.getElementsByTagName("className");
Node n = nl.item(0).getFirstChild();
String name = n.getNodeValue();
//通過類名生成例項物件並將其返回
Class c = Class.forName(name);
//生成例項
Object obj = c.newInstance();
return obj;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
測試類:client
package abstractFactoryPattern;
public class Client {
public static void main(String[] args) {
//建立對應的按鈕。 只建立父類。
SkinFactory sFactory;
Button btn;
TextField tField;
//獲取對應的工廠
sFactory =(SpringSkinFactory)XMLUtils.getClassname();
btn = sFactory.buttonFactory();
tField = sFactory.textFieldFactory();
btn.show();
tField.show();
}
}
如果你想要改一個工廠很簡單。修改對應的xml檔案 。
象這樣
<?xml version ="1.0"?>
<config>
<!-- <className>abstractFactoryPattern.SpringSkinFactory</className>--><className>abstractFactoryPattern.SummerSkinFactory</className>
</config>
5、抽象工廠模式的優缺點
優點:抽象工廠模式最大的優點就是建立一個新的產品族非常簡單。就是再來一個面板工廠,什麼秋天,春天。都很簡單隻要新建就好了。
缺點:缺點就是不好建立產品等級的結構。要是建立這樣的那就必須修改原始檔不符合開閉原則。開啟繼承,關閉修改。
6、抽象工廠模式的使用場景
1、產品等級結構穩定,在設計完成之後不會向系統增加新的產品等級或者刪除已有的等級結構。
2、系統中有多於一個的產品族,而每次只用其中一個產品族。可以通過配置檔案來使使用者能夠動態的改變產品族,也可以很方便增加新的產品族。
3、屬於同一個產品族的產品將在一起使用,這以約束條件在系統設計中體現出來。同一個產品族中的產品可以使沒有任何關係的物件,但是他們都具有同一個約束,如同一作業系統下的文字框和按鈕。
4、一個系統不應當依賴於產品類例項如何被建立、組合、表達和表達的細節,這點對於所有的工廠模式都是很重要的,使用者無需關心物件的建立過程,將物件的建立和使用解耦!