Android設計模式--工廠模式 經典麥當勞

文章參考:https://blog.csdn.net/nugongahou110/article/details/50425823

一個非常貼近生活的-- 麥當勞點餐 的例子來告訴你什麼是工廠模式

思維導圖。


其實工廠模式在我們的現實生活中非常常見,下面我舉個生活中的例子,大家應該就能明白工廠模式的用處在哪裏了!

麥當勞大家都吃過吧?我們去點餐的時候,我們可以點一個漢堡,一杯可樂,一個薯條。我們還可以點一杯可樂,一個薯條。點完之後點餐員會問我們一句還要別的嗎?你說不要了! 然後你的這一份餐就點完了,可以給錢了。咦,我們發現這是一個建造者模式(Builder Pattern)啊!

(ps:這確實是突然發現的,之前寫建造者模式那篇文章的時候並沒有想到這個例子)
  • 到現在我們的工廠模式還沒有出現,那就先來鞏固一下建造者模式吧~反正一會兒和工廠模式也不衝突

假設我們只提供三種類型的食物:漢堡、飲料、小吃

漢堡(巨無霸、吉士漢堡、雙層吉士漢堡)

/**
 * 漢堡
 */
public interface IBurgers {
     String makeBurger();
}
public class BigMac implements IBurgers{

     @Override
     public String makeBurger() {
            return "巨無霸";
     }

}
public class CheeseBurger implements IBurgers{

     @Override
     public String makeBurger() {
            return "吉士漢堡包" ;
     }

}
public class DoubleCheeseBurger implements IBurgers{

     @Override
     public String makeBurger() {
            return "雙層吉士漢堡" ;
     }

}

飲料(可樂,牛奶,橙汁)

/**
 * 飲料
 */
public interface IBeverages {
     String makeDrinking();
}
public class Coke implements IBeverages{

     @Override
     public String makeDrinking() {
            return "可樂";
     }

}
public class Milk implements IBeverages{

     @Override
     public String makeDrinking() {
            return "牛奶";
     }

}
public class OrangeJuice implements IBeverages{

     @Override
     public String makeDrinking() {
            return "橙汁";
     }

}

小吃(奶昔、巧克力奶昔、蘋果派)

/**
 * 小吃
 */
public interface ISnacks {
     String makeSnack();
}
public class MilkShack implements ISnacks{

     @Override
     public String makeSnack() {
            return "奶昔";
     }

}
public class ChocolateShack implements ISnacks{

     @Override
     public String makeSnack() {
            return "巧克力奶昔" ;
     }

}
public class ApplePie implements ISnacks{

     @Override
     public String makeSnack() {
            return "蘋果派";
     }

}

好了,食物都準備好了之後,我們還要創建一個訂單類,因爲這些食物都是客戶自選組合的,所以我們的訂單類可以使用建造者設計模式

public class Order {
     private IBurgers mBurger;
     private IBeverages mBeverages;
     private ISnacks mSnack;

     private Order(OrderBuilder builder){
            mBurger = builder. mBurger;
            mBeverages = builder. mBeverages;
            mSnack = builder. mSnack;
     }

// 拼接套餐 漢堡 + 飲料 + 小吃
public String makeOrder(){
           StringBuilder sb = new StringBuilder();
            if ( mBurger!= null) {
                 sb.append( mBurger.makeBurger()).append( " ");
           }
            if ( mBeverages!= null) {
                 sb.append( mBeverages.makeDrinking()).append( " ");
           }
            if ( mSnack!= null) {
                 sb.append( mSnack.makeSnack());
           }
            return sb.toString();
     }

    // 鏈式調用。建造者模式。
     public static class OrderBuilder{
            private IBurgers mBurger;
            private IBeverages mBeverages;
            private ISnacks mSnack;
            public OrderBuilder(){

           }
            public OrderBuilder addBurger(IBurgers burgers){
                 this. mBurger = burgers;
                 return this;
           }
            public OrderBuilder addBeverage(IBeverages beverages){
                 this. mBeverages = beverages;
                 return this;
           }
            public OrderBuilder addSnack(ISnacks snacks){
                 this. mSnack = snacks;
                 return this;
           }
            public Order build(){
                 return new Order( this);
           }
     }
}
  • 1

這篇文章並不是講解建造者模式,如果大家有對建造者模式不懂得可以去看我的另一篇文章Android設計模式之建造者模式(builder pattern)

好了現在我們來了一個顧客,他點了雙層吉士漢堡+可樂+巧克力奶昔

public class McDonald {
     public static void main(String[] args) {     
           Order order = new Order.OrderBuilder()
                                           .addBurger( new DoubleCheeseBurger())
                                           .addBeverage( new Coke())
                                           .addSnack( new ChocolateShake())
                                           .build();
           System. out.println( order.makeOrder());
     }
}

這裏寫圖片描述

這時候又進來一個顧客,他只是走路走累了,只想點一杯可樂

public class McDonald {
     public static void main(String[] args) {
           Order order = new Order.OrderBuilder()
                                           .addBeverage( new Coke())
                                           .build();
           System. out.println( order.makeOrder());
     }
}
  • 這裏寫圖片描述

這時候又進來一個顧客,他也不知道自己到底想吃什麼,我們也有過這種情況吧?不知道吃什麼怎麼辦,那就來一個巨無霸套餐把!

工廠模式出現

我們的工廠模式來了!套餐就是人家給你配好的一份訂單,你要點巨無霸套餐,人家就直接把巨無霸+可樂+蘋果派給你端上來。就不用我們自己去一個一個選了!是不是很方便!現在我們寫一個訂單工廠類

public class OrderFactory {
     //創建一份巨無霸套餐
     public static Order createBigMacCombo(){
            return new  Order.OrderBuilder()
                                .addBurger( new BigMac())
                                .addBeverage( new Coke())
                                .addSnack( new ApplePie())
                                .build();
     }
}
  • 當我們的顧客來了,說要一份巨無霸套餐,我們只需要這樣生成訂單
public class McDonald {
     public static void main(String[] args) {
           Order order = OrderFactory. createBigMacCombo();
           System. out.println( order.makeOrder());
     }
}
  • 這裏寫圖片描述

使用工廠模式,訂單生成的操作交給我們訂單工廠去做,我們的顧客不用自己去配食物,點餐員只需要一鍵生成一份巨無霸套餐就可以了!

我們也可以多添加幾份套餐供顧客選擇

public class OrderFactory {
     //創建一份巨無霸套餐(巨無霸+可樂+蘋果派)
     public static Order createBigMacCombo(){
            return new Order.OrderBuilder()
                                .addBurger( new BigMac())
                                .addBeverage( new Coke())
                                .addSnack( new ApplePie())
                                .build();
     }
     //創建一份吉士漢堡套餐(吉士漢堡+牛奶+奶昔)
     public static Order createCheeseBurgerCombo(){
            return new Order.OrderBuilder()
                                .addBurger( new CheeseBurger())
                                .addBeverage( new Milk())
                                .addSnack( new MilkShake())
                                .build();
     }
     //創建一份雙層吉士漢堡套餐(雙層吉士漢堡+橙汁+巧克力奶昔)
     public static Order createDoubleBurgerCombo(){
            return new Order.OrderBuilder()
                                .addBurger( new DoubleCheeseBurger())
                                .addBeverage( new OrangeJuice())
                                .addSnack( new ChocolateShake())
                                .build();
     }
}

Android源碼中工廠模式的體現

我們都是用過線程池對吧,我們創建一個線程池的時候可以這樣創建

ExecutorService es = Executors.newCachedThreadPool();

其實這個Executors就是一個工廠類!他的作用就和我們上個例子中的訂單工廠OrderFactory一樣一樣的,我們可以看一看

public class Executors {

    public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }


    public static ExecutorService newWorkStealingPool(int parallelism) {
        return new ForkJoinPool
            (parallelism,
             ForkJoinPool.defaultForkJoinWorkerThreadFactory,
             null, true);
    }


    public static ExecutorService newWorkStealingPool() {
        return new ForkJoinPool
            (Runtime.getRuntime().availableProcessors(),
             ForkJoinPool.defaultForkJoinWorkerThreadFactory,
             null, true);
    }


    public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>(),
                                      threadFactory);
    }


    public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }
 //.....還有很多個
 //這其中每一個方法就是一個套餐!

我們看到其中每一個方法中都是new了一個ThreadPoolExecutor,這纔是真正的線程池,它裏面有很多個參數我們可以進行配置,但是有時候我們根本不用自己去配置,直接到Executors工廠類中選擇一種我們需要的套餐就可以了!省去了複雜的配置過程!這就是Android系統中的工廠模式的體現。和我們的麥當勞是一個意思!

總結

所以工廠模式並不是簡簡單單的在我們new一個對象外邊再包一層工廠類這麼簡單,他的存在是有他存在的道理的,如果我們只是簡簡單單new個對象,何必還用工廠模式這麼麻煩呢,直接new不就成了嗎。通過麥當勞和線程池這個例子,我想大家對於工廠模式的存在意義都心中有數了吧!


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章