Java 简单工厂 工厂方法 抽象工厂模式

参考程杰《大话设计模式》

工厂模式:为创建对象提供过度接口,以便将创建对象的具体过程隐藏起来。

(1)简单工厂模式Simple Factory:不利于产生系列产品;
(2)工厂方法模式Factory Method:又称为多形性工厂;
(3)抽象工厂模式Abstract Factory:又称为工具箱,产生产品族,但不利于产生新的产品;

三种工厂模式逐步抽象。GoF中工厂模式只分为两类,工厂方法和抽象工厂,认为简单工厂是工厂方法的一种特例而已。

简单工厂模式

使用工厂创建不同的对象

在这里插入图片描述

当需要增加一个Operation时,需要先增加一个继承自Operation的子类,然后在工厂的switch里增加新的分支。

实例

定义枚举类型,作为工厂里switch的类型

public enum OperationTypeEnum {
    ADD(0),
    SUB(1),
    MUL(2),
    DIV(3)
    ;
    private Integer code;

    OperationTypeEnum(Integer code) {
        this.code = code;
    }
}

创建操作的基类,和其子类,子类实现自己的相关逻辑

public abstract class Operation {
    protected double numA;
    protected double numB;
    public abstract double getResult() throws Exception;

    public Operation(double numA, double numB) {
        this.numA = numA;
        this.numB = numB;
    }

    public void setNumA(double numA) {
        this.numA = numA;
    }

    public void setNumB(double numB) {
        this.numB = numB;
    }

    public Operation() {
    }
}

public class OperationAdd extends Operation{
    @Override
    public double getResult() {
        return numA + numB;
    }
}

public class OperationSub extends Operation{
    @Override
    public double getResult() {
        return numA - numB;
    }
}

public class OperationMul extends Operation {
    @Override
    public double getResult() {
        return numA * numB;
    }
}

public class OperationDiv extends Operation {
    final double exp = 0.00001d;
    @Override
    public double getResult() throws Exception {
        if(Math.abs(numB - 0d) < exp){
            throw new Exception("除数不能为0");
        }
        return numA / numB;
    }
}

工厂类,根据不同枚举,生产不同子类

public class SimpleFactory {

    public static Operation creatOperation(OperationTypeEnum type){
        switch (type){
            case ADD:
                return new OperationAdd();
            case SUB:
                return new OperationSub();
            case MUL:
                return new OperationMul();
            case DIV:
                return new OperationDiv();
            default:
                return null;
        }
    }
}

使用

public class TestdemoApplication {
    public static void main(String[] args) {
        double numA = 100.954d;
        double numB = 21.2d;
        Operation operation = SimpleFactory.creatOperation(OperationTypeEnum.ADD);
        operation.setNumA(numA);
        operation.setNumB(numB);
        System.out.println(operation.getResult());

        operation = SimpleFactory.creatOperation(OperationTypeEnum.SUB);
        operation.setNumA(numA);
        operation.setNumB(numB);
        System.out.println(operation.getResult());

        operation = SimpleFactory.creatOperation(OperationTypeEnum.MUL);
        operation.setNumA(numA);
        operation.setNumB(numB);
        System.out.println(operation.getResult());

        operation = SimpleFactory.creatOperation(OperationTypeEnum.DIV);
        operation.setNumA(numA);
        operation.setNumB(numB);
        System.out.println(operation.getResult());
    }
}

输出结果

在这里插入图片描述

工厂方法模式

定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。

在这里插入图片描述

当需要增加一个Operation时,不需要修改已有代码,只需要先增加一个继承自Operation的子类,再新增一个工厂子类,用来生产新的Operation子类。

实例

工厂接口和其子类,即具体生成不同产品的子工厂

public interface Factory {
    Operation createOperation();
}

public class AddFactory implements Factory {
    @Override
    public Operation createOperation() {
        return new OperationAdd();
    }
}

public class SubFactory implements Factory {
    @Override
    public Operation createOperation() {
        return new OperationSub();
    }
}

public class MulFactory implements Factory {
    @Override
    public Operation createOperation() {
        return new OperationMul();
    }
}

public class DivFactory implements Factory {
    @Override
    public Operation createOperation() {
        return new OperationDiv();
    }
}

创建操作的基类,和其子类,子类实现自己的相关逻辑

public abstract class Operation {
    protected double numA;
    protected double numB;
    public abstract double getResult() throws Exception;

    public Operation(double numA, double numB) {
        this.numA = numA;
        this.numB = numB;
    }

    public void setNumA(double numA) {
        this.numA = numA;
    }

    public void setNumB(double numB) {
        this.numB = numB;
    }

    public Operation() {
    }
}

public class OperationAdd extends Operation{
    @Override
    public double getResult() {
        return numA + numB;
    }
}

public class OperationSub extends Operation{
    @Override
    public double getResult() {
        return numA - numB;
    }
}

public class OperationMul extends Operation {
    @Override
    public double getResult() {
        return numA * numB;
    }
}

public class OperationDiv extends Operation {
    final double exp = 0.00001d;
    @Override
    public double getResult() throws Exception {
        if(Math.abs(numB - 0d) < exp){
            throw new Exception("除数不能为0");
        }
        return numA / numB;
    }
}


使用

```java
public class TestdemoApplication {
    public static void main(String[] args) {
        double numA = 100.954d;
        double numB = 21.2d;
        //先创建工厂
        Factory factory = new AddFactory();
        Operation operation = factory.createOperation();
        operation.setNumA(numA);
        operation.setNumB(numB);
        System.out.println(operation.getResult());

        factory = new SubFactory();
        operation = factory.createOperation();
        operation.setNumA(numA);
        operation.setNumB(numB);
        System.out.println(operation.getResult());

        factory = new MulFactory();
        operation = factory.createOperation();
        operation.setNumA(numA);
        operation.setNumB(numB);
        System.out.println(operation.getResult());

        factory = new DivFactory();
        operation = factory.createOperation();
        operation.setNumA(numA);
        operation.setNumB(numB);
        System.out.println(operation.getResult());
    }
}

输出结果

在这里插入图片描述

抽象工厂模式

提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

在这里插入图片描述

如果要新增一个产品,需要新增的类很多,如下实例中,需要新增产品的抽象类(ProductComputer),新增其实现类(AppleProductComputer,MiProductComputer),修改工厂类(Factory,AppleFactory,MiFactory新增createPadComputer()方法)

实例

工厂相关接口和实现类

public interface Factory {
    ProductPhone createPhone();

    ProductPad createPad();
}

//生成苹果产品的工厂
public class AppleFactory implements Factory{
    @Override
    public ProductPhone createPhone() {
        return new AppleProductPhone();
    }

    @Override
    public ProductPad createPad() {
        return new AppleProductPad();
    }
}

//生成小米产品的工厂
public class MiFactory implements Factory{
    @Override
    public ProductPhone createPhone() {
        return new MiProductPhone();
    }

    @Override
    public ProductPad createPad() {
        return new MiProductPad();
    }
}

产品相关接口和实现类

//产品--手机
public interface ProductPhone {
    void installScreen();

    void installkeyboard();
}

public class AppleProductPhone implements ProductPhone{
    @Override
    public void installScreen() {
        System.out.println("安装苹果手机屏幕");
    }

    @Override
    public void installkeyboard() {
        System.out.println("安装苹果手机键盘");
    }
}

public class MiProductPhone implements ProductPhone{
    @Override
    public void installScreen() {
        System.out.println("安装小米手机屏幕");
    }

    @Override
    public void installkeyboard() {
        System.out.println("安装小米手机键盘");
    }
}


//产品--平板
public interface ProductPad {
    void installScreen();

    void installkeyboard();
}

public class AppleProductPad implements ProductPad{
    @Override
    public void installScreen() {
        System.out.println("安装苹果平板屏幕");
    }

    @Override
    public void installkeyboard() {
        System.out.println("安装苹果平板键盘");
    }
}

public class MiProductPad implements ProductPad{
    @Override
    public void installScreen() {
        System.out.println("安装小米平板屏幕");
    }

    @Override
    public void installkeyboard() {
        System.out.println("安装小米平板键盘");
    }
}

使用

public class TestdemoApplication {
    public static void main(String[] args) {
        Factory factory = new MiFactory();
        ProductPhone phone = factory.createPhone();
        ProductPad pad = factory.createPad();
        phone.installkeyboard();
        phone.installScreen();
        pad.installkeyboard();
        pad.installScreen();
    }
}

输出结果

在这里插入图片描述

总结

  • 简单工厂模式最大优点在于工厂类中包含了必要的逻辑判断,根据客户的选择条件动态实例化相关类,对于客户端来说,去除了与具体产品的依赖
  • 工厂方法模式,客户端需要决定实例化哪一个工厂来实现运算类,选择判断的问题还存在,但是判断是在客户端做的。
  • 抽象工厂模式最大好处是便于交换产品系列,具体的工厂在初始化时改变,即可改变不同的产品配置。并且具体的创建实例过程与客户端分离,客户端只是通过它们的抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户代码中。
  • 所有在用简单工厂的地方,都可以考虑用反射+配置文件方式去除switch或if分支,解除分支判断带来的耦合。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值