工厂模式

一、介绍: 

       1、 工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。

       2、 主要解决的问题:主要解决接口选择的问题。
 
       3、 何时使用:我们明确地计划不同条件下创建不同实例时。
 
       4、 优点: 
             (1)一个调用者想创建一个对象,只要知道其名称就可以了。 
             (2)扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。 
             (3)屏蔽产品的具体实现,调用者只关心产品的接口。
 
       5、 缺点:每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,
 
                        同时也增加了系统具体类的依赖。
 
二、实现的方式:
 
       问题一:以冰淇淋为例,不同口味的冰淇淋如何快速的生产出来
 

     1、简单工厂模式:

             
第一步、定义一个冰激凌接口,里边只有一个方法,就是显示是哪种口味:
       public interface IceCream {
         public void taste();
      }
 
第二步、 定义三个类:AppleIceCream、BananaIceCream、OrangeIceCream,并继承上面的接口,实现其中的方法。显示自己独特的口味
 
public class AppleIceCream implements IceCream {
     public void taste(){
         System.out.println("这是苹果口味的冰激凌");
     }
}
 
public class BananaIceCream implements IceCream {
    public void taste() {
         System.out.println("这是香蕉口味的冰激凌");
    }
}
 
public class OrangeIceCream implements IceCream{
    public void taste(){
         System.out.println("这是橘子口味的冰激凌");
    }
}
 
第三步、 定义一个工厂类,用来制作不同口味的冰激凌
 
   public class IceCreamFactory { 
          public static IceCream creamIceCream(String taste){ 
              IceCream iceCream = null; // 这里我们通过switch来判断,具体制作哪一种口味的冰激凌 
                 switch(taste){ 
                   case "Apple": 
                       iceCream = new AppleIceCream(); 
                       break; 
                   case "Orange": 
                       iceCream = new OrangeIceCream(); 
                       break; 
                   case "Banana": 
                       iceCream = new BananaIceCream(); 
                       break; 
                   default: break; 
                } 
         return iceCream; 
    }
}
 
第四步、测试,通过统一的工厂,传入不同参数调用生产冰激凌的方法去生产不同口味的冰激凌
 
   public class Client { 
     public static void main(String[] args) { 
 
            IceCream appleIceCream = IceCreamFactory.creamIceCream("Apple"); 
            appleIceCream.taste();
 
            IceCream bananaIceCream = IceCreamFactory.creamIceCream("Banana"); 
            bananaIceCream.taste(); 
 
            IceCream orangeIceCream = IceCreamFactory.creamIceCream("Orange"); 
            orangeIceCream.taste();
        }
    }
 
问题二:整个机器已经做成了,按钮数目为3也已经固定了,如果想要再添加一种口味,那么就要打开机器内部,往里边添加制作草莓味冰激凌的原料以及制作工艺,还要在机器外部再增加一个按钮。这可麻烦了,毕竟整个机器的布局什么的都固定下来了。
 
2、工厂方法模式
  
          
  
第一步、 和简单工厂模式一样,先定义一个接口。再定义AppleIceCream、BananaIceCream和OrangeIceCream去实现这个接口:
   
第二步、 定义工厂接口
   
           public interface IceCreamFactory {
               public IceCream createIceCream();
             }
 
第三步、 再分别定义AppleIceCreamFactory、BananaIceCreamFactory、OrangeIceCreamFactory,继承刚刚定义的工厂接口:
 
     public class AppleIceCreamFactory implements IceCreamFactory { 
                public IceCream createIceCream() { 
                      return new AppleIceCream(); 
                    } 
              }
 
    public class BananaIceCreamFactory implements IceCreamFactory { 
                public IceCream createIceCream() { 
                   return new BananaIceCream(); 
               } 
             }
 
   public class OrangeIceCreamFactory implements IceCreamFactory{
             public IceCream createIceCream() { 
                    return new OrangeIceCream(); 
             } 
         }
 
第四步、测试
 
    public class Client { 
     public static void main(String[] args) { 
 
        //生产苹果味冰激凌 
        IceCreamFactory appleFactory = new AppleIceCreamFactory(); 
        IceCream appleIceCream = appleFactory.createIceCream(); 
        appleIceCream.taste();
 
        //生产香蕉口味冰激凌 
        IceCreamFactory bananaFactory = new BananaIceCreamFactory(); 
        IceCream bananaIceCream = bananaFactory.createIceCream(); 
        bananaIceCream.taste();
 
        //生产橘子口味冰激凌
        IceCream orangeIceCream = new OrangeIceCreamFactory().createIceCream();
        orangeIceCream.taste();
        }
    }
 
问题三、 不同人的需求是不同的,有的人吃冰激凌是当做饭后甜点,有的人直接把它当饭吃。因此,为了让顾客有多种选择,想要对每种口味冰激凌的量进行分类,分为大份和小份的。比如我们之前生产的是大份的冰激凌,那么要完成生产多种口味小份的冰激凌,如何解决?
 
3、抽象工厂模式
 
 
第一步、 由于要生产不同大小的冰激凌,所以,现在冰激凌的接口有两个,分别是 BigIceCream 和 SmallIceCream:
 
    public interface BigIceCream {
         public void taste();
   }
  public interface SmallIceCream {
         public void taste();
  }
第二步、 定义各个口味的冰激凌,继承刚刚定义的接口,实现其方法:
  
public class BigAppleIceCream implements BigIceCream {
     public void taste() {
         System.out.println("这是苹果味冰激凌(大份)");
    }
  }
public class SmallAppleIceCream implements SmallIceCream {
     public void taste() {
       System.out.println("这是苹果味冰激凌(小份)");
   }
}
后边还有四个类BigBananaIceCream、SmallBananaIceCream、BigOrangeIceCream、SmallOrangeIceCream  省略
第三步、 定义工厂接口,有两个方法,分别生产小份大的和大份的:
   public interface IceCreamFactory {
         public BigIceCream createBigIceCream();
         public SmallIceCream createSmallIceCream();
   }
第四步、 定义三个工厂类继承上边的接口并实现其方法
   public class AppleIceCreamFactory implements IceCreamFactory { 
     
     public BigIceCream createBigIceCream() { 
        return new BigAppleIceCream(); 
     } 
    public SmallIceCream createSmallIceCream() { 
         return new SmallAppleIceCream(); 
      } 
    } 
    public class BananaIceCreamFactory implements IceCreamFactory { 
        public BigIceCream createBigIceCream() { 
          return new BigBananaIceCream(); 
      } 
        public SmallIceCream createSmallIceCream() { 
            return new SmallBananaIceCream(); 、
          } 
    } 
    public class OrangeIceCreamFactory implements IceCreamFactory { 
        public BigIceCream createBigIceCream() { 
            return new BigOrangeIceCream(); 
       } 
        public SmallIceCream createSmallIceCream() { 
            return new SmallOrangeIceCream(); 
       } 
   }
 
第五步、测试:
 
      public class Client { 
     public static void main(String[] args) { 
 
        //生产苹果味冰激凌 
        IceCreamFactory appleIceCreamFactory = new AppleIceCreamFactory(); 
        BigIceCream appleBigIceCream = appleIceCreamFactory.createBigIceCream(); 
        SmallIceCream appleSmallIceCream = appleIceCreamFactory.createSmallIceCream(); 
        appleBigIceCream.taste(); 
        appleSmallIceCream.taste();
 
        //生产香蕉口味冰激凌 
        IceCreamFactory bananaIceCreamFactory = new BananaIceCreamFactory(); 
        BigIceCream bananaBigIceCream = bananaIceCreamFactory.createBigIceCream(); 
        SmallIceCream bananaSmallIceCream = bananaIceCreamFactory.createSmallIceCream(); 
        bananaBigIceCream.taste(); 
        bananaSmallIceCream.taste();
 
        //生产橘子口味冰激凌
        IceCreamFactory orangeIceCreamFactory = new OrangeIceCreamFactory(); 
        BigIceCream orangeBigIceCream = orangeIceCreamFactory.createBigIceCream(); 
        SmallIceCream orangeSmallIceCream = orangeIceCreamFactory.createSmallIceCream(); 
        orangeBigIceCream.taste(); 
        orangeSmallIceCream.taste();
        }
    }
三、总结:
   1、简单工厂模式适用于工厂类需要创建的对象比较少的情况,客户只需要传入具体的参数,就可以忽略工厂的生产细节,去获取想要的对象;
   2、工厂方法模式,主要是针对单一产品结构的情景;
   3、抽象工厂模式则是针对多级产品结构(系列产品)的一种工厂模式。
每种模式都有自己的优点和弊端,没有最好的模式,只有最适合的模式,只要符合实际开发需求就是最好的。
 
 
posted @ 2019-05-31 15:54  #独狼  阅读(238)  评论(0编辑  收藏  举报