簡(jiǎn)介
工廠模式有三種:簡(jiǎn)單工廠模式测暗,工廠方法模式,抽象工廠模式奠骄,這三種都屬于工廠模式辰狡,但各有不同。
簡(jiǎn)單工廠模式
簡(jiǎn)單工廠模式屬于類的創(chuàng)建型模式,又叫做靜態(tài)工廠方法模式祈惶。通過(guò)專門定義一個(gè)類來(lái)負(fù)責(zé)創(chuàng)建其他類的實(shí)例雕旨,被創(chuàng)建的實(shí)例通常都具有共同的父類扮匠。
模式中包含的角色及其職責(zé)
1.工廠(Creator)角色:簡(jiǎn)單工廠模式的核心捧请,它負(fù)責(zé)實(shí)現(xiàn)創(chuàng)建所有實(shí)例的內(nèi)部邏輯。工廠類可以被外界直接調(diào)用棒搜,創(chuàng)建所需的產(chǎn)品對(duì)象疹蛉。
2.抽象(Product)角色:簡(jiǎn)單工廠模式所創(chuàng)建的所有對(duì)象的父類,它負(fù)責(zé)描述所有實(shí)例所共有的公共接口力麸。
3.具體產(chǎn)品(Concrete Product)角色:簡(jiǎn)單工廠模式所創(chuàng)建的具體實(shí)例對(duì)象可款。
下面來(lái)看一個(gè)例子:
//先寫工廠角色
public class FruitFactory {
/*
* 獲得Apple類的實(shí)例(第一種寫法)
*/
public static Fruit getApple() {
return new Apple();
}
/*
* 獲得Banana類實(shí)例(第一種寫法)
*/
public static Fruit getBanana() {
return new Banana();
}
//(第二種寫法)傳入類名的字符串做判斷后產(chǎn)生對(duì)應(yīng)的實(shí)體類對(duì)象
public static Fruit getFruit(String type) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
if(type.equalsIgnoreCase("apple")) {
return Apple.class.newInstance();
} else if(type.equalsIgnoreCase("banana")) {
return Banana.class.newInstance();
} else {
System.out.println("找不到相應(yīng)的實(shí)例化類");
return null;
}
//第三種寫法,傳入類名克蚂,運(yùn)用Java的反射機(jī)制生成實(shí)體類對(duì)象
Class fruit = Class.forName(type);
return (Fruit) fruit.newInstance();
}
}
//再寫抽象角色(水果接口)
public interface Fruit {
/*
* 采集
*/
public void get();
}
//再寫兩個(gè)具體產(chǎn)品角色實(shí)現(xiàn)抽象接口(蘋果類)
public class Apple implements Fruit{
/*
* 采集
*/
public void get(){
System.out.println("采集蘋果");
}
}
//香蕉類
public class Banana implements Fruit{
/*
* 采集
*/
public void get(){
System.out.println("采集香蕉");
}
}
//主類(客戶端)
public class MainClass {
public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
//實(shí)例化一個(gè)Apple(從工廠中獲裙刖ā)(第一種寫法)
Fruit apple = FruitFactory.getApple();
Fruit banana = FruitFactory.getBanana();
apple.get();
banana.get();
//(第二種寫法)
Fruit apple = FruitFactory.getFruit("Apple");
Fruit banana = FruitFactory.getFruit("Banana");
apple.get();
banana.get();
}
}
運(yùn)行結(jié)果:
采集蘋果
采集香蕉
簡(jiǎn)單工廠模式的優(yōu)缺點(diǎn)
1.在這個(gè)模式中,工廠類是整個(gè)模式的關(guān)鍵所在埃叭。它包含必要的判斷邏輯摸恍,能夠根據(jù)外界給定的信息,決定究竟應(yīng)該創(chuàng)建哪個(gè)具體類的對(duì)象赤屋。用戶在使用時(shí)可以直接根據(jù)工廠類去創(chuàng)建所需的實(shí)例立镶,而無(wú)需了解這些對(duì)象是如何創(chuàng)建以及如何組織的。有利于整個(gè)軟件體系結(jié)構(gòu)的優(yōu)化类早。
2.不難發(fā)現(xiàn)媚媒,<font color=red>簡(jiǎn)單工廠模式的缺點(diǎn)也正體現(xiàn)在其工廠類上,由于工廠類集中了所有實(shí)例的創(chuàng)建邏輯涩僻,所以“高內(nèi)聚”方面做的并不好缭召。另外,當(dāng)系統(tǒng)中的具體產(chǎn)品類不斷增多時(shí)逆日,可能會(huì)出現(xiàn)要求工廠類也要做相應(yīng)的修改嵌巷,擴(kuò)展性并不很好</font>。
工廠方法模式
工廠方法模式同樣屬于類的創(chuàng)建型模式又被稱為多態(tài)工廠模式 屏富。工廠方法模式的意義是定義一個(gè)創(chuàng)建產(chǎn)品對(duì)象的工廠接口晴竞,將實(shí)際創(chuàng)建工作推遲到子類當(dāng)中。核心工廠類不再負(fù)責(zé)品的創(chuàng)建狠半,這樣核心類成為一個(gè)抽象工廠角色噩死,僅負(fù)責(zé)具體工廠子類必須實(shí)現(xiàn)的接口颤难,<font color=red>這樣進(jìn)一步抽象化的好處是使得工廠方法模式可以使系統(tǒng)在不修改具體工廠角色的情況下引進(jìn)新的產(chǎn)品。</font>
模式中包含的角色及其職責(zé)
1.抽象工廠(Creator)角色:工廠方法模式的核心已维,任何工廠類都必須實(shí)現(xiàn)這個(gè)接口行嗤。
2.具體工廠( Concrete Creator)角色:具體工廠類是抽象工廠的一個(gè)實(shí)現(xiàn),負(fù)責(zé)實(shí)例化產(chǎn)品對(duì)象垛耳。
3.抽象(Product)角色:工廠方法模式所創(chuàng)建的所有對(duì)象的父類栅屏,它負(fù)責(zé)描述所有實(shí)例所共有的公共接口。
4.具體產(chǎn)品(Concrete Product)角色:工廠方法模式所創(chuàng)建的具體實(shí)例對(duì)象堂鲜。
對(duì)于簡(jiǎn)單工廠模式來(lái)說(shuō)栈雳,工廠方法模式把那個(gè)工廠又抽象化了一層,具體的實(shí)體類對(duì)象的創(chuàng)建推遲放到具體的工廠中去
看例子:
//先寫那個(gè)抽象工廠角色 工廠方法模式的核心缔莲,任何工廠類都必須實(shí)現(xiàn)這個(gè)接口哥纫。
public interface FruitFactory {
public Fruit getFruit();
}
//再寫具體工廠角色(要實(shí)現(xiàn)抽象工廠這個(gè)接口,蘋果工廠) 具體工廠類是抽象工廠的一個(gè)實(shí)現(xiàn)痴奏,負(fù)責(zé)實(shí)例化產(chǎn)品對(duì)象
public class AppleFactory implements FruitFactory {
public Fruit getFruit() {
return new Apple();
}
}
//香蕉工廠 具體工廠類是抽象工廠的一個(gè)實(shí)現(xiàn)蛀骇,負(fù)責(zé)實(shí)例化產(chǎn)品對(duì)象
public class Banana implements Fruit{
/*
* 采集
*/
public void get(){
System.out.println("采集香蕉");
}
}
//栗子工廠 具體工廠類是抽象工廠的一個(gè)實(shí)現(xiàn),負(fù)責(zé)實(shí)例化產(chǎn)品對(duì)象
public class PearFactory implements FruitFactory {
public Fruit getFruit() {
return new Pear();
}
}
//再寫抽象角色(水果接口) 工廠方法模式所創(chuàng)建的所有對(duì)象的父類读拆,它負(fù)責(zé)描述所有實(shí)例所共有的公共接口
public interface Fruit {
public void get();
}
//再寫具體產(chǎn)品角色 (工廠方法模式所創(chuàng)建的具體實(shí)例對(duì)象)
//蘋果類
public class Apple implements Fruit{
/*
* 采集
*/
public void get(){
System.out.println("采集蘋果");
}
}
//香蕉類
public class Banana implements Fruit{
/*
* 采集
*/
public void get(){
System.out.println("采集香蕉");
}
}
//栗子類
public class Pear implements Fruit {
public void get() {
System.out.println("采集梨子");
}
}
//主程序(客戶端)
public class MainClass {
public static void main(String[] args) {
//獲得AppleFactory
FruitFactory ff = new AppleFactory();
//通過(guò)AppleFactory來(lái)獲得Apple實(shí)例對(duì)象
Fruit apple = ff.getFruit();
apple.get();
//獲得BananaFactory
FruitFactory ff2 = new BananaFactory();
Fruit banana = ff2.getFruit();
banana.get();
//獲得PearFactory
FruitFactory ff3 = new PearFactory();
Fruit pear = ff3.getFruit();
pear.get();
}
}
運(yùn)行結(jié)果:
采集蘋果
采集香蕉
采集梨子
工廠方法模式和簡(jiǎn)單工廠模式比較
1.工廠方法模式與簡(jiǎn)單工廠模式在結(jié)構(gòu)上的不同不是很明顯擅憔。<font color=red>工廠方法類的核心是一個(gè)抽象工廠類</font>,<font color=blue>而簡(jiǎn)單工廠模式把核心放在一個(gè)具體類上</font>檐晕。
2.工廠方法模式之所以有一個(gè)別名叫多態(tài)性工廠模式是因?yàn)榫唧w工廠類都有共同的接口暑诸,或者有共同的抽象父類。<font color=red>當(dāng)系統(tǒng)擴(kuò)展需要添加新的產(chǎn)品對(duì)象時(shí)棉姐,僅僅需要添加一個(gè)具體對(duì)象以及一個(gè)具體工廠對(duì)象屠列,原有工廠對(duì)象不需要進(jìn)行任何修改,也不需要修改客戶端</font>伞矩,很好的符合了“開放-封閉”原則笛洛。而簡(jiǎn)單工廠模式在添加新產(chǎn)品對(duì)象后不得不修改工廠方法,擴(kuò)展性不好乃坤。
3.工廠方法模式退化后可以演變成簡(jiǎn)單工廠模式苛让。
抽象工廠模式
抽象工廠模式是所有形態(tài)的工廠模式中最為抽象和最其一般性的,<font color=red>抽象工廠模式可以向客戶端提供一個(gè)接口湿诊,使得客戶端在不必指定產(chǎn)品的具體類型的情況下狱杰,能夠創(chuàng)建多個(gè)產(chǎn)品族的產(chǎn)品對(duì)象</font>。
模式中包含的角色及其職責(zé)
1.抽象工廠(Creator)角色:抽象工廠模式的核心厅须,<font color=red>包含對(duì)多個(gè)產(chǎn)品結(jié)構(gòu)的聲明</font>仿畸,任何工廠類都必須實(shí)現(xiàn)這個(gè)接口。
2.具體工廠( Concrete Creator)角色:具體工廠類是抽象工廠的一個(gè)實(shí)現(xiàn),<font color=red>負(fù)責(zé)實(shí)例化某個(gè)產(chǎn)品族中的產(chǎn)品對(duì)象</font>错沽。
3.抽象(Product)角色:抽象模式所創(chuàng)建的所有對(duì)象的父類簿晓,它負(fù)責(zé)描述所有實(shí)例所共有的公共接口。
4.具體產(chǎn)品(Concrete Product)角色:抽象模式所創(chuàng)建的具體實(shí)例對(duì)象
舉個(gè)栗子
//先寫抽象工廠角色
public interface FruitFactory {
//實(shí)例化Apple
public Fruit getApple();
//實(shí)例化Banana
public Fruit getBanana();
}
//再寫具體工廠角色(和工廠方法模式不同的是:這次的具體工廠角色分不同層級(jí))即不僅僅只是蘋果香蕉的區(qū)別千埃,還有南憔儿、北、溫室之分
public class NorthFruitFactory implements FruitFactory {
public Fruit getApple() {
return new NorthApple();
}
public Fruit getBanana() {
return new NorthBanana();
}
}
public class SouthFruitFactory implements FruitFactory {
public Fruit getApple() {
return new SouthApple();
}
public Fruit getBanana() {
return new SouthBanana();
}
}
public class WenshiFruitFactory implements FruitFactory {
public Fruit getApple() {
return new WenshiApple();
}
public Fruit getBanana() {
return new WenshiBanana();
}
}
//再寫抽象角色
public interface Fruit {
/*
* 采集
*/
public void get();
}
//具體角色
public class NorthApple extends Apple {
public void get() {
System.out.println("采集北方蘋果");
}
}
public class NorthBanana extends Banana {
public void get() {
System.out.println("采集北方香蕉");
}
}
public class SouthApple extends Apple {
public void get() {
System.out.println("采集南方蘋果");
}
}
public class SouthBanana extends Banana {
public void get() {
System.out.println("采集南方香蕉");
}
}
public class WenshiApple extends Apple {
public void get() {
System.out.println("采集溫室蘋果");
}
}
public class WenshiBanana extends Banana {
public void get() {
System.out.println("采集溫室香蕉");
}
}
//主類
public class MainClass {
public static void main(String[] args) {
FruitFactory ff = new NorthFruitFactory();
Fruit apple = ff.getApple();
apple.get();
Fruit banana = ff.getBanana();
banana.get();
FruitFactory ff2= new SouthFruitFactory();
Fruit apple2 = ff2.getApple();
apple2.get();
Fruit banana2 = ff2.getBanana();
banana2.get();
FruitFactory ff3 = new WenshiFruitFactory();
Fruit apple3 = ff3.getApple();
apple3.get();
Fruit banana3 = ff3.getBanana();
banana3.get();
}
}
運(yùn)行結(jié)果
采集北方蘋果
采集北方香蕉
采集南方蘋果
采集南方香蕉
采集溫室蘋果
采集溫室香蕉