精通设计模式之工厂方法模式

来源:互联网 发布:centos iso镜像 下载 编辑:程序博客网 时间:2024/05/17 04:53

工厂方法模式

工厂方法模式又被称为虚拟构造器(Virtual Constructor)

作用

定义用于创建对象的接口,但是让子类决定要实例化哪个类。工厂方法将类实例化推迟到子类。

说明

真实案例

  1. 铁匠制造武器。精灵需要精灵武器和兽人需要兽医武器。根据手头的客户,正确的类型的铁匠被召唤。
  2. 发送器发送信息。短信发送器发送短信息和邮件发送器发送邮件信息。根据业务需求,调用正确类型的发送器发送信息。

简而言之

工厂方法模式提供了一种将实例化逻辑委托给子类的方法

维基百科定义

在基于类的编程中,工厂方法模式是使用工厂方法来处理创建对象的问题的创建模式,而不必指定将要创建的对象的确切类。这可以通过调用工厂方法(在接口中指定并由子类实现)来实现,或者在基类中实现,并且可选地被派生类覆盖,而不是调用构造函数。

程序示例

以我们的信息发送器为例。首先我们有一个信息发送器接口和一些实现

/** * Description: 定义发送者接口 * <br /> Author: vimx86 */public interface Sender {    /**     * 发送信息     */    void send();}/** * Description: 邮件发送者 * <br /> Author: vimx86 */public class MailSender implements Sender {    @Override    public void send() {        System.out.println("邮件发送者发送了一封邮件!");    }}/** * Description: 短信息发送者 * <br /> Author: vimx86 */public class SmsSender implements Sender {    @Override    public void send() {        System.out.println("短信息发送者发送了一封邮件!");    }}

定义信息发送器生产工厂

/** * Description: 发送工厂(普通工厂模式) * <br /> Author: vimx86 */public class SimpleSendFactory {    /**     * 根据发送者类型名称生产对应发送者     *     * @param type 发送者类型     * @return 具体发送者     */    public Sender produce(String type) {        if ("mail".equals(type)) {            return new MailSender();        } else if ("sms".equals(type)) {            return new SmsSender();        } else {            System.out.println("请输入正确的类型!");            return null;        }    }}

现在,根据发送器类型调用正确的信息发送器并发送信息。

/** * Description: 测试普通工厂模式 * <br /> Author: vimx86 */public class SimpleSendFactoryTest {    @Test    public void test() throws Exception {        SimpleSendFactory factory = new SimpleSendFactory();        Sender sender = factory.produce("sms");        sender.send();    }}

适用场景

何时使用“工厂方法”模式

  • 一个类不能预期它必须创建的对象类
  • 一个类希望其子类来指定它创建的对象
  • 类将责任委托给几个辅助子类之一,并且您想要本地化哪个助手子类是委托的知识

Known uses

点进去看一看,理解一下 ^_^!!!
* java.util.Calendar
* java.util.ResourceBundle
* java.text.NumberFormat
* java.nio.charset.Charset
* java.net.URLStreamHandlerFactory
* java.util.EnumSet
* javax.xml.bind.JAXBContext

信息发送案例

  • 普通工厂模式
  • 多个工厂方法模式
  • 静态工厂方法模式

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

工厂方法模式的运用

结合实际业务进行分析运用设计案例

业务场景

获取不同票务商(大众,猫眼,蜘蛛等等)提供的影院实时座位图。
考虑业务扩展,保证有新票务商的接入时不影响当前业务。提供扩展性,可维护性。

分析设计

因为每家票务商都需要提供实时座位图功能,故可抽象出共同的接口 实时座位图提供商 提供实时座位图功能。

定义实时座位图提供商接口 RealTimeSeats 和实现具体票务商的子类。

public interface RealTimeSeats{    /**    * 获取实时座位图信息    */    RealtimeSeatModel getSeats(RealTimeSeatsRequest realTimeSeatsRequest);}/** * Description: 猫眼获取实时座位图 * <br /> Author: vimx86 */public class MaoYanRealTimeSeats implements RealTimeSeats{    @Override    public RealtimeSeatModel getSeats(RealTimeSeatsRequest realTimeSeatsRequest) {          // 猫眼获取实时座位图逻辑调用……   }}/** * Description: 蜘蛛网获取实时座位图 * <br /> Author: vimx86 */public class SpiderRealTimeSeats implements RealTimeSeats{    @Override    public RealtimeSeatModel getSeats(RealTimeSeatsRequest realTimeSeatsRequest) {        // 蜘蛛网获取实时座位图逻辑调用……    }}

定义获取实时座位图工厂

/** * Description: 实时座位图工厂 * <br /> Author: vimx86 */public class RealTimeSeatsFactory {    public static RealTimeSeats produceSpider() {        return new SpiderRealTimeSeats ();    }    public static RealTimeSeats produceMaoYan() {        return new MaoYanRealTimeSeats ();    }}

这种工厂方法模式 扩展需要修改工厂类,等我们学习了抽象工厂模式再进一步改进。

参考资料

  • Java设计模式
  • Java开发中的23种设计模式详解
原创粉丝点击