设计模式-简单工厂模式

来源:互联网 发布:单桂敏淘宝店铺7205286 编辑:程序博客网 时间:2024/05/16 23:58

设计模式-简单工厂模式

概念:

1、简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。

2、简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例。

3、该模式中包含的角色及其职责:
工厂(Factory)角色:
简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类的创建产品类的方法可以被外界直接调用,创建所需的产品对象。
抽象产品(AbstarctProduct)角色:
简单工厂模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。
具体产品(SpecificProduct)角色:
是简单工厂模式的创建目标,所有创建的对象都是充当这个角色的某个具体类的实例。

优点

工厂类是整个模式的核心类; 包含了必要的逻辑判断,根据外界给定的信息,决定究竟应该创建哪个具体类的对象.通过使用工厂类,外界可以从直接创建具体产品对象的尴尬局面摆脱出来,仅仅需要负责“消费”对象就可以了。而不必管这些对象究竟如何创建及如何组织的.明确了各自的职责和权利,有利于整个软件结构的优化

缺点

当系统中的具体产品类不断增多时候,可能会出现要求工厂类根据不同条件创建不同实例的需求.这种对条件的判断和对具体产品类型的判断交错在一起,很难避免模块功能的蔓延,对系统的维护和扩展非常不利;利用反射可以使得这些缺点在工厂方法模式中得到了一定的克服。

使用场景

工厂类负责创建的对象比较少;
客户只知道传入工厂类的参数,对于如何创建对象(逻辑)不关心;
由于简单工厂很容易违反高内聚责任分配原则,因此一般只在很简单的情况下应用。

UML类图结构:


图背景介绍:

上图利用简单工厂模式实现一个控制台计算器功能

图解说明:

工厂(Factory)角色:
类:OperationFactory
说明:通过传入操作符‘+’ | ‘-’  | ‘*’  | ‘/’ 给方法buildOperation,告诉工厂我要哪个具体产品,内部使用swith语句实现(关注我的博客,后续有关于使用反射实现的方式)
代码:
/** * Created by laizhiyuan on 2017/6/1. * * 设计模式-简单工厂模式-工厂类 */public abstract class OperationFactory {    public static final AbstractOperation buildOperation(char oper){        switch (oper){            case '+':                return new AddOperation();            case '-':                return new SubOperation();            case '*':                return new MultOperation();            case '/':                return new DivisionOperation();            default:                throw new RuntimeException("input oper error");        }    }}
抽象产品(AbstarctProduct)角色:
类: AbstractOperation 
说明:产品基类,可以使用普通类或抽象类,定义产品模板和统一工厂方法的返回值;这里我使用抽象类作为基类;
代码:

/** * Created by laizhiyuan on 2017/5/31. * * 设计模式-简单工厂模式-产品基类-运算逻辑抽象 */public abstract class AbstractOperation {    /**     * 操作数A     */    private double countA;    /**     * 操作数B     */    private double countB;    public double getCountA() {        return countA;    }    public void setCountA(double countA) {        this.countA = countA;    }    public double getCountB() {        return countB;    }    public void setCountB(double countB) {        this.countB = countB;    }    /**     * 抽象运算接口,由子类实现     * @return     */    public abstract double countResult();}

具体产品(SpecificProduct)角色:
类:AddOperation DivisionOperation SubOperation MultOperation
说明:具体实现
代码:
/** * Created by laizhiyuan on 2017/6/1. * * 设计模式-简单工厂模式-产品子类(加法运算实现) */public class AddOperation extends AbstractOperation{    /**     * 加法运算实现     * @return     */    @Override    public double countResult() {        if (this.getCountA() == 0){            return this.getCountB();        }        if (this.getCountB() == 0){            return this.getCountA();        }        return this.getCountA() + this.getCountB();    }}


/** * Created by laizhiyuan on 2017/6/1. * * 设计模式-简单工厂模式-产品子类(除法运算实现) */public class DivisionOperation extends AbstractOperation{    /**     * 除法运算实现     * @return     */    @Override    public double countResult() {        if (this.getCountB() == 0){            /**             * 除数不能为0             */            throw new RuntimeException("Divisor cannot be zero");        }        return this.getCountA() / this.getCountB();    }}


/** * Created by laizhiyuan on 2017/6/1. * * 设计模式-简单工厂模式-产品子类(乘法运算实现) */public class MultOperation extends AbstractOperation{    /**     * 乘法运算实现     * @return     */    @Override    public double countResult() {        if (this.getCountA() == 0 || this.getCountB() == 0){            return 0;        }        return this.getCountA() * this.getCountB();    }}


/** * Created by laizhiyuan on 2017/6/1. * * 设计模式-简单工厂模式-产品子类(减法运算实现) */public class SubOperation extends AbstractOperation{    /**     * 减法运算实现     * @return     */    @Override    public double countResult() {        if (this.getCountA() == 0){            return 0;        }        if (this.getCountB() == 0){            return this.getCountA();        }        return this.getCountA() - this.getCountB();    }}



测试

/** * Main方法测试 * * Created by laizhiyuan on 2017/6/1. */public class Main {    public static void main(String[] args) {        System.out.println("请输入第一个操作数:");        Scanner scanner = new Scanner(System.in);        String operA = scanner.nextLine();        try{            System.out.println("请输入操作符:");            String oper = scanner.nextLine();            char operChar = oper.charAt(0);            boolean tag = false;            if (operChar != '+' && operChar != '-' && operChar != '*' && operChar != '/'){                tag = true;            }            while (tag){                System.out.println("输入操作符错误,请重新输入!");                oper = scanner.nextLine();                operChar = oper.charAt(0);                if (operChar != '+' && operChar != '-' && operChar != '*' && operChar != '/'){                    tag = true;                }else{                    tag = false;                }            }            System.out.println("请输入第二个操作数:");            String operB = scanner.nextLine();            AbstractOperation operation = OperationFactory.buildOperation(operChar);            operation.setCountA(Double.valueOf(operA));            operation.setCountB(Double.valueOf(operB));            double resultCount = operation.countResult();            System.out.println("计算结果是=======> " + resultCount);        }catch (Exception ex){            System.out.printf("输入有误!");            System.exit(1);        }    }}

控制台输出











原创粉丝点击