设计模式:简单工厂模式

最近正在学习设计模式,第一个接触到的就是非常经典的工场模式。由于之前没有多少设计模式相关的知识积累,所以我选择了据说对菜鸟非常友好的《大话设计模式》。不得不说大话设计模式这本书,内容非常接地气,我个人非常喜欢,本文就是将大话设计模式中的简单工厂模式例子用JAVA实现。

场景:使用面向对象语言设计一个简单计算器,要求输入两个数以及操作符,输出计算结果。

项目结构图如下:
工程结构图

项目分为了四个部分,MainClass作为客户端,负责用户输入、工程方法调用和结果输出;CalculatorFactory作为工厂类,向用户端提供运算类的对象;CalculatoryName是枚举,由于switch/case在jdk7之前都不支持String,所以这里用枚举作为switch的选择变量;ICalculator是抽象的运算类接口,AddCalculator、SubCalculator、MulCalculator、ExcCalculator分别为加、减、乘、除四种运算类的实现。

运算类接口ICalculator:

package com.jswang.calculator;

public interface ICalculator {
    public double getResult(double num1, double num2);
}

加法运算类AddCalculator:

package com.jswang.calculator;

public class AddCalculator implements ICalculator{
    @Override
    public double getResult(double num1, double num2) {
        return num1+num2;
    }
}

减法运算类SubCalculator:

package com.jswang.calculator;

public class SubCalculator implements ICalculator{

    @Override
    public double getResult(double num1, double num2) {
        return num1-num2;
    }

}

乘法运算类MulCalculator:

package com.jswang.calculator;

public class MulCalculator implements ICalculator{

    @Override
    public double getResult(double num1, double num2) {
        return num1*num2;
    }

}

除法运算类ExcCalculator:

package com.jswang.calculator;

public class ExcCalculator implements ICalculator{

    @Override
    public double getResult(double num1, double num2) {
        if(num2!=0){
            return num1/num2;   
        }
        else{
            return Double.MAX_VALUE;
        }
    }

}

运算类工厂CalculatorFactory:

package com.jswang.factory;

import com.jswang.calculator.AddCalculator;
import com.jswang.calculator.ExcCalculator;
import com.jswang.calculator.ICalculator;
import com.jswang.calculator.MulCalculator;
import com.jswang.calculator.SubCalculator;
import com.jswang.calculatorenum.CalculatorName;

public class CalculatorFactory {
    public static ICalculator getCalculator(String calc) {

        ICalculator calculator = null;

        switch (CalculatorName.getCalcName(calc)) {
            case ADD:
                calculator = new AddCalculator();break;
            case SUB:
                calculator = new SubCalculator();break;
            case MUL:
                calculator = new MulCalculator();break;
            case EXC:
                calculator = new ExcCalculator();break;
            case UNKNOW:
                break;
        }

        return calculator;

    }
}

运算类名称枚举:CalculatorName:

package com.jswang.calculatorenum;

public enum CalculatorName {
    ADD, SUB, MUL, EXC, UNKNOW;

    public static CalculatorName getCalcName(String calc) {
        try {

            return valueOf(calc);

        }

        catch (Exception ex) {

            return UNKNOW;

        }

    }

}

客户端MainClass:

package com.jswang.main;

import java.util.Scanner;

import com.jswang.calculator.ICalculator;
import com.jswang.factory.CalculatorFactory;

public class MainClass {
    public static void main(String[] args) {
        double num1 = 0.0;
        double num2 = 0.0;
        String opt = "";

        Scanner scanner = new Scanner(System.in);
        System.out.println("输入 num1:");
        num1 = scanner.nextDouble();
        System.out.println("输入 num2:");
        num2 = scanner.nextDouble();
        System.out.println("输入 opt:");
        opt = scanner.next();
        scanner.close();

        // 简单工厂模式
        ICalculator calculator = CalculatorFactory.getCalculator(opt);
        if (null != calculator) {
            double res = calculator.getResult(num1, num2);
            System.out.println(res);
        } else {
            System.out.println("暂不支持 " + opt + " 运算符!");
        }

    }
}

执行结果:
两数相加(ADD):
这里写图片描述
两数相减(SUB):
这里写图片描述
两数相乘(MUL):
这里写图片描述
两数相除(EXC):
这里写图片描述

可能看完上述代码,会很困惑一点,就是明明只为了实现一个加减乘除运算,为什么要额外付出这么大的代价绕了好几个弯。其实这就要谈到设计模式里很重要的一个原则:开放–封闭原则。良好的面向对象设计,应该对扩展开放,而对修改尽量拒绝。也就是说一个软件系统,不应该在新的需求发生时,去大量的改动源代码,而是扩展新的代码,这样的系统才是健壮的,可维护的。

可能这么说还是假大空了,那就考虑上述的例子,如果将上面工厂类中的逻辑代码switch/case选择运算类的代码,放在MainClass中去,这意味着不再需要工程模式,也不需要抽象出运算类。业务逻辑全都放在客户端,当新的需求比如需要支持num1的num2次方时,需要在客户端进行改动,增加一个新的case分支。这就导致当不断的有新需求来临,客户端日益臃肿,而且客户端中任何一个算法出问题,都可能导致整个系统崩溃。

简单工厂模式,就是为了避免客户端和业务逻辑过于耦合而设计的。将业务逻辑都封装在相关的业务逻辑类中,工厂模式负责根据用户需求进行调度,产生相应的业务对象以供客户使用,这样当有了新的运算需求,仅仅需要新增一个运算类集成抽象运算类接口,并在工厂类中加一个分支即可,客户端无需知道细节,只需要按需要调用工厂产生所需的运算对象即可。各个算法类之间分离,即使出了问题也不会相互影响,这也是解耦的好处。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值