Java-工厂设计模式

  • 2019 年 10 月 14 日
  • 筆記

一、关于工厂设计模式

介绍设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,

    并且是通过使用一个共同的接口来指向新创建的对象。

意图:定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。

主要解决:主要解决接口选择的问题。

何时使用:我们明确地计划不同条件下创建不同实例时。

如何解决:让其子类实现工厂接口,返回的也是一个抽象的产品。

分类:普通简单工厂、多个方法的简单工厂、多个静态方法的简单工厂、工厂设计模式。

 

二、代码实现

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

  

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

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

Sender

package pers.hupo.hupow.factory;  /**   * @author hupo   * 创建一个接口   * */  public interface Sender {      void Send();  }

 

其次,创建实现类:

MailSender

package pers.hupo.hupow.factory;    /**   * @author hupo   * Sender实现类   * */  public class MailSender implements Sender {      @Override      public void Send() {          System.out.println("this mail message");      }  }

 

SmsSender

package pers.hupo.hupow.factory;    /**   * @author hupo   * Sender实现类   * */  public class SmsSender implements Sender {      @Override      public void Send() {          System.out.println("this sms message");      }  }

 

最后,建工厂类

package pers.hupo.hupow.factory;    /**   * @author hupo   * 工厂类   * */  public class SendFactory {        public Sender produce(String type) {          if ("mail".equals(type)) {              return new MailSender();          }          if ("sms".equals(type)) {              return new SmsSender();          }          return null;      }  }

 

测试方法

package pers.hupo.hupow.factory;      public class FactoryTest {      public static void main(String[] args) {

     SendFactory sendFactory
= new SendFactory(); Sender sender = sendFactory.produce("sms"); sender.Send(); } }

 

输出结果:

this sms message

 

  多个方法的简单工厂:是对普通工厂方法模式的改进,在普通工厂方法模式中,如果传递的字符串出错,则不能正确创建对象,

             而多个工厂方法模式是提供多个工厂方法,分别创建对象。关系图如下

 

 

 

 将工厂类改动一些 如下:

package pers.hupo.hupow.factory;    /**   * @author hupo   * 工厂类   * */  public class SendFactory {      /*       * 多方法的简单工厂       */       public Sender produceMail() {          return new MailSender();       }         public Sender produceSms() {          return new SmsSender();       }  }

修改一下测试类

 SendFactory sendFactory = new SendFactory();   Sender sender = sendFactory.produceMail();   sender.Send();

输出结果:

  this mail message

   

  多个静态方法简单工厂:将上面的多个工厂类里的方法置为静态的,不需要创建实例,直接调用即可。如下

package pers.hupo.hupow.factory;    /**   * @author hupo   * 工厂类   * */  public class SendFactory {      /*       * 静态多方法工厂       * */      public static Sender produceMail() {          return new MailSender();      }        public static Sender produceSms() {          return new SmsSender();      }    }

测试

      /*静态多方法*/          Sender sender = SendFactory.produceMail();          sender.Send();

输出:

this mail messageb

 

总体来说,简单工厂模式适合:凡是出现了大量的产品需要创建,并且具有共同的接口时,可以通过工厂方法模式进行创建。在以上的三种模式中,

第一种如果传入的字符串有误,不能正确创建对象(当然你可以做一个返回报错信息的类),第三种相对于第二种,不需要实例化工厂类,所以,大多数情况下,我们会选用第三种——静态工厂方法模式。

 

三、工厂方法模式(Factory Method)

简单工厂模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序,必须对工厂类进行修改,这违背了闭包原则。

所以,从设计角度考虑,有一定的问题,如何解决?就用到工厂方法模式,创建一个工厂接口和创建多个工厂实现类,这样一旦需要增加新的功能,直接增加新的工厂类就可以了,不需要修改之前的代码。

 

 

首先还是创建发送信息端的接口

Sender

package pers.hupo.hupow.FactoryMethod;    /**   * @author hupo   * 工厂方法设计模式-信息接口   */  public interface Sender {      void Send();  }

两个实现类

MailSender

package pers.hupo.hupow.FactoryMethod;    /**   * @author hupo   * 工厂方法设计模式-实现类   * */  public class MailSender implements Sender {      @Override      public void Send() {          System.out.println("this is mailSender");      }  }

SmsSender

package pers.hupo.hupow.FactoryMethod;    /**   * @author hupo   * 工厂方法设计模式-实现类   * */  public class SmsSender implements Sender {      @Override      public void Send() {          System.out.println("this is smsSender");      }  }

 

 然后再来创造工厂类接口(大内统管( ̄▽ ̄)”

Provider

package pers.hupo.hupow.FactoryMethod;    /**   * @author hupo   * 工厂方法设计模式-工厂类接口   * */  public interface Provider {      Sender produce();  }

实现类工厂

SendMailFactory

package pers.hupo.hupow.FactoryMethod;    /**   * @author hupo   * 工厂类设计方法-实现方法   * */  public class SendMailFactory implements Provider {      @Override      public Sender produce() {          return new MailSender();      }  }

SendSmsFactory

package pers.hupo.hupow.FactoryMethod;    /**   * @author hupo   * 接口实现方法   * */  public class SendSmsFactory implements Provider {      @Override      public Sender produce() {          return new SmsSender();      }  }

完成之后写个测试类来试试

package pers.hupo.hupow.FactoryMethod;    /**   * @author hupo   * 测试类   * */  public class FactoryMethodTest {      public static void main(String[] args) {          Provider provider = new SendMailFactory();          Sender sender = provider.produce();          sender.Send();      }  }

输出结果

this is mailSender

 

加个工厂类扩展试试

添加哲学家van 和Billy 继承sender

van

package pers.hupo.hupow.FactoryMethod;    public class VanSender implements Sender {      @Override      public void Send() {          System.out.println("f♂ck y♂u");      }  }

View Code

Billy

package pers.hupo.hupow.FactoryMethod;    public class BillySender implements Sender {      @Override      public void Send() {          System.out.println("帕秋莉♂GO");      }  }

View Code

然后使用SendBillyFactory 继承Provider

package pers.hupo.hupow.FactoryMethod;    public class SendBillyFactory implements Provider {      @Override      public Sender produce() {          return new BillySender();      }  }

View Code

测试类

    /*哲学家测试*/          Provider provider = new SendBillyFactory();          Sender sender = provider.produce();          sender.Send();

View Code

输出:

帕秋莉♂GO

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