【设计模式】创建型模式之简单工厂模式

1.模式介绍

  • 简单工厂模式又叫静态方法模式(因为工厂类定义了一个静态方法)

  • 现实生活中,工厂是负责生产产品的;同样在设计模式中,简单工厂模式我们可以理解为负责生产对象的一个类,称为“工厂类”。 

2.解决的问题

将“类实例化的操作”与“使用对象的操作”分开,让使用者不用知道具体参数就可以实例化出所需要的“产品”类,从而避免了在客户端代码中显式指定,实现了解耦。

3.实际案例

需求:实现一个计算器,包含最基本的加减乘除操作。

需求分析:

首先,加减乘除属于某种操作,因此可以定义一个所有操作的超类Operation类。

其有一个抽象方法getResult(),需要子类进行实现,具体内部实现策略由具体子类提供。

而OperationFactory根据+、-、*、/操作的不同来生成具体的Operation子类。

 

public abstract class Operation {
    protected double numA;
    protected double numB;
​
    public double getNumA() {
        return numA;
    }
​
    public void setNumA(double numA) {
        this.numA = numA;
    }
​
    public double getNumB() {
        return numB;
    }
​
    public void setNumB(double numB) {
        this.numB = numB;
    }
​
    protected abstract double getResult(double numA, double numB);
}

OperationAdd类继承Operation类,表示加法操作。

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

同理,OperationMinus、OperationMultiply、OperationDivide分别表示减法、乘法、除法操作。

public class OperationMinus extends Operation {
​
    @Override
    protected double getResult(double numA, double numB) {
        return numA - numB;
    }
}
public class OperationMultiply extends Operation{
​
    @Override
    protected double getResult(double numA, double numB) {
        return numA * numB;
    }
}
public class OperationDivide extends Operation {
​
    @Override
    protected double getResult(double numA, double numB) {
        if (Double.compare(numB, 0) == 0) {
            throw new IllegalArgumentException("numB can not be zero!");
        }
        return numA / numB;
    }
}

OperationFactory是一个Operation工厂,根据具体传入的操作符来返回对应的具体Operation子类。

public class OperationFactory {
​
    public static Operation getOperation(String oper) {
        switch (oper) {
            case "+":
                return new OperationAdd();
            case "-":
                return new OperationMinus();
            case "*":
                return new OperationMultiply();
            case "/":
                return new OperationDivide();
            default:
                return null;
        }
    }
}

如下,根据实际传入的operation操作符的不同,执行不同的运算。

public class Main {
    public static void main(String[] args) {
        double numA = 8000;
        double numB = 1000;
        /**
         * 根据提供的operation的不同,执行不同的运算
         */
        String oper = "+";
        double result;
        Operation operation;
        operation = OperationFactory.getOperation(oper);
        result = operation.getResult(numA, numB);
        System.out.println(result);
​
        oper = "-";
        operation = OperationFactory.getOperation(oper);
        result = operation.getResult(numA, numB);
        System.out.println(result);
​
        oper = "*";
        operation = OperationFactory.getOperation(oper);
        result = operation.getResult(numA, numB);
        System.out.println(result);
​
        oper = "/";
        operation = OperationFactory.getOperation(oper);
        result = operation.getResult(numA, numB);
        System.out.println(result);
    }
}
/**
 * 运行结果
 *
 9000.0
 7000.0
 8000000.0
 8.0
 */

4.优点

  • 将创建实例的工作与使用实例的工作分开,使用者不必关心类对象如何创建,实现了解耦;

  • 把初始化实例时的工作放到工厂里进行,使代码更容易维护。 更符合面向对象的原则 & 面向接口编程,而不是面向实现编程。 

5.缺点

  • 工厂类集中了所有实例(产品)的创建逻辑,一旦这个工厂不能正常工作,整个系统都会受到影响;

  • 违背“开放 - 关闭原则”,一旦添加新产品就不得不修改工厂类的逻辑,这样就会造成工厂逻辑过于复杂。

  • 简单工厂模式由于使用了静态工厂方法,静态方法不能被继承和重写,会造成工厂角色无法形成基于继承的等级结构。

6.应用场景

在了解了优缺点后,我们知道了简单工厂模式的应用场景:

  • 客户如果只知道传入工厂类的参数,对于如何创建对象的逻辑不关心时;

  • 当工厂类负责创建的对象(具体产品)比较少时。

posted @ 2019-01-20 17:02 Ye_yang 阅读(...) 评论(...) 编辑 收藏