工厂方法模式

工厂方法模式是对简单工厂模式的进一步抽象化和推广,其好处是可以使系统在不修改原来代码的情况下引进新的产品,即满足开闭原则。

一、工厂方法模式

1、工厂方法模式的定义

工厂方法模式(Factory Method Pattern),又叫作多态性工厂模式。

指定义一个创建对象的接口,让子类决定实例化哪一个类,工厂方法把一个类的实例化推迟到其子类中进行。

工厂方法模式解决了简单工厂生产太多产品导致其内容代码臃肿(if条件太多)的问题,也符合开闭原则。

2、工厂方法模式的结构

(1)模式的结构

工厂方法模式的主要角色如下:

  • 抽象工厂(Abstract Factory)
    是工厂方法模式的核心,与应用程序无关。提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法 newProduct() 来创建产品。
  • 具体工厂(ConcreteFactory)
    实现抽象工厂接口的具体工厂类,重写创建对象方法来完成具体产品的创建。
  • 抽象产品(Product)
    是所有对象的超类,定义了产品的规范,描述了产品的共同主要特性和功能。
  • 具体产品(ConcreteProduct)
    实现了抽象产品角色所定义的接口,某个产品对象由专门的具体工厂来创建,具体产品和具体工厂之间往往一一对应。

(2)结构图如下:(图来自网络)
在这里插入图片描述

3、优缺点

主要优点:

  • 用户只需要知道具体工厂的名称就可得到想要的产品,无须知道产品的具体创建过程。
  • 灵活性增强,对于新产品的创建,只需多写一个相应的工厂类。
  • 典型的解耦框架。高层模块只需要知道产品的抽象类,无须关心其他实现类,满足迪米特法则、依赖倒置原则和里氏替换原则。

主要缺点:

  • 类的个数容易过多,增加复杂度
  • 增加了系统的抽象性和理解难度
  • 抽象产品只能生产一种产品,此弊端可使用抽象工厂模式解决。
4、使用场景
  • 客户端不关心创建产品的细节,只关心创建产品的工厂名。创建产品对象的任务由多个具体子工厂中的某一个完成,而抽象工厂只提供创建产品的接口。
  • 一个类通过其子类来指定创建哪个产品对象。
5、在框架源码中使用也很广泛
  • Logback源码中 ILoggerFactory

二、模式的通用实现

代码如下:

public class FactoryMethodPattern {
    public static void main(String[] args) {
        try {
            AbstractFactory factory1 = new ConcreteFactory1();
            Product product1 = factory1.newProduct();
            product1.show();

            AbstractFactory factory2 = new ConcreteFactory2();
            Product product2 = factory2.newProduct();
            product2.show();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}

//抽象产品:提供了产品的接口
interface Product {
    public void show();
}
//具体产品1:实现抽象产品中的抽象方法
class ConcreteProduct1 implements Product {
    @Override
    public void show() {
        System.out.println("具体产品1显示...");
    }
}
//具体产品2:实现抽象产品中的抽象方法
class ConcreteProduct2 implements Product {
    @Override
    public void show() {
        System.out.println("具体产品2显示...");
    }
}

//抽象工厂:提供了厂品的生成方法
interface AbstractFactory {
    public Product newProduct();
}
//具体工厂1:实现了厂品的生成方法
class ConcreteFactory1 implements AbstractFactory {
    @Override
    public Product newProduct() {
        System.out.println("具体工厂1生成-->具体产品1...");
        return new ConcreteProduct1();
    }
}
//具体工厂2:实现了厂品的生成方法
class ConcreteFactory2 implements AbstractFactory {
    @Override
    public Product newProduct() {
        System.out.println("具体工厂2生成-->具体产品2...");
        return new ConcreteProduct2();
    }
}

三、模式的应用实例

简易计算器为例,需求:输入两个数和运算符,得到结果。传送门:简单工厂模式

简单工厂模式的实现改造成工厂方法模式实现。

1、抽象工厂
public interface IOperationFactory {
    IOperation createOperation();
}
2、具体工厂
  • 加法
public class AddFactory implements IOperationFactory{
    @Override
    public IOperation createOperation() {
        return new OperationAdd();
    }
}
  • 除法,其他同理
public class DivFactory implements IOperationFactory {
    @Override
    public IOperation createOperation() {
        return new OperationDiv();
    }
}
3、抽象产品
public interface IOperation {
    double compute (double number1, double number2) throws Exception;
}
4、具体产品
  • 加法
public class OperationAdd implements IOperation {
    @Override
    public double compute(double number1, double number2) {
        return number1 + number2;
    }
}
  • 除法,其他同理
public class OperationDiv implements IOperation {
    @Override
    public  double compute(double number1, double number2) throws Exception {
        if(number2 == 0){
            throw new Exception("除数不能为0!");
        }
        return number1 / number2;
    }
}
5、测试
    public static void main(String[] args) throws Exception {
        double num1 = 10;
        double num2 = 2;

        IOperationFactory addFactory = new AddFactory();
        IOperation add = addFactory.createOperation();
        System.out.println(add.compute(num1, num2));

        IOperationFactory divFactory = new DivFactory();
        IOperation div = divFactory.createOperation();
        System.out.println(div.compute(num1, num2));
    }

在这里插入图片描述

参考文章:

—— Stay Hungry. Stay Foolish. 求知若饥,虚心若愚。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值