zoukankan      html  css  js  c++  java
  • Java设计模式:Factory Method(工厂方法)模式

    概念定义

    工厂方法(Factory Method)模式,又称多态工厂(Polymorphic Factory)模式或虚拟构造器(Virtual Constructor)模式。工厂方法模式通过定义工厂抽象父类(或接口)负责定义创建对象的公共接口,而工厂子类(或实现类)则负责生成具体的对象。

    工厂方法模式对简单工厂模式中的工厂类进一步抽象。核心工厂类不再负责产品的创建,而是演变为一个抽象工厂角色,仅负责定义具体工厂子类必须实现的接口。同时,针对不同的产品提供不同的工厂。即每个产品都有一个与之对应的工厂。这样,系统在增加新产品时就不会修改工厂类逻辑而是添加新的工厂子类,从而弥补简单工厂模式对修改开放的缺陷。

    在实际项目中,工厂方法模式是使用较多的工厂模式。

    应用场景

    • 当一个类不知道它所需要的对象的类时
      在工厂方法模式中,客户端不需要知道具体产品类的类名,只需要知道所对应的工厂即可,具体的产品对象由具体工厂类创建。
    • 当一个类希望通过其子类来指定创建哪个对象时
      在工厂方法模式中,抽象工厂类只需提供一个创建产品的接口,而由其子类来确定具体要创建的对象。利用面向对象的多态性和里氏替换原则,程序运行时子类对象将覆盖父类对象,从而使得系统更容易扩展。
    • 将创建对象的任务委托给多个工厂子类中的某一个,客户端在使用时可以无需关心是哪个工厂子类创建产品子类,需要时再动态指定,可将具体工厂类的类名存储在配置文件或数据库中。

    示例代码

    工厂方法模式由工厂接口(或抽象类)、一组实现工厂接口工厂类、一个产品接口(或抽象类)和一组实现产品接口的具体产品组成。某具体产品由其对应的具体工厂类创建。

    本节通过一个"喜闻乐见"的豪车系列,展示简单工厂模式的实现。示例代码如下:

    // 产品接口 //
    public interface ICar { // 也可定义为抽象类,但接口扩展性更好
        void drive();
    }
    // 若干具体的产品 //
    public class Bmw implements ICar {
        @Override
        public void drive() { System.out.println("drive a Bmw"); }
    }
    public class Benz implements ICar {
        @Override
        public void drive() { System.out.println("drive a Benz"); }
    }
    public class Audi implements ICar {
        @Override
        public void drive() { System.out.println("drive a Audi"); }
    }
    // 工厂接口 //
    public interface IFactory { // 也可定义为抽象类,但接口扩展性更好
        public ICar create();
    }
    // 若干具体的工厂,与具体产品一一对应 //
    public class BmwFactory implements IFactory {
        @Override
        public ICar create() { return new Bmw(); }
    }
    public class BenzFactory implements IFactory {
        @Override
        public ICar create() { return new Benz(); }
    }
    public class AudiFactory implements IFactory {
        @Override
        public ICar create() { return new Audi(); }
    }
    

    客户端通过new BenzFactory().create().drive()即可创建Benz实例并调用其drive()方法。新增豪车时,只需要新增豪车自身产品类和对应的工厂类,而不需要修改任何已有类。

    开源框架中,常常通过配置文件制定具体的工厂类,其模式形如:

    public <T> T getProduct(typeOrName) {
        IProductFactory iProductFactory = getIProductFactory(); // 通过配置文件获取具体工厂类
        return iProductFactory.getProduct(typeOrName);
    }
    

    模式优缺点

    工厂方法模式的优点如下:

    • 客户端只依赖产品的抽象,符合依赖倒置原则;无需关注具体产品,符合迪米特(最少知识)原则。
    • 工厂方法模式符合开放封闭原则,新增产品时只需增加相应的产品和工厂类,而无需修改现有代码。
    • 工厂方法模式符合单一职责原则,每个具体的工厂类只负责创建对应的产品。
    • 工厂方法模式不使用静态工厂方法,可以形成基于继承的等级结构。

    缺点如下:

    • 新增产品时除增加新产品类外,还要增加对应的具体工厂类,没有简单工厂代码简洁、高效。
    • 为了扩展性而进一步引入抽象层,增加了系统的抽象性和理解难度。

    业界实践

    • org.slf4j.LoggerFactory.getLogger(slf4j-api-1.7.25.jar)
    • org.springframework.context.support.AbstractApplicationContext.getBean(spring-context-4.3.4.RELEASE.jar)
  • 相关阅读:
    堆排序
    上线打包不常见错误整理
    ios开发者相关的几个apple邮箱
    App被拒选择回复还是重新提审,如何选择最高效的应对方式?
    iOS证书(.p12)和描述文件(.mobileprovision)申请
    OC与Swift混编
    tableViewCell重用
    tabBar选择不同item设置标题不同颜色
    iOS 关于TouchID指纹解锁的实现
    cocoaPods报错You need at least git version 1.8.5 to use CocoaPods
  • 原文地址:https://www.cnblogs.com/clover-toeic/p/11613179.html
Copyright © 2011-2022 走看看