【设计模式】 抽象工厂模式

98 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第20天,点击查看活动详情

抽象工厂模式

针对于工厂方法中存在的问题,当有多个产品簇时,工厂类会爆炸性的增长 如下反例所示

  • 反例

 /**
  * 
  */
 ​
 //抽象产品 食物
 interface Food{
     void eat();
 }
 ​
 //具体产品 汉堡包
 class Hamburger implements Food{
     @Override
     public void eat() {
         System.out.println("吃汉堡包!");
     }
 }
 ​
 //具体产品 米线
 class RiceNoodle implements  Food{
 ​
     @Override
     public void eat() {
         System.out.println("吃米线");
     }
 }
 //抽象产品工厂 食物工厂
 interface FoodFactory{
     public Food getFood();
 }
 ​
 //具体产品工厂 汉堡包工厂
 class HamburgerFactory implements FoodFactory{
 ​
     @Override
     public Food getFood() {
         return new Hamburger();
     }
 }
 ​
 //具体产品工厂 米线工厂
 class RiceNoodleFactory implements FoodFactory{
 ​
     @Override
     public Food getFood() {
         return new RiceNoodle();
     }
 }
 ​
 ​
 //抽象产品 饮料
 interface Drink{
     public void drink();
 }
 //具体产品 可乐
 class Cola implements Drink{
 ​
     @Override
     public void drink() {
         System.out.println("可口可乐,你值得拥有!");
     }
 }
 //具体产品 缤纷
 class IcePeak implements Drink{
 ​
     @Override
     public void drink() {
         System.out.println("西安人从小就喝");
     }
 }
 //抽象饮料工厂
 interface DrinkFactory{
     public Drink getDrink();
 }
 //具体饮料工厂 可乐工厂
 class KolaFactory implements DrinkFactory{
 ​
     @Override
     public Drink getDrink() {
         return new Cola();
     }
 }
 //具体饮料工厂 缤纷工厂
 class IcePeakFactory implements DrinkFactory{
 ​
     @Override
     public Drink getDrink() {
         return new IcePeak();
     }
 }
  • 正例

    • 使用抽象工厂模式。
    • 代码
     //抽象产品 食物
     interface Food{
         void eat();
     }
     ​
     //具体产品 汉堡包
     class Hamburger implements Food{
         @Override
         public void eat() {
             System.out.println("吃汉堡包!");
         }
     }
     ​
     //具体产品 米线
     class RiceNoodle implements  Food{
     ​
         @Override
         public void eat() {
             System.out.println("吃米线");
         }
     }
     ​
     //抽象产品 饮料
     interface Drink{
         public void drink();
     }
     //具体产品 可乐
     class Cola implements Drink{
         @Override
         public void drink() {
             System.out.println("可口可乐,你值得拥有!");
         }
     }
     //具体产品 缤纷
     class IcePeak implements Drink{
         @Override
         public void drink() {
             System.out.println("西安人从小就喝");
         }
     }
     //抽象产品工厂 工厂
     interface Factory{
         public Food getFood();
         public Drink getDrink();
     }
     ​
     class KFCFactory implements Factory{
         @Override
         public Food getFood() {
             return new Hamburger();
         }
     ​
         @Override
         public Drink getDrink() {
             return new Cola();
         }
     }
     ​
     class SanQinFactory implements Factory{
         @Override
         public Food getFood() {
             return new RiceNoodle();
         }
     ​
         @Override
         public Drink getDrink() {
             return new IcePeak();
         }
     }
    
    • 分析

      • 优点

        • 仍然有简单工厂,和工厂方法的优点。
        • 扩展产品簇的时候(新增别的Food和Drink),不需要添加过多的工厂类。
      • 缺点

        • 当产品等级(新增SmalllFoold)发生变化,需要修改之前工厂代码 违反了开闭原则

结论

  • 当产品等级比较固定时,建议采用抽象工厂。