1、現(xiàn)有一個(gè)水果蔬菜項(xiàng)目嗤军,需要根據(jù)傳參的不同生成不同的水果對(duì)象
2叙赚、以面向?qū)ο蟮脑瓌t設(shè)計(jì)這個(gè)項(xiàng)目
? ? 1)抽象出一個(gè)接口Fruit
? ??public interface Fruit {
????????void get();
????}
? ? 2) 創(chuàng)建接口實(shí)現(xiàn)類Apple震叮、Banana
? ? Banana:
public class Banana implements Fruit {
@Override
? ? public void get() {
System.out.println("This is Banana");
? ? }
}
????Apple:
public class Appleimplements Fruit {
@Override
? ? public void get() {
????????System.out.println("This is Apple");
? ? }
}
????3)創(chuàng)建一個(gè)蔬菜工廠,根據(jù)參數(shù)不同創(chuàng)建不同的水果對(duì)象
public class FruitFactory {
public static Fruit createFruit(String type)throws IllegalAccessException, InstantiationException {
????if(type.equals("apple")){
????????return Apple.class.newInstance();
? ? ? ? }else if(type.equals("banana")){
????????return Banana.class.newInstance();
? ? ? ? }
????????return null;
? ? }
}
? ??4)運(yùn)行
????傳入不同的參數(shù)哲嘲,獲取不同的對(duì)象
public static void main(String[] args)throws InstantiationException, IllegalAccessException {
Fruit apple = FruitFactory.createFruit("apple");
? ? Fruit banana = FruitFactory.createFruit("banana");
? ? apple.get();
? ? banana.get();
}
結(jié)果:
This is Apple
This is Banana
這是典型的簡(jiǎn)單工廠模式眠副,但是這種方式有問題囱怕,若需要新增一個(gè)水果類型光涂,需要修改FruitFactory方法新增個(gè)else if,另外還需新增個(gè)水果類。這就違反了設(shè)計(jì)模式的開放-封閉原則齐佳。接下來我會(huì)采用工廠模式改造這個(gè)項(xiàng)目
3炼吴、利用工廠模式改造項(xiàng)目
? ? 1)在原來的基礎(chǔ)上改造FruitFactory,把FruitFactory抽象成一個(gè)接口
public interface FruitFactory {? ??
????Fruit createFruit();
}
? ? 2)生成一個(gè)抽象工廠的實(shí)現(xiàn)類AppleFactory,里面創(chuàng)建一個(gè)Apple對(duì)象
public class AppleFactroyimplements FruitFactory {
@Override
? ? public FruitcreateFruit() {
????????return new Apple();
? ? }
}
? ? 3)運(yùn)行
public static void main(String[] args) {
FruitFactory appleFactory =new AppleFactroy();
? ? FruitFactory bananaFactory =new BananaFactory();
? ? Fruit apple = appleFactory.createFruit();
? ? Fruit banana = bananaFactory.createFruit();
? ? apple.get();
? ? banana.get();
}
結(jié)果:
This is Apple
This is Banana
利用工廠設(shè)計(jì)模式就解決了之前簡(jiǎn)單工廠模式出現(xiàn)的問題,如果需要新增一個(gè)水果童芹,只需兩步:1假褪、新增水果對(duì)象。2缀遍、新增生成這個(gè)水果對(duì)象的對(duì)應(yīng)的工廠饱须。
4歹苦、工廠模式
? ? 1)定義
? ? ? ?工廠方法模式的意義是定義一個(gè)創(chuàng)建產(chǎn)品對(duì)象的工廠接口殴瘦,將實(shí)際創(chuàng)建工作推遲到子類當(dāng)中蚪腋。核心工廠類不再負(fù)責(zé)產(chǎn)品的創(chuàng)建立帖,這樣核心類成為一個(gè)抽象工廠角色晓勇,僅負(fù)責(zé)具體工廠子類必須實(shí)現(xiàn)的接口,這樣進(jìn)一步抽象化的好處是使得工廠方法模式可以使系統(tǒng)在不修改具體工廠角色的情況下引進(jìn)新的產(chǎn)品描融。
? ? 2)工廠模式結(jié)構(gòu)圖
? ??
? ? 3)工廠模式的角色和職責(zé)
? ? ? ? 1、抽象工廠角色:工廠方法模式的核心,任何工廠類都必須實(shí)現(xiàn)這個(gè)接口谋右。(抽象工廠角色里包含獲取抽象產(chǎn)品角色的方法)(本例中的抽象工廠角色是FruitFactory)
? ? ? ? 2啸蜜、具體工廠角色:具體工廠類是抽象工廠的一個(gè)實(shí)現(xiàn)衬横,負(fù)責(zé)實(shí)例化產(chǎn)品對(duì)象蜂林。(本例中的具體工廠角色是AppleFactory矮锈、BananaFactory)
? ? ? ? 3债朵、抽象產(chǎn)品角色:工廠方法模式所創(chuàng)建的所有對(duì)象的父類序芦,它負(fù)責(zé)描述所有實(shí)例所共有的公共接口。(本例中的抽象產(chǎn)品角色是Fruit)
? ? ? ? 4藏杖、具體產(chǎn)品角色:工廠方法模式創(chuàng)建的具體實(shí)例(本例中的具體產(chǎn)品角色是Apple、Banana)
5亮航、工廠模式出現(xiàn)的問題怠苔。
? ? ????看似工廠模式已經(jīng)很好了锅劝,抽象工廠生成出不同的具體產(chǎn)品工廠玻粪,然后具體產(chǎn)品工廠生產(chǎn)出具體的產(chǎn)品伦仍。但是我們思考這樣一個(gè)問題:如果具體產(chǎn)品還能往下分類,例如上例中的蘋果我要分為南方蘋果、北方蘋果娜谊,這時(shí)上面工廠模式就無法解決這個(gè)問題,無法生產(chǎn)出具體的南方蘋果或北方蘋果。這是有人就會(huì)想,我們新建一個(gè)北方蘋果或南方蘋果類鉴竭,在蘋果工廠的獲取蘋果對(duì)象方法上加個(gè)參數(shù),根據(jù)傳入不同參數(shù)的蘋果獲取不同的對(duì)象,但這樣就又出現(xiàn)問題了,這又違反了設(shè)計(jì)模式的基本原則:開放-封閉原則呻拌。新增一個(gè)溫室蘋果的話又要修改蘋果工廠代碼垃喊。那這個(gè)問題我們需要怎么解決呢?接下來引入抽象工廠設(shè)計(jì)模式解決這個(gè)問題。
6他托、利用抽象工廠模式重構(gòu)這個(gè)項(xiàng)目仆葡。
? ? 1)在原有的Apple赏参、Banana類上,改造封裝成抽象類沿盅,形成一個(gè)產(chǎn)品族(蘋果產(chǎn)品族把篓、香蕉產(chǎn)品族)
? ? ? ? 蘋果產(chǎn)品
????public abstract class Apple implements Fruit {? ?}
? ? ? ? 香蕉產(chǎn)品
public abstract class Banana implements Fruit {}
? ? ?2)修改抽象工廠接口,改成獲取產(chǎn)品族對(duì)象腰涧。
public interface FruitFactory {
/**
? ? *? 獲取蘋果實(shí)例
? ? */
? ? FruitgetApple();
? ? /**
? ? * 獲取香蕉實(shí)例
? ? */
? ? FruitgetBanana();
}
? ? 3)具體工廠實(shí)現(xiàn)類
public class NorthFruitFactory implements FruitFactory{
????@Override
? ? public Fruit getApple() {
????????return new NorthApple();
? ? }
????@Override
? ? public Fruit getBanana() {
????????return new NorthBanana();
? ? }
}
? ? 4)具體產(chǎn)品實(shí)習(xí)類NorthApple韧掩、SouthApple
NorthApple
public class NorthAppleextends Apple {
????@Override
? ? public void get() {
????????System.out.println("This is NorthApple");
? ? }
}
????SouthApple
public class SouthAppleextends Apple {
@Override
? ? public void get() {
????????System.out.println("This is SouthApple");
? ? }
}
?5)運(yùn)行
public static void main(String[] args) {
FruitFactory north =new NorthFruitFactory();
? ? Fruit northApple = north.getApple();
? ? Fruit northBanana = north.getBanana();
? ? northApple.get();
? ? northBanana.get();
}
結(jié)果
This is NorthApple
This is NorthBanana
8、抽象工廠模式
? ? 1)定義
? ?????? 抽象工廠模式是所有形態(tài)的工廠模式中最為抽象和最其一般性的窖铡。抽象工廠模式可以向客戶端提供一個(gè)接口揍很,使得客戶端在不必指定產(chǎn)品的具體類型的情況下,能夠創(chuàng)建多個(gè)產(chǎn)品族的產(chǎn)品對(duì)象万伤。
? ? 2)抽象工廠模式中的角色和職責(zé)
????????1.抽象工廠(Creator)角色(本例中的抽象工廠角色是FruitFactory)
????????????抽象工廠模式的核心窒悔,包含對(duì)多個(gè)產(chǎn)品結(jié)構(gòu)的聲明,任何工廠類都必須實(shí)現(xiàn)這個(gè)接口敌买。
????????2.具體工廠( Concrete? Creator)角色(本例中的具體工廠角色是NorthFactory)
????????????具體工廠類是抽象工廠的一個(gè)實(shí)現(xiàn)简珠,負(fù)責(zé)實(shí)例化某個(gè)產(chǎn)品族中的產(chǎn)品對(duì)象。
????????3.抽象(Product)角色(本例中的抽象角色是Fruit)
????????????抽象模式所創(chuàng)建的所有對(duì)象的父類虹钮,它負(fù)責(zé)描述所有實(shí)例所共有的公共接口聋庵。
????????4.具體產(chǎn)品(Concrete Product)角色(本例中的具體產(chǎn)品角色是SouthApple等)
????????????抽象模式所創(chuàng)建的具體實(shí)例對(duì)象
???????總結(jié):抽象工廠中方法對(duì)應(yīng)產(chǎn)品結(jié)構(gòu),具體工廠對(duì)應(yīng)產(chǎn)品族芙粱。