精华内容
参与话题
问答
  • java工厂模式三种详解(部分转载)

    万次阅读 多人点赞 2018-05-11 09:04:37
    工厂方法模式(Factory Method) 工厂方法模式分为三种: 1、普通工厂模式,就是建立一个工厂类,对实现了同一接口的一些类进行实例的创建。首先看下关系图: 举例如下:(我们举一个发送邮件和短信的例子) ...

    本文转载截取,原文内容更丰富。想详细了解的小伙伴可以去原创作者:

    https://blog.csdn.net/zhangerqing/article/details/8194653

    工厂方法模式(Factory Method)

    工厂方法模式分为三种:

    1、普通工厂模式,就是建立一个工厂类,对实现了同一接口的一些类进行实例的创建。首先看下关系图:

    举例如下:(我们举一个发送邮件和短信的例子)

    首先,创建二者的共同接口:

    1. public interface Sender {  
    2.     public void Send();  
    3. }  

    其次,创建实现类:

    1. public class MailSender implements Sender {  
    2.     @Override  
    3.     public void Send() {  
    4.         System.out.println("this is mailsender!");  
    5.     }  
    6. }  
    1. public class SmsSender implements Sender {  
    2.   
    3.     @Override  
    4.     public void Send() {  
    5.         System.out.println("this is sms sender!");  
    6.     }  
    7. }  

    最后,建工厂类:

    1. public class SendFactory {  
    2.   
    3.     public Sender produce(String type) {  
    4.         if ("mail".equals(type)) {  
    5.             return new MailSender();  
    6.         } else if ("sms".equals(type)) {  
    7.             return new SmsSender();  
    8.         } else {  
    9.             System.out.println("请输入正确的类型!");  
    10.             return null;  
    11.         }  
    12.     }  
    13. }  

    我们来测试下:

    1. public class FactoryTest {  
    2.   
    3.     public static void main(String[] args) {  
    4.         SendFactory factory = new SendFactory();  
    5.         Sender sender = factory.produce("sms");  
    6.         sender.Send();  
    7.     }  
    8. }  

    输出:this is sms sender!

    2、多个工厂方法模式,是对普通工厂方法模式的改进,在普通工厂方法模式中,如果传递的字符串出错,则不能正确创建对象,而多个工厂方法模式是提供多个工厂方法,分别创建对象。关系图:

    将上面的代码做下修改,改动下SendFactory类就行,如下:

    public class SendFactory {  
       public Sender produceMail(){  
    1.         return new MailSender();  
    2.     }  
    3.       
    4.     public Sender produceSms(){  
    5.         return new SmsSender();  
    6.     }  
    7. }  

    测试类如下:

    1. public class FactoryTest {  
    2.   
    3.     public static void main(String[] args) {  
    4.         SendFactory factory = new SendFactory();  
    5.         Sender sender = factory.produceMail();  
    6.         sender.Send();  
    7.     }  
    8. }  

    输出:this is mailsender!

    3、静态工厂方法模式,将上面的多个工厂方法模式里的方法置为静态的,不需要创建实例,直接调用即可。

    1. public class SendFactory {  
    2.       
    3.     public static Sender produceMail(){  
    4.         return new MailSender();  
    5.     }  
    6.       
    7.     public static Sender produceSms(){  
    8.         return new SmsSender();  
    9.     }  
    10. }  
    1. public class FactoryTest {  
    2.   
    3.     public static void main(String[] args) {      
    4.         Sender sender = SendFactory.produceMail();  
    5.         sender.Send();  
    6.     }  
    7. }  

    输出:this is mailsender!

    总体来说,工厂模式适合:凡是出现了大量的产品需要创建,并且具有共同的接口时,可以通过工厂方法模式进行创建。在以上的三种模式中,第一种如果传入的字符串有误,不能正确创建对象,第三种相对于第二种,不需要实例化工厂类,所以,大多数情况下,我们会选用第三种——静态工厂方法模式。

    4、抽象工厂模式(Abstract Factory)

    工厂方法模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序,必须对工厂类进行修改,这违背了闭包原则,所以,从设计角度考虑,有一定的问题,如何解决?就用到抽象工厂模式,创建多个工厂类,这样一旦需要增加新的功能,直接增加新的工厂类就可以了,不需要修改之前的代码。因为抽象工厂不太好理解,我们先看看图,然后就和代码,就比较容易理解。

    请看例子:

    1. public interface Sender {  
    2.     public void Send();  
    3. }  

    两个实现类:

    1. public class MailSender implements Sender {  
    2.     @Override  
    3.     public void Send() {  
    4.         System.out.println("this is mailsender!");  
    5.     }  
    6. }  
    1. public class SmsSender implements Sender {  
    2.   
    3.     @Override  
    4.     public void Send() {  
    5.         System.out.println("this is sms sender!");  
    6.     }  
    7. }  

    两个工厂类:

    1. public class SendMailFactory implements Provider {  
    2.       
    3.     @Override  
    4.     public Sender produce(){  
    5.         return new MailSender();  
    6.     }  
    7. }  
    1. public class SendSmsFactory implements Provider{  
    2.   
    3.     @Override  
    4.     public Sender produce() {  
    5.         return new SmsSender();  
    6.     }  
    7. }  

    在提供一个接口:

    1. public interface Provider {  
    2.     public Sender produce();  
    3. }  

    测试类:

    1. public class Test {  
    2.   
    3.     public static void main(String[] args) {  
    4.         Provider provider = new SendMailFactory();  
    5.         Sender sender = provider.produce();  
    6.         sender.Send();  
    7.     }  
    8. }  

    其实这个模式的好处就是,如果你现在想增加一个功能:发及时信息,则只需做一个实现类,实现Sender接口,同时做一个工厂类,实现Provider接口,就OK了,无需去改动现成的代码。这样做,拓展性较好!

    展开全文
  • 设计模式(一)工厂模式Factory(创建型)

    万次阅读 多人点赞 2012-04-25 21:29:42
    设计模式一 工厂模式Factory  在面向对象编程中, 最通常的方法是一个new操作符产生一个对象实例,new操作符就是用来构造对象实例的。但是在一些情况下, new操作符直接生成对象会带来一些问题。举例来说, 许多类型...
    
    
    
    

    设计模式一 工厂模式Factory

             在面向对象编程中, 最通常的方法是一个new操作符产生一个对象实例,new操作符就是用来构造对象实例的。但是在一些情况下, new操作符直接生成对象会带来一些问题。举例来说, 许多类型对象的创造需要一系列的步骤: 你可能需要计算或取得对象的初始设置; 选择生成哪个子对象实例; 或在生成你需要的对象之前必须先生成一些辅助功能的对象。 在这些情况,新对象的建立就是一个 “过程”,不仅是一个操作,像一部大机器中的一个齿轮传动。

    模式的问题:你如何能轻松方便地构造对象实例,而不必关心构造对象实例的细节和复杂过程呢?

    解决方案建立一个工厂来创建对象

    实现:

    一、引言
        1)还没有工厂时代:假如还没有工业革命,如果一个客户要一款宝马车,一般的做法是客户去创建一款宝马车,然后拿来用。
        2)简单工厂模式:后来出现工业革命。用户不用去创建宝马车。因为客户有一个工厂来帮他创建宝马.想要什么车,这个工厂就可以建。比如想要320i系列车。工厂就创建这个系列的车。即工厂可以创建产品。
        3)工厂方法模式时代:为了满足客户,宝马车系列越来越多,如320i,523i,30li等系列一个工厂无法创建所有的宝马系列。于是由单独分出来多个具体的工厂。每个具体工厂创建一种系列。即具体工厂类只能创建一个具体产品。但是宝马工厂还是个抽象。你需要指定某个具体的工厂才能生产车出来。
        4)抽象工厂模式时代:随着客户的要求越来越高,宝马车必须配置空调。而且这空调必须对应给系列车才能使用。于是这个工厂开始生产宝马车和需要的空调。
             最终是客户只要对宝马的销售员说:我要523i空调车,销售员就直接给他523i空调车了。而不用自己去创建523i空调车宝马车.
       (我只是举个例子,说到宝马配置空调完全是为了举例,甚至有点扯,哪有车和空调必须对应才能使用啊)
         这就是工厂模式。
    二、分类 
            工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的。 
    工厂模式可以分为三类: 
    1)简单工厂模式(Simple Factory) 
    2)工厂方法模式(Factory Method) 
    3)抽象工厂模式(Abstract Factory) 
             这三种模式从上到下逐步抽象,并且更具一般性。 
            GOF在《设计模式》一书中将工厂模式分为两类:工厂方法模式(Factory Method)与抽象工厂模式(Abstract Factory)。将简单工厂模式(Simple Factory)看为工厂方法模式的一种特例,两者归为一类。 
    三、区别 
    工厂方法模式:
    一个抽象产品类,可以派生出多个具体产品类。   
    一个抽象工厂类,可以派生出多个具体工厂类。   
    每个具体工厂类只能创建一个具体产品类的实例。
    抽象工厂模式:
    多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。   
    一个抽象工厂类,可以派生出多个具体工厂类。   
    每个具体工厂类可以创建多个具体产品类的实例。   
    区别:
    工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。   
    工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。

    两者皆可。 


    四、简单工厂模式 
    建立一个工厂(一个函数或一个类方法)来制造新的对象。
    分布说明引子:从无到有。客户自己创建宝马车,然后拿来用。
     


    <?php
    /**
     * 车子系列
     *
     */
    Class BWM320{
    function __construct($pa) {
    
    }
    }
    Class BMW523{
       function __construc($pb){
    
    }
    }
    
    /**
     * 
     * 客户自己创建宝马车
     */
    class Customer {
    
       function createBMW320(){
           return new BWM320();
       }
    
       function createBMW523(){
           return new BMW523();
       }
    } 


           客户需要知道怎么去创建一款车,客户和车就紧密耦合在一起了.为了降低耦合,就出现了工厂类,把创建宝马的操作细节都放到了工厂里面去,客户直接使用工厂的创建工厂方法,传入想要的宝马车型号就行了,而不必去知道创建的细节.这就是工业革命了:简单工厂模式

    即我们建立一个工厂类方法来制造新的对象。如图:



    产品类:

    <?php
    /**
     * 车子系列
     *
     */
    abstract Class BWM{
        function __construct($pa) {
    
        }
    }
    Class BWM320 extends BWM{
        function __construct($pa) {
    
        }
    }
    Class BMW523 extends BWM{
       function __construc($pb){
    
       }
    }
    
    
    

     工厂类:

    /**
     * 
     * 工厂创建车
     */
    class Factory {
    
    
        static function  createBMW($type){
            switch ($type) {
              case 320:
                 return new BWM320();
              case 523:
                 return new BMW523();
            //....
       }
    }
    

    客户类:

    /**
     * 
     * 客户通过工厂获取车
     */
    class Customer {
        private $BMW;
        function getBMW($type){
            $this¬-> BMW =  Factory::createBMW($type);
        }
    }
    
    


          简单工厂模式又称静态工厂方法模式。重命名上就可以看出这个模式一定很简单。它存在的目的很简单:定义一个用于创建对象的接口。 
          先来看看它的组成: 
             1) 工厂类角色:这是本模式的核心,含有一定的商业逻辑和判断逻辑。
             2) 抽象产品角色:它一般是具体产品继承的父类或者实现的接口。         
             3) 具体产品角色:工厂类所创建的对象就是此角色的实例。在java中由一个具体类实现。 
            
            下面我们从开闭原则(对扩展开放;对修改封闭)上来分析下简单工厂模式。当客户不再满足现有的车型号的时候,想要一种速度快的新型车,只要这种车符合抽象产品制定的合同,那么只要通知工厂类知道就可以被客户使用了。所以对产品部分来说,它是符合开闭原则的;但是工厂部分好像不太理想,因为每增加一种新型车,都要在工厂类中增加相应的创建业务逻辑(createBMW($type)方法需要新增case),这显然是违背开闭原则的。可想而知对于新产品的加入,工厂类是很被动的。对于这样的工厂类,我们称它为全能类 或者上帝类。 
            我们举的例子是最简单的情况,而在实际应用中,很可能产品是一个多层次的树状结构。由于简单工厂模式中只有一个工厂类来对应这些产品,所以这可能会把我们的上帝累坏了,也累坏了我们这些程序员:( 
            于是工厂方法模式作为救世主出现了。 工厂类定义成了接口,而每新增的车种类型,就增加该车种类型对应工厂类的实现,这样工厂的设计就可以扩展了,而不必去修改原来的代码。
    五、工厂方法模式 
            工厂方法模式去掉了简单工厂模式中工厂方法的静态属性,使得它可以被子类继承。这样在简单工厂模式里集中在工厂方法上的压力可以由工厂方法模式里不同的工厂子类来分担。 
    工厂方法模式组成: 
           1)抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。 
           2)具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。 
           3)抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。 
           4)具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。 
           工厂方法模式使用继承自抽象工厂角色的多个子类来代替简单工厂模式中的“上帝类”。正如上面所说,这样便分担了对象承受的压力;而且这样使得结构变得灵活 起来——当有新的产品产生时,只要按照抽象产品角色、抽象工厂角色提供的合同来生成,那么就可以被客户使用,而不必去修改任何已有 的代码。可以看出工厂角色的结构也是符合开闭原则的! 
     


    代码如下: 

    产品类:

    <?php
    /**
     * 车子系列
     *
     */
    abstract Class BWM{
    function __construct($pa) {
    
    }
    }
    Class BWM320 extends BWM{
    function __construct($pa) {
    
    }
    }
    Class BMW523 extends BWM{
       function __construc($pb){
    
    }
    }
    
    


    创建工厂类:

    /**
     * 创建工厂的接口
     *
     */
    interface FactoryBMW { 
           function createBMW(); 
    } 
    
    
    /**
     * 
     * 创建BWM320车
     */
    class FactoryBWM320 implements FactoryBMW {
       function  createBMW($type){
          return new BWM320();
       }
    
    }
    
    
    /**
     * 
     * 创建BWM523车
     */
    class FactoryBWM523 implements FactoryBMW {
       function  createBMW($type){
          return new BMW523();
       }
    }
    
    


    客户类:

    /**
     * 
     * 客户得到车
     */
    class Customer {
       private $BMW;
       function  getBMW($type){
          switch ($type) {
            case 320:
               $BWM320 = new FactoryBWM320();
               return $BWM320->createBMW();
            case 523:
               $BWM523 = new FactoryBWM523();
               return $BWM320->createBMW();
                //....
          }
    
      }
    }
    
    


           可以看出工厂方法的加入,使得对象的数量成倍增长。当产品种类非常多时,会出现大量的与之对应的工厂对象,这不是我们所希望的。因为如果不能避免这种情 况,可以考虑使用简单工厂模式与工厂方法模式相结合的方式来减少工厂类:即对于产品树上类似的种类(一般是树的叶子中互为兄弟的)使用简单工厂模式来实 现。

    工厂方法小结:
            工厂方法模式仿佛已经很完美的对对象的创建进行了包装,使得客户程序中仅仅处理抽象产品角色提供的接口。那我们是否一定要在代码中遍布工厂呢?大可不必。也许在下面情况下你可以考虑使用工厂方法模式: 
         1)当客户程序不需要知道要使用对象的创建过程。 
         2)客户程序使用的对象存在变动的可能,或者根本就不知道使用哪一个具体的对象。


           简单工厂模式与工厂方法模式真正的避免了代码的改动了?没有。在简单工厂模式中,新产品的加入要修改工厂角色中的判断语句;而在工厂方法模式中,要么将判 断逻辑留在抽象工厂角色中,要么在客户程序中将具体工厂角色写死(就象上面的例子一样)。而且产品对象创建条件的改变必然会引起工厂角色的修改。
           面对这种情况,我们可以使用反射机制:

     class Customer {
         private $BMW;
         function  getBMW($type){
             $class = new ReflectionClass('FactoryBWM' .$type );//建立 'FactoryBWM'这个类的反射类  
              $instance  = $class->newInstanceArgs();//相当于实例化'FactoryBWM' .$type类  
              return $instance->createBMW();
            //或者直接 
             /**
             * $instance = new 'FactoryBWM' .$type();
             * return $instance->createBMW();
             */
        }
    }
    

     

    六、抽象工厂模式 
           随着客户的要求越来越高,宝马车需要配置空调。于是这个工厂开始生产宝马车和配置需要的空调。这时候工厂有二个系列的产品:宝马车和空调.宝马车必须使用对应的空调才能使用.这时候分别使用一个车工厂和一个空调工厂都不能满足我们的需求,我们必须确认车跟空调的对应关系。因此把车工厂跟空调工厂联系在一起。因此出现了抽象工厂模式。
         可以说,抽象工厂模式和工厂方法模式的区别就在于需要创建对象的复杂程度上。而且抽象工厂模式是三个里面最为抽象、最具一般性的。
    抽象工厂模式的用意为:给客户端提供一个接口,可以创建多个产品族中的产品对象 ,而且使用抽象工厂模式还要满足一下条件:
         1)系统中有多个产品族,而系统一次只可能消费其中一族产品。
         2)同属于同一个产品族的产品以其使用。
    抽象工厂模式的各个角色(和工厂方法一样):
         1)抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。 
         2)具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。
         3)抽象产品角色:它是具体产品继承的父类或者是实现的接口。
         4)具体产品角色:具体工厂角色所创建的对象就是此角色的实例。

     

    其结构:


     
    我们的例子:
     

    代码:

    产品类:

    <?php
    /**
     * 车子系列以及型号
     *
     */
    abstract class  BWM{
    }
    
    class BWM523 extends  BWM {
    }
    class BWM320 extends  BWM {
    
    
    }
    /**
     * 空调
     *
     */
    abstract class aircondition{
    }
    class airconditionBWM320  extends aircondition {
    
    }
    class airconditionBWM52 extends aircondition {
    
    }
    
    
    创建工厂类:

    /**
     * 创建工厂的接口
     *
     */
    interface FactoryBMW { 
         function createBMW(); 
         function createAirC(); 
    } 
    
    
    /**
     * 
     * 创建BWM320车
     */
    class FactoryBWM320 implements FactoryBMW {
        function  createBMW(){
        return new BWM320();
    }
    function  createAirC(){ //空调
        return new airconditionBWM320();
    }
    }
    
    
    /**
     * 
     * 创建BWM523车
     */
    class FactoryBWM523 implements FactoryBMW {
        function  createBMW(){
        return new BWM523();
    }
    function  createAirC(){
        return new airconditionBWM523();
    }
    }
    
    
    客户:

    /**
     * 
     * 客户得到车
     */
    class Customer {
       private $BMW;
       private $airC;
       function  getBMW($type){
           $class = new ReflectionClass('FactoryBWM' .$type );//建立 Person这个类的反射类  
            $instance  = $class->newInstanceArgs();//相当于实例化Person 类  
            $this->BMW =  $instance->createBMW();
           $this->airC =  $instance->createAirC();
       }
    }
    
    


    展开全文
  • 在面向对象编程中, 最通常的方法是一个new操作符产生一个对象实例,new操作符就是用来构造对象实例的。但是在一些情况下, new操作符直接生成对象会带来一些问题。举例来说, 许多类型对象的创造需要一系列的步骤: 你...

     在面向对象编程中, 最通常的方法是一个new操作符产生一个对象实例,new操作符就是用来构造对象实例的。但是在一些情况下, new操作符直接生成对象会带来一些问题。举例来说, 许多类型对象的创造需要一系列的步骤: 你可能需要计算或取得对象的初始设置; 选择生成哪个子对象实例; 或在生成你需要的对象之前必须先生成一些辅助功能的对象。 在这些情况,新对象的建立就是一个 “过程”,不仅是一个操作,像一部大机器中的一个齿轮传动。

     

    模式的问题:你如何能轻松方便地构造对象实例,而不必关心构造对象实例的细节和复杂过程呢?

    解决方案:建立一个工厂来创建对象

    实现:

    一、引言
        1)还没有工厂时代:假如还没有工业革命,如果一个客户要一款宝马车,一般的做法是客户去创建一款宝马车,然后拿来用。
        2)简单工厂模式:后来出现工业革命。用户不用去创建宝马车。因为客户有一个工厂来帮他创建宝马.想要什么车,这个工厂就可以建。比如想要320i系列车。工厂就创建这个系列的车。即工厂可以创建产品。
        3)工厂方法模式时代:为了满足客户,宝马车系列越来越多,如320i,523i,30li等系列一个工厂无法创建所有的宝马系列。于是由单独分出来多个具体的工厂。每个具体工厂创建一种系列。即具体工厂类只能创建一个具体产品。但是宝马工厂还是个抽象。你需要指定某个具体的工厂才能生产车出来。

       4)抽象工厂模式时代:随着客户的要求越来越高,宝马车必须配置空调。于是这个工厂开始生产宝马车和需要的空调。

       最终是客户只要对宝马的销售员说:我要523i空调车,销售员就直接给他523i空调车了。而不用自己去创建523i空调车宝马车.

       这就是工厂模式。

    二、分类 
            工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的。 
    工厂模式可以分为三类: 

    1)简单工厂模式(Simple Factory) 
    2)工厂方法模式(Factory Method) 
    3)抽象工厂模式(Abstract Factory) 

     这三种模式从上到下逐步抽象,并且更具一般性。 
            GOF在《设计模式》一书中将工厂模式分为两类:工厂方法模式(Factory Method)与抽象工厂模式(Abstract Factory)。

            将简单工厂模式(Simple Factory)看为工厂方法模式的一种特例,两者归为一类。 

    三、区别 
    工厂方法模式:
    一个抽象产品类,可以派生出多个具体产品类。   
    一个抽象工厂类,可以派生出多个具体工厂类。   
    每个具体工厂类只能创建一个具体产品类的实例。
    抽象工厂模式:
    多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。   
    一个抽象工厂类,可以派生出多个具体工厂类。   
    每个具体工厂类可以创建多个具体产品类的实例。   
    区别:
    工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。   
    工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。
    两者皆可。 

     四、简单工厂模式 
    建立一个工厂(一个函数或一个类方法)来制造新的对象。
    分布说明引子:从无到有。客户自己创建宝马车,然后拿来用。

     

     

    public class BMW320 {
    	public BMW320(){
    		System.out.println("制造-->BMW320");
    	}
    }
    
    public class BMW523 {
    	public BMW523(){
    		System.out.println("制造-->BMW523");
    	}
    }
    
    public class Customer {
    	public static void main(String[] args) {
    		BMW320 bmw320 = new BMW320();
    		BMW523 bmw523 = new BMW523();
    	}
    }
    

    客户需要知道怎么去创建一款车,客户和车就紧密耦合在一起了.为了降低耦合,就出现了工厂类,把创建宝马的操作细节都放到了工厂里面去,客户直接使用工厂的创建工厂方法,传入想要的宝马车型号就行了,而不必去知道创建的细节.这就是工业革命了:简单工厂模式

    即我们建立一个工厂类方法来制造新的对象。如图:

    产品类:

    abstract class BMW {
    	public BMW(){
    		
    	}
    }
    
    public class BMW320 extends BMW {
    	public BMW320() {
    		System.out.println("制造-->BMW320");
    	}
    }
    public class BMW523 extends BMW{
    	public BMW523(){
    		System.out.println("制造-->BMW523");
    	}
    }
    

    工厂类:

    public class Factory {
    	public BMW createBMW(int type) {
    		switch (type) {
    		
    		case 320:
    			return new BMW320();
    
    		case 523:
    			return new BMW523();
    
    		default:
    			break;
    		}
    		return null;
    	}
    }


    客户类:

    public class Customer {
    	public static void main(String[] args) {
    		Factory factory = new Factory();
    		BMW bmw320 = factory.createBMW(320);
    		BMW bmw523 = factory.createBMW(523);
    	}
    }
    

       简单工厂模式又称静态工厂方法模式。重命名上就可以看出这个模式一定很简单。它存在的目的很简单:定义一个用于创建对象的接口。 
          先来看看它的组成: 
             1) 工厂类角色:这是本模式的核心,含有一定的商业逻辑和判断逻辑,用来创建产品
             2) 抽象产品角色:它一般是具体产品继承的父类或者实现的接口。         
             3) 具体产品角色:工厂类所创建的对象就是此角色的实例。在java中由一个具体类实现。 
            
            下面我们从开闭原则(对扩展开放;对修改封闭)上来分析下简单工厂模式。当客户不再满足现有的车型号的时候,想要一种速度快的新型车,只要这种车符合抽象产品制定的合同,那么只要通知工厂类知道就可以被客户使用了。所以对产品部分来说,它是符合开闭原则的;但是工厂部分好像不太理想,因为每增加一种新型车,都要在工厂类中增加相应的创建业务逻辑(createBMW(int type)方法需要新增case),这显然是违背开闭原则的。可想而知对于新产品的加入,工厂类是很被动的。对于这样的工厂类,我们称它为全能类或者上帝类。 
            我们举的例子是最简单的情况,而在实际应用中,很可能产品是一个多层次的树状结构。由于简单工厂模式中只有一个工厂类来对应这些产品,所以这可能会把我们的上帝累坏了,也累坏了我们这些程序员。
            于是工厂方法模式作为救世主出现了。 工厂类定义成了接口,而每新增的车种类型,就增加该车种类型对应工厂类的实现,这样工厂的设计就可以扩展了,而不必去修改原来的代码。
    五、工厂方法模式 
            工厂方法模式去掉了简单工厂模式中工厂方法的静态属性,使得它可以被子类继承。这样在简单工厂模式里集中在工厂方法上的压力可以由工厂方法模式里不同的工厂子类来分担。 
    工厂方法模式组成: 
           1)抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。 
           2)具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。 
           3)抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。 
           4)具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。 
           工厂方法模式使用继承自抽象工厂角色的多个子类来代替简单工厂模式中的“上帝类”。正如上面所说,这样便分担了对象承受的压力;而且这样使得结构变得灵活 起来——当有新的产品产生时,只要按照抽象产品角色、抽象工厂角色提供的合同来生成,那么就可以被客户使用,而不必去修改任何已有 的代码。可以看出工厂角色的结构也是符合开闭原则的! 

    代码如下: 

    产品类:

    abstract class BMW {
    	public BMW(){
    		
    	}
    }
    public class BMW320 extends BMW {
    	public BMW320() {
    		System.out.println("制造-->BMW320");
    	}
    }
    public class BMW523 extends BMW{
    	public BMW523(){
    		System.out.println("制造-->BMW523");
    	}
    }


    创建工厂类:

    interface FactoryBMW {
    	BMW createBMW();
    }
    
    public class FactoryBMW320 implements FactoryBMW{
    
    	@Override
    	public BMW320 createBMW() {
    
    		return new BMW320();
    	}
    
    }
    public class FactoryBMW523 implements FactoryBMW {
    	@Override
    	public BMW523 createBMW() {
    
    		return new BMW523();
    	}
    }
    


    客户类:

    public class Customer {
    	public static void main(String[] args) {
    		FactoryBMW320 factoryBMW320 = new FactoryBMW320();
    		BMW320 bmw320 = factoryBMW320.createBMW();
    
    		FactoryBMW523 factoryBMW523 = new FactoryBMW523();
    		BMW523 bmw523 = factoryBMW523.createBMW();
    	}
    }


     工厂方法模式仿佛已经很完美的对对象的创建进行了包装,使得客户程序中仅仅处理抽象产品角色提供的接口,但使得对象的数量成倍增长。当产品种类非常多时,会出现大量的与之对应的工厂对象,这不是我们所希望的。

    参考http://blog.csdn.net/hguisu/article/details/7505909

     

    以上就是简单工厂模式,工厂方法模式,抽象工厂模式在这里

     

    更多设计模式:23种设计模式系列

    作者:jason0539

    博客:http://blog.csdn.net/jason0539(转载请说明出处)

     

    展开全文
  • 工厂模式

    万次阅读 2018-10-30 11:08:37
    工厂模式:建立创建对象的工厂 在面向对象编程中,术语“工厂”表示一个负责创建其他类型对象的类。通常情况下,作为一个工厂的类有一个对象以及与它关联的多个方法。客户端使用某些参数调用此方法之后,工厂会...

    #工厂模式:建立创建对象的工厂

    在面向对象编程中,术语“工厂”表示一个负责创建其他类型对象的类。通常情况下,作为一个工厂的类有一个对象以及与它关联的多个方法。客户端使用某些参数调用此方法之后,工厂会据此创建所需类型的对象,然后将它们返回给客户端。
    工厂具有下列优点:松耦合,即对象的创建可以独立于类的实现;客户端无需了解创建对象的类,但是照样可以使用它来创建对象。它只需要知道需要传递的接口、方法和参数,就能够创建 所需类型的对象了。这简化了客户端的实现;可以轻松地在工厂中添加其他类来创建其他类型的对象,而这无需更改客户端代码。最简单的情况下,客户端只需要传递一个参数就可以了;工厂还可以重用现有对象。但是,如果客户端直接创建对象的化,总是创建一个新对象。

    Factory模式有3种变体:
    (1)简单工厂模式: 允许接口创建对象,但不会暴露对象的创建逻辑。
    (2)工厂方法模式:允许接口创建对象,但使用哪个类来创建对象,则是交由子类决定的。
    (3)抽象工厂模式:抽象工厂是一个能够创建一系列相关的对象而无需指定/公开其具体类的接口。该模式能够提供其他工厂的对象,在其内部创建其他对象。

    ##一、简单工厂模式

    工厂可以帮助开发人员创建不同类型的对象,而不是直接将对象实例化。

    下图是简单工厂的UML图。客户端类使用的是Factory类,该类具有create_type()方法。当客户端使用类型参数调用create_type()方法时,Factory会根据传入的参数,返回Product1或Product2。
    图1
    实现:在下面的代码段中,我们将创建一个名为Animal的抽象产品。Animal是一个抽象的基类(ABCMeta是 Python的特殊元类,用来生成类Abstract),它带有方法do_say()。我们利用Animal接口创建了两种产品(Cat和Dog),并实现了do_say()方法来提供这些动物的相应的叫声。ForestFactory是一个带有make_sound()方法的工厂。根据客户端传递的参数类型,它就可以在运行时创建适当的Animal实例,并输出正确的声音:

    from abc import ABCMeta, abstractmethod
    #抽象类
    class Animal(metaclass = ABCMeta): 
    	@abstractmethod
    	def do_say(self):
    		pass
    class Dog(Animal):		
    	def do_say(self):
    		print('汪汪。。。')
    class Cat(Animal):		
    	def do_say(self):
    		print('喵喵。。。')		
    #工厂类:
    class ForestFactory:
    	def make_sound(self, object_type):		
    		return eval(object_type)().do_say()
    		
    #client code
    if __name__ == '__main__':		
    	ff = ForestFactory()
    	animal = input('Which animal should make sound(Dog or Cat)?')
    	ff.make_sound(animal)
    

    ##二、工厂方法模式

    以下几点可以帮助我们了解工厂方法模式:
    (1)我们定义了一个接口来创建对象,但是工厂本身并不负责创建对象,而是将这以任务交由子类来完成,即子类决定了要实例化哪些类;
    (2)Factory方法的创建是通过继承而不是通过实例化来完成的;
    (3)工厂方法使设计更加具有可定制性。它可以返回相同的实例或子类,而不是某种类型的对象。

    在UML图中,有一个包含factoryMethod()方法的抽象类Creator。factoryMethod()方法负责创建指定类型的对象。ConcreteCreator类提供了一个实现Creator抽象类的factoryMethod()方法,这种方法可以在运行是时修改已创建的对象。ConcreteCreator创建ConcreteProduct,并确保其创建的对象实现了Product类,同时为Product接口中的所有方法提供相应的实现。
    简而言之,Creator接口的factoryMethod()方法和ConcreteCreator类共同决定了要创建Product的哪个子类。因此,工厂方法模式定义了一个接口来创建对象,但具体实例化哪个类则是由它的子类决定的。
    图2

    from abc import ABCMeta, abstractmethod
    
    #抽象Product
    class Section(metaclass = ABCMeta):
    	@abstractmethod
    	def describe(self):		#抽象方法
    		pass
    #ConcreteProduct1		
    class PersonalSection(Section):	
    	def describe(self):
    		print('Personal Section!')
    #ConcreteProduct2		
    class AlbumSection(Section):	
    	def describe(self):
    		print('Album Section!')	
    #ConcreteProduct3		
    class PatentSection(Section):	
    	def describe(self):
    		print('Patent Section!')
    #ConcreteProduct4		
    class PublicationSection(Section):	
    	def describe(self):
    		print('Publication Section!')	
    #抽象类Creator		
    class Profile(metaclass = ABCMeta):		
    	def __init__(self):
    		self.sections = []
    		self.createProfile()
    	@abstractmethod
    	def createProfile(self):
    		pass
    	def getSections(self):
    		return self.sections
    	def addSectons(self, section):
    		self.sections.append(section)
    #ConcreteCreator类
    class linkedin(Profile):		
    	def createProfile(self):
    		self.addSectons(PersonalSection())
    		self.addSectons(PatentSection())
    		self.addSectons(PublicationSection())
    #ConcreteCreator类
    class facebook(Profile):		
    	def createProfile(self):
    		self.addSectons(PersonalSection())
    		self.addSectons(AlbumSection())		
    		
    if __name__ == '__main__':		
    	profile_type = input('Which Profile you\'d like to create?(LinkedIn or FaceBook)')
    	profile = eval(profile_type.lower())()	#实例化类
    	print('Creating Profile...:', type(profile).__name__)
    	print('Profile has sections...:', profile.getSections())
    
    

    工厂方法模式的优点:
    (1)它具有更大的灵活性,使得代码更加通用,因为它不是单纯地实例化某个类。这样,实现哪些类取决于接口(Product),而不是ConcreteCreator。
    (2)它们是松耦合的,因为创建对象的代码与使用它的代码是分开的。客户端完全不需要关心要传递哪些参数以及需要实例化哪些类。由于添加新类更加容易,所以降低了维护成本。

    ##三、抽象工厂模式
    抽象工厂模式的主要目的是提供一个接口来创建一系列相关对象,而无需指定具体的类。工厂方法将创建实例的任务委托给了子类,而抽象工厂方法的目标是创建一系列相关对象。如图3所示,ConcreteFactory1 和 ConcreteFactory2 是通过AbstractFactory接口创建的。此接口具有创建多种产品的相应方法。
    这里写图片描述
    ConcreteFactory1 和 ConcreteFactory2实现了AbstractFactory,并创建实例ConcreteProduct1、ConcreteProduct2、AnotherConcreteProduct1和AnotherConcreteProduct2。
    在这里,ConcreteProduct1和ConcreteProduct2是通过AbstractProduct接口创建的,而AnotherConcreteProduct1和AnotherConcreteProduct2则是通过AnotherAbstractProduct接口创建的。
    实际上,抽象工厂模式不仅确保客户端与对象的创建相互隔离,同时还确保客户端能够使用创建的对象。但是,客户端只能通过接口访问对象。如果要使用一个系列中的多个产品,那么抽象工厂模式能够帮助客户端一次使用来自一个产品/系列的多个对象。
    ###实现抽象工厂模式
    例子:一家披萨店,供应印式和美式披萨饼。为此,我们首先创建一个抽象基类—PizzaFactory(AbstractFactory)。PizzaFactory类有两个抽象方法即createVegPizza()和createNonVegPizza(),它们需要通过ConcreteFactory实现。在这个例子中,我们创建了两个具体的工厂,分别名为IndianPizzaFactory和USPizzaFactory。

    from abc import ABCMeta, abstractmethod
    #AbstractFactory
    class PizzaFactory(metaclass = ABCMeta):
    	@abstractmethod
    	def createVegPizza(self):
    		pass
    	@abstractmethod	
    	def createNonVegPizza(self):
    		pass
    #ConcreteFactory		
    class IndianPizzaFactory(PizzaFactory):		
    	def createVegPizza(self):
    		return DeluxVeggiePizza()
    	def createNonVegPizza(self):
    		return ChickenPizza()	
    #ConcreteFactory		
    class USPizzaFactory(PizzaFactory):		
    	def createVegPizza(self):
    		return MexicanVegPizza()
    	def createNonVegPizza(self):
    		return HamPizza()	
    #进一步定义	AbstractProducts:
    #AbstractProduct
    class VegPizza(metaclass = ABCMeta):
    	@abstractmethod
    	def prepare(self, VegPizza):	#定义自己的方法	
    		pass
    #AnotherAbstractProduct		
    class NonVegPizza(metaclass = ABCMeta):	
    	@abstractmethod
    	def serve(self, VegPizza):		#定义自己的方法
    		pass
    		
    #为每个AbstractProducts定义ConcreteProducts,创建DeluxVeggiePizza和MexicanVegPizza:
    class DeluxVeggiePizza(VegPizza):	#ConcreteProducts1		
    	def prepare(self):
    		print('Prepare:', type(self).__name__)
    #定义AnotherConcreteProduct:		
    class MexicanVegPizza(VegPizza):	#ConcreteProducts2
    	def prepare(self):
    		print('Prepare:', type(self).__name__)
    #定义ChickenPizza和HamPizza,分别代表AnotherConcreteProducts1和AnotherConcreteProducts2:	
    class ChickenPizza(NonVegPizza):	#AnotherConcreteProducts1		
    	def serve(self, VegPizza):
    		print(type(self).__name__, ' is served with Chicken on ', type(VegPizza).__name__)	
    class HamPizza(NonVegPizza):		
    	def serve(self, VegPizza):
    		print(type(self).__name__, ' is served with Ham on ', type(VegPizza).__name__)
    		
    #当最终用户来到PizzaStore并要一份美式非素食披萨的时候,USPizzaFactory负责准备素食,
    #然后在上面加上火腿,马上就变成非素食披萨了:
    class PizzaStore:
    	def __init__(self):
    		pass
    	def makePizzas(self):	
    		for factory in [IndianPizzaFactory(), USPizzaFactory()]:
    			self.factory = factory
    			self.NonVegPizza = self.factory.createNonVegPizza()
    			self.VegPizza = self.factory.createVegPizza()
    			self.VegPizza.prepare()
    			self.NonVegPizza.serve(self.VegPizza)
    			
    if __name__ == '__main__':		
    	pizza = PizzaStore()
    	pizza.makePizzas()
    

    ###工厂方法与抽象工厂方法

    工厂方法 抽象工厂方法
    它向客户端开发了一个创建对象的方法 抽象工厂方法包含一个或多个工厂方法来创建一个系列的相关对象
    它使用继承和子类来决定要创建哪个对象 它使用组合将创建对象的任务委托给其他类
    工厂方法用于创建一个产品 抽象工厂方法用于创建相关产品的系列
    展开全文
  • 工厂三兄弟之抽象工厂模式(二)

    万次阅读 多人点赞 2013-07-13 16:34:27
    2 产品等级结构与产品族 在工厂方法模式中具体工厂负责生产具体的产品,每一个具体工厂对应一种具体产品,工厂方法具有唯一性,一般情况下,一个具体工厂中只有一个或者一组重载的工厂方法。但是有时候我们希望一个...
  • 工厂方法模式

    千次阅读 2019-05-31 20:40:44
  • 简单工厂(静态工厂

    千次阅读 2018-09-07 13:27:19
    简单工厂(静态工厂) 示例 使用典范 简单工厂(静态工厂) 定义:由一个工厂对象决定创建出哪一种产品类的实例 类型:创建型,不属于GOF23种设计模式 适用场景: 工厂类负责创建的对象比较少 客户端...
  • 工厂模式以及应用简单解释

    千次阅读 2018-03-17 13:04:32
    一个jpa引发的血案,项目中应用的jpa比较多,自己看了关于jpa相关的应用,然后打算了解一些源码,但是不太能看懂。想知道为什么在jpa中定义了方法,就能够操作数据库,不定义方法也能操作数据库,资料上说应用的代理...
  • 深入理解工厂模式

    万次阅读 2018-10-24 10:53:34
    一、工厂模式 1.1定义 “Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.” (在基类中...
  • 三大工厂模式的代码实现及总结

    万次阅读 多人点赞 2018-08-05 13:49:04
    简单工厂模式、工厂方法模式、抽象工厂模式,都是属于创建型设计模式。严格上来说,简单工厂模式不属于23设计模式之一,因为它违背了开闭原则。这三种设计模式,名字都包含“工厂”二字,如果没有认真地对它们的...
  • 工厂模式,工厂方法模式,抽象工厂模式 详解

    万次阅读 多人点赞 2017-03-09 10:02:25
    1. 工厂模式 1.1 定义 简单工厂模式是由一个工厂对象根据收到的消息决定要创建哪一个类的对象实例。 1.2 使用场景 工厂类负责创建的对象比较少,客户只需要传入工厂类参数,对于如何创建对象(逻辑)不关心。简单...
  • 《JAVA与模式》之装饰模式

    千次阅读 2016-01-05 12:21:00
    在阎宏博士的《JAVA与模式》一书中开头是这样描述装饰(Decorator)模式的:  装饰模式又名包装(Wrapper)模式。装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。 ...
  • 动态的工厂模式

    千次阅读 2005-04-10 23:01:00
    工厂模式可以说是我们应用得最广泛的设计模式之一。所谓工厂模式,就是不是由客户类来实现类的实例,而是由工厂来实现类的实例。如没有应用工厂模式的客户类Client要实现对接口类Parent和他的实现类Son的使用,必须...
  • 定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类。...工厂方法模式代码 [java]view plaincopy interfaceIProduct{ publicvoidproductMethod(); } c
  • 工厂方法模式、简单工厂模式、抽象工程模式

    千次阅读 多人点赞 2018-04-07 22:11:06
    工厂设计模式是一种创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。 针对的问题:在面向对象编程中,最...
  • 抽象工厂模式:我们现在要对mysql/oracle数据库中的User表进行操作,User表定义如下:public class User { private int uid; private String uname; public int getUid() { return uid; } public void set...
  • 简单工厂模式

    万次阅读 2019-10-27 23:16:23
    简单工厂模式又称为静态工厂方法模式,它属于类创建型模式,在这种模式中,可以根据参数的不同,返回不同类的实例,被创建的实例通常都具有共同的父类或实现了相同的接口。 业务场景 在某糕点定制APP中,需要根据...
  • 3种工厂模式

    千次阅读 2019-05-03 20:49:40
    3种工厂模式 问题描述 简单工厂模式:模拟女娲造人,如果传入参数M,则返回一个Man对象,如果传入参数W,则返回一个Woman对象,实现该场景。...抽象工程模式:电脑配件生产内存、CPU等硬件设备,这些...
  • JAVA设计模式之抽象工厂模式

    万次阅读 多人点赞 2015-04-11 08:26:32
    本文属于23种设计模式系列。 继续前面简单工厂模式工厂方法模式的例子,以汽车配件制造介绍抽象工厂模式
  • 工厂方法模式VS简单工厂模式

    千次阅读 2016-06-10 23:14:46
    转发请注明出处:http://blog.csdn.net/qq_28055429/article/details/51628921One----简单工厂模式:一,基本知识:(1)定义:简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不...
  • 5种创建型模式之:抽象工厂模式

    万次阅读 2017-04-07 23:11:25
    抽象工厂模式工厂方法模式的升级版本,他用来创建一组相关或者相互依赖的对象。他与工厂方法模式的区别就在于,工厂方法模式针对的是一个产品等级结构;而抽象工厂模式则是针对的多个产品等级结构。在编程中,...
  • php 开发模式工厂模式

    千次阅读 2018-05-23 13:35:57
    php [php] view plain copy// 开发模式之工程模式 // 工厂模式: // 由工厂类根据参数来决定创建出哪一种产品类的实例; // 工厂类是指包含了一个专门用来创建其他对象的方法的类。所谓按需分配,传入参数...
  • 工厂方法模式引入工厂等级结构,解决了简单工厂模式工厂类职责过重的问题,但由于工厂方法模式中每个工厂只创建一类具体类的对象,这将会导致系统当中的工厂类过多,这势必会增加系统的开销。此时,我们可以考虑将...
  • PHP 设计模式 简单工厂工厂模式

    千次阅读 2018-01-02 18:37:19
    工厂模式是创建型模式的一种,分为简单工厂模式工厂模式,抽象工厂模式,简单工厂可以称之为工厂模式的一个特例 先用一段简单的代码说明一下,现在假设我们是顾客,需要苹果味饮料和香蕉味饮料 class ...
  • 掌握简单工厂模式工厂方法模式、抽象工厂模式,并进行设计应用。 二、实验内容 (1)、 简单工厂模式使用简单工厂模式模拟女娲(Nvwa)造人(Person),如果传入参数M,则返回一个Man对象,如果传入参数W,则返回一...
  • 设计模式(一) 工厂模式 五种写法总结

    万次阅读 多人点赞 2016-10-12 16:47:11
    http://blog.csdn.net/zxt0601/article/details/52703280本文出自:【张旭童的博客】系列开篇瞎BB设计模式相关的文章学习与总结,一直有意为之,一直又觉得时机不到。一 是怕自己代码经验还不够,学习了也不懂,强行...
  • 三种工厂模式的C++实现

    万次阅读 多人点赞 2014-03-05 11:36:02
    引出工厂模式的设计问题◆ 1.为了提高内聚(Cohesion)和松耦合(Coupling),我们经常会抽象出一些类的公共接口以形成抽象基类或者接口。这样我们可以通过声明一个指向基类的指针来指向实际的子类实现,达到了多态...
  • 工厂方法模式: 通用类图如下: 抽象产品类: 具体产品类 抽象工厂类 具体的工厂类 场景类: 工厂方法模式的优点: 使用场景: 工厂方法模式的扩展: (1)简单工厂模式 (2)多工厂模式 抽象工厂模式.....
  • 工厂模式,是指定义一个创建对象的接口,让实现这个接口的类来决定实例化哪个类。本文对(简单工厂|静态工程工厂方法|多工厂、抽象工厂)进行了区别和详解。
  • Spring IOC与工厂模式

    千次阅读 2020-05-06 14:04:51
    Spring IOC与工厂模式 PS:本文内容较为硬核,需要对java的面向对象、反射、类加载器、泛型、properties、XML等基础知识有较深理解。 (一)简单介绍 在讲Spring IOC之前,有必要先来聊一下工厂模式(Factory ...

空空如也

1 2 3 4 5 ... 20
收藏数 1,119,805
精华内容 447,922
关键字:

工厂