设计模式-简单工厂模式

简单工厂模式:简单的说就是通过传入的参数,动态的生成你需要的类,并调用该类的方法。
也能使你的代码变的易于维护扩展性好灵活等等,,

话不多说,来看一段 将普通代码演变成工厂模式的例子
有一段实现计算器的简单代码

public class program2 {
    public static void main(String[] args) {
        try {
            System.out.println("请输入数字A");
            Scanner scanner = new Scanner(System.in);
            double strNumberA = scanner.nextDouble();
            System.out.println("请选择运算符号");
            String strOperate = scanner.next();
            System.out.println("请输入数字B");
            double strNumberB = scanner.nextDouble();
            String result = "";
            switch (strOperate) {
                case "+":
                    result = String.valueOf(strNumberA + strNumberB);
                    break;
                case "-":
                    result = String.valueOf(strNumberA - strNumberB);
                    break;
                case "*":
                    result = String.valueOf(strNumberA * strNumberB);
                    break;
                case "/":
                    if (strNumberB != 0) {
                        result = String.valueOf(strNumberA / strNumberB);
                    } else {
                        System.out.println("除数不能为0");
                    }
                    break;
            }
            System.out.println(result);
        } catch (Exception e) {
            System.out.println("你的输入有误:" + e);
        }
    }
}

恩,乍一看,这段代码命名规范,考虑到了除法的特殊情况,也考虑到了用户输入的是否是数字的问题,没啥毛病呀。
恩,代码是没啥毛病。但是!
1 如果别的地方要复用怎么办?用ctrl+c ctrl+v?这其实是非常不好的编码习惯!因为当你的代码中重复的代码多到一定程度,维护的时候就是一场灾难。

2 假如我需要增加一个开平方根运算,是直接在switch中直接新加一个分支?那么问题就来了,为了添加一个新的运算方法,却要让加减乘除的运算一起参与编译,如果你一不小心把加法改成了减法!这就糟糕了。

第一个问题的解决方案:将加减乘除的业务封装起来
第二个问题的解决方案 : 将加减乘除等运算分离,修改其中一个不影响另外的几个,增加运算算法也不影响其他代码

改进后的代码

 //运算类 基类 提取公共属性和方法
public class Operation {
    private double strNumberA;
    private double strNumberB;

    public double getStrNumberA() {
        return strNumberA;
    }

    public void setStrNumberA(double strNumberA) {
        this.strNumberA = strNumberA;
    }

    public double getStrNumberB() {
        return strNumberB;
    }

    public void setStrNumberB(double strNumberB) {
        this.strNumberB = strNumberB;
    }

    /**
     * 得到结果
     * @return
     * @throws Exception
     */
    public  double getResult() throws Exception {
        return 0d;
    }
    }


/**
 * 加法
 */
public class OperationAdd extends Operation {
    @Override
    public double getResult() {
        double result;
        result = getStrNumberA() + getStrNumberB();
        return result;
    }
}


/**
 * 减法
 */
public class OperationSub extends Operation {

    @Override
    public double getResult() {
        double result;
        result = this.getStrNumberA() - this.getStrNumberB();
        return result;
    }
}

/**
 * 乘法
 */
public class OperationMul extends Operation {

    @Override
    public double getResult() {
        double result;
        result = this.getStrNumberA() * this.getStrNumberB();
        return result;
    }
}

/**
 * 除法
 */
public class OperationDiv extends Operation {
    @Override
    public double getResult() throws Exception {
        double result;
        if (this.getStrNumberB() == 0) {
            throw new Exception("除数不能为0!");
        }
        result = this.getStrNumberA() / this.getStrNumberB();
        return result;
    }

}

上述代码使用封装的方式将业务从代码中分离了出来
并用继承的方式实现了各个运算模块互不干扰
那么现在我们如何去实例化对象呢?也就是说到底要实例化谁?将来会不会增加实例化的对象,比如增加开根运算,这是很容易变化的地方!应该考虑用一个单独的类来做这个创建实例的过程,这就是工厂


/**
 * 工厂模式
 * 根据用户传入的操作符
 * 动态的返回对应的操作对象
 */
public class OperationFactory {
    public static Operation createOperate(String operate) {
        Operation operation = null;
        switch (operate) {
            case "+":
                operation = new OperationAdd();
                break;
            case "-":
                operation = new OperationSub();
                break;
            case "*":
                operation = new OperationMul();
                break;
            case "/":
                operation = new OperationDiv();
                break;
        }
        return operation;
    }
}

通过这个operationFactory类使得我们调用的时候 只要传入对应的operate操作符,程序将通过多态的方式将你想要的operation类返回给你

public class program4 {
    public static void main(String[] args) {
        System.out.println("请输入数字A");
        Scanner scanner = new Scanner(System.in);
        double strNumberA = scanner.nextDouble();
        System.out.println("请选择运算符号");
        String strOperate = scanner.next();
        System.out.println("请输入数字B");
        double strNumberB = scanner.nextDouble();

        //传入对应的操作符 工厂将会实例化对应的operation类并返回
        Operation operation = OperationFactory.createOperate(strOperate);
        operation.setStrNumberA(strNumberA);
        operation.setStrNumberB(strNumberB);

        try {
            System.out.println(operation.getResult());
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

如果需要更改 加法 的逻辑 只需要更改对应的 加法类 operationAdd 就可以了 不会影响其他的类 <易维护>
如果需要增加一个算法 只需要添加一个对应的运算子类 并在工厂类的 switch添加新的分支就可以<易扩展>
只需要传入不同的操作符,就能实例化对应的operation类<灵活>
如果需要修改界面 就只要更改界面 与算法没有关系

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值