源码分析设计模式之工厂模式(二、工厂方法模式)

上篇文章讲到了简单工厂模式众多缺陷,为了解决简单工厂模式带来的缺陷,从而引出了工厂方法模式

二、工厂方法模式

  • 工厂方法模式,又称工厂模式、多态工厂模式和虚拟构造器模式,通过定义工厂父类负责定义创建对象的公共接口,而子类则负责生成具体的对象
  • 简单理解就是: 将创建对象的任务委托给多个工厂子类中的某一个,客户端在使用时可以无须关心是哪一个工厂子类创建产品子类,需要时再动态指定,可将具体工厂类的类名存储在配置文件或数据库中
角色组成
  • 抽象工厂角色:它是具体工厂继承的父类或者实现的接口
  • 具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象
  • 抽象产品角色:它是具体产品继承的父类或者是实现的接口
  • 具体产品角色:具体工厂角色所创建的对象就是此角色的实例
/* ----------------------- 服务端 ----------------------- */
/**
 * 抽象产品
 */
interface Food {
    
    
    void production();
}

/**
 * 具体产品
 */
class HanBao implements Food {
    
    
    @Override
    public void production() {
    
    
        System.out.println("生产的汉堡包咯");
    }
}

class Xiaolongxia implements Food {
    
    
    @Override
    public void production() {
    
    
        System.out.println("生产的小龙虾咯");
    }
}

/**
 * 定义食物抽象工厂
 */
interface FoodFactory {
    
    
    public Food getFood();
}

/**
 * 具体产品工厂
 */
class HanBaoFactory implements FoodFactory {
    
    
    @Override
    public Food getFood() {
    
    
        return new HanBao();
    }
}

class XiaolongxiaFactory implements FoodFactory {
    
    
    @Override
    public Food getFood() {
    
    
        return new Xiaolongxia();
    }
}
/* ----------------------- 服务端 ----------------------- */
/* ----------------------- 客户端 ----------------------- */
public class Client {
    
    
    public static void main(String[] args) {
    
    
        FoodFactory ff = new HanBaoFactory();
        Food food = ff.getFood();
        food.production();
    }
}
/* ----------------------- 客户端 ----------------------- */

这个时候如果要新增产品,只需要创建新的具体产品类和具体产品工厂类,而不需要修改其他的服务端代码,这样就符合了单一职责(每个具体产品工厂只负责创建该产品),又符合了开闭原则(系统对扩展开放,对修改关闭)
在这里插入图片描述

工厂方法模式的缺点
  • 又面临最初的高耦合情况,因为一旦修改了具体产品工厂类名,客户端也要跟着修改,又违反了设计原则中的依赖倒置原则
  • 一旦产品繁多,那么工厂类也会造成繁多爆炸的情况
为工厂方法模式的缺点开脱一下
  • 有个名称叫规约:就是约定大于配置。我们把工厂的名字视为接口,而作为服务端,我们有责任和义务保证工厂的名字是趋向稳定的,客户端虽然依赖于工厂的具体的类名,但是在业内,基本上工厂的名字大多都比较稳定,至少工厂类的名字要比具体的类名字更稳定

  • 这里规约二字仿佛就把高耦合给开脱了,但是在以前,我们创建对象都是通过 new 的形式来的,而现在我们都是通过 Spring 中的 BeanFactory 来实例化的,BeanFactory 会在各个生命周期中对 bean 进行管理,而且 Spring 在这些阶段中通过各种接口暴露给我们,我们就是通过实现这些接口来对 bean 进行各种处理,而这些接口就是趋向稳定的

应用场景
  • 当一个类不知道它所需要的对象的类时,在工厂方法模式中,客户端不需要知道具体产品类的类名,只需要知道所对应的工厂即可
  • 当一个类希望通过其子类来指定创建对象时,在工厂方法模式中,对于抽象工厂类只需要提供一个创建产品的接口,而由其子类来确定具体要创建的对象,利用面向对象的多态性和里氏代换原则,在程序运行时,子类对象将覆盖父类对象,从而使得系统更容易扩展
开始对工厂方法模式进行变化
  • 目前我们的工厂是用来专门生产食物的,当我们现在要生产喝的时候,按照工厂方法模式来我们就需要新增抽象工厂,具体工厂,抽象产品,具体产品。
  • 而这么做的话,每增加一个产品等级,就需要增加四个类,这样就会造成类的爆炸式增长,从而增加了系统的复杂度和开销。而且一个工厂类只能生产一个具体产品
那么为了解决这些问题,抽象工厂模式就要闪亮登场了

おすすめ

転載: blog.csdn.net/qq_39249094/article/details/117405890