设计模式之简单工厂模式

最近在学习设计模式,主要通过阅读大话设计模式,来学习,学习之余,做一个学习笔记。
需求:编写一个计算器类。
最初设计:新建计算机类,封装两个数值类,按照MVC的思想去实现,dao层封装四个方法,分别是增删改查,在实现类中去实现,然后业务层判断客户端传来的具体数值,更具操作符不同,选择调用不同的Dao层方法。
代码:

    /**
 * @author 123
 *   计算器类
 */
public class Calc {

    private double numA;
    private 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;
    }
}
/**
 * @author 123
 *  Dao层方法
 */
public interface ICalcDao {
    double  add(Calc calc);
    double  subtraction(Calc calc);
    double  multiply(Calc calc);
    double  divide(Calc calc);
}
package calc;

/**
 * @author 123
 *  Dao层实现类
 */
public class CalcDaoImpl implements ICalcDao{

    @Override
    public double add(Calc calc) {
        // TODO Auto-generated method stub
        return calc.getNumA()+calc.getNumB();
    }

    @Override
    public double subtraction(Calc calc) {
        // TODO Auto-generated method stub
        return calc.getNumA()-calc.getNumB();
    }

    @Override
    public double multiply(Calc calc) {
        // TODO Auto-generated method stub
        return calc.getNumA()*calc.getNumB();
    }

    @Override
    public double divide(Calc calc) {
        // TODO Auto-generated method stub
        return calc.getNumA()/calc.getNumB();
    }

}
package calc;

/**
 * @author 123
 *  业务层接口
 */
public interface ICalcService {
  double result(double numA,double numB,String operator);
}
package calc;

/**
 * @author 123
 *  业务层实现类
 */
public class CalcServiceImpl implements ICalcService {

    @Override
    public double result(double numA, double numB, String operator) {
        // TODO Auto-generated method stub
        ICalcDao icalc = new CalcDaoImpl();
        Calc calc = new Calc();
        Double result = null;
        calc.setNumA(numA);
        calc.setNumB(numB);
        if ("+".equals(operator)) {

            result = icalc.add(calc);
        } else if ("-".equals(operator)) {

            result = icalc.subtraction(calc);
        } else if ("*".equals(operator)) {

            icalc.multiply(calc);
        } else if ("/".equals(operator)) {
           if(numB==0){
               System.out.println("除数不能为0");
               return -1;
           }
           result =icalc.divide(calc);
        } else {
           System.out.println("请输入正确的操作符类型");
           return -1;
        }

        return result;
    }
}
package calc;

import java.util.Scanner;
import static java.lang.System.*;

/**
 * @author 123
 * 客户端类
 */
public class Client {
        public static void main(String[] args) {
            double numA = 0;
            double numB = 0;
            String operator = null;
            try {
                Scanner sc = new Scanner(System.in);
                System.out.println("请输入需要运算的第一个数字");
                numA = sc.nextDouble();
                System.out.println("请输入需要运算的第二个数字");
                numB = sc.nextDouble();
                System.out.println("请输入需要运算的规则");
                operator = sc.next();
            } catch (Exception e) {
                // TODO Auto-generated catch block
                System.out.println("您输入的数字类型不合法");
                e.printStackTrace();
                exit(0);
            }
            ICalcService calcService = new CalcServiceImpl();
            double result = calcService.result(numA, numB, operator);
            System.out.println("结果为"+result);
        }
}

阅读设计模式后设计:
把操作封装成不同的类,新建抽象操作类,封装两个用于计算的遍历和一个用于得到结果抽象方法,新建加减乘除类继承操作类,实现得到结果类,新建工厂类,设置静态方法,返回值为抽象操作类,根据不同的操作符,新建不同的算术类(即加减乘除类 向上转型),然后在客户端里进行调用工厂类,得到抽象类,继而调用抽象类中抽象方法,但是因为是向上转型,子类中重写了父类的得到结果的方法,所以是调用了对应子类的方法,这里主要运用的是多态的思想,一句比较经典的话是向上转型,会遗忘子类中独有的方法,引用对像会调用父类独有的和子类重写父类的方法。
代码:

package calc2;

/**
 * @author 123
 * 操作类
 */
public   abstract class Operator {

    private double numA;
    private double numB;

    public abstract double result();

    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;
    }

}
package calc2;

/**
 * @author 123
 * 加法类
 */
public class Add extends Operator {

    @Override
    public double result() {
        // TODO Auto-generated method stub
        return getNumA() + getNumB();
    }

}

其他减法除法类类似。。。。。。。。。。。。

package calc2;

/**
 * @author 123
 * 工厂类
 */
public class CalcFactory {
    public static Operator getResult(String operator) {
        Operator opera = null;
        if ("+".equals(operator)) {
            opera = new Add();

        } else if ("-".equals(operator)) {
            opera = new Subtraction();
        } else if ("*".equals(operator)) {
            opera = new Multiply();
        } else if ("/".equals(operator)) {

            opera = new Divide();
        } 

        return opera;
    }
}
package calc2;

import java.util.Scanner;
import static java.lang.System.*;

/**
 * @author 123
 * 客户端类
 */
public class Client {
        public static void main(String[] args) {
            double numA = 0;
            double numB = 0;
            String operator = null;
            try {
                Scanner sc = new Scanner(System.in);
                System.out.println("请输入需要运算的第一个数字");
                numA = sc.nextDouble();
                System.out.println("请输入需要运算的第二个数字");
                numB = sc.nextDouble();
                System.out.println("请输入需要运算的规则");
                operator = sc.next();
            } catch (Exception e) {
                // TODO Auto-generated catch block
                System.out.println("您输入的数字类型不合法");
                e.printStackTrace();
                exit(0);
            }
            Operator operator2 = CalcFactory.getResult(operator);
            operator2.setNumA(numA);
            operator2.setNumB(numB);
            System.out.println("结果为"+operator2.result());
        }
}

两种方式比较,第一种,是惯用的MVC框架,虽然也运用到面向对象的思想,但是没有考虑到程序的扩展性,如果要增加其他算术方法,接口层和业务层都要有改动,改动面积大,但是感觉不是这样啊,即便是下面的简单工厂模式而言,如果增加一个根号运算,得在新加一个根号运算类,然后在工厂类里面增加相应的条件判断,这样看下来,二者都是要改动啊,而且改动看来也是差不多的,,,,,以后再慢慢体会吧

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值