java编写某计算器控制台程序_计算器 - 进阶的憨狗 - 博客园

源起

最近在看程杰著作的《大话设计模式》,全书以小菜和大鸟对话的形势,由浅入深的讲解程序的设计思想,影射出一个个设计模式。我之前虽然也使用过一些设计模式,但没有系统的学习、整理、总结,现从该书入手,拟补自己技术领域的一块空白。该书虽以C#语言为基础,但对Java程序猿来说,却不影响阅读。本专栏记录自己学习设计模式的过程及自己的认识,争取从小菜蜕变成大鸟。

定义

从设计模式的类型上来说,简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式。

需求

使用Java来编写一个计算器控制台程序,要求输入两个数和运算符号,得到结果。

实现

级别1

48304ba5e6f9fe08f3fa1abda7d326ab.png

1 import java.util.Scanner;

2

3 public class Operateion{

4

5 public static void main(String[] args) {

6 Scanner scanner = new Scanner(System.in);

7 try{

8 do{

9 System.out.println("输入数字A:");

10 double numA = scanner.nextDouble();

11 System.out.println("输入运算符(+、-、*、/):");

12 Stringoperate = scanner.next();

13 System.out.println("输入数字B:");

14 double numB = scanner.nextDouble();

15 double result = 0;

16 if(operate.equals("+"))

17 result = numA + numB;

18 else if (operate.equals("-"))

19 result = numA - numB;

20 else if (operate.equals("*"))

21 result = numA * numB;

22 else if (operate.equals("/") && numB != 0)

23 result = numA / numB;

24 else if (numB == 0)

25 System.err.println("除数不能为0!");

26 else

27 System.err.println("运算符输入有误!");

28 System.out.println("运算结果为:"+ result);

29 System.out.println("是否继续操作(Y/N):");

30 }while(!scanner.next().equalsIgnoreCase("n"));

31 }catch (RuntimeException e) {

32 System.err.println("程序发生异常退出!");

33 }

34 }

35 }

48304ba5e6f9fe08f3fa1abda7d326ab.png

上面的程序实现了最基本的四则运算,并对基本的异常进行了处理,还可以循环运算。假如说我别处也需要一个运算的程序,还需要再写一份,难复用。我们需要一份可以复用的代码!

级别2

48304ba5e6f9fe08f3fa1abda7d326ab.png

1 import java.util.Scanner;

2

3 public class Operation {

4

5 /*客户端代码 */

6 public static void main(String[] args) {

7 Scanner scanner = new Scanner(System.in);

8 try{

9 do{

10 System.out.println("输入数字A:");

11 double numA = scanner.nextDouble();

12 System.out.println("输入运算符(+、-、*、/):");

13 String operate = scanner.next();

14 System.out.println("输入数字B:");

15 double numB = scanner.nextDouble();

16 double result = getResult(numA, numB, operate);

17 System.out.println("运算结果为:"+ result);

18 System.out.println("是否继续操作(Y/N):");

19 }while(!scanner.next().equalsIgnoreCase("n"));

20 }catch (RuntimeException e) {

21 System.err.println("程序发生异常退出!");

22 }

23 }

24

25 /*计算器代码 */

26 public static double getResult(double numA, double numB, String operate) {

27 doubleresult = 0;

28 if(operate.equals("+"))

29 result = numA + numB;

30 else if (operate.equals("-"))

31 result = numA - numB;

32 else if (operate.equals("*"))

33 result = numA * numB;

34 else if (operate.equals("/") && numB != 0)

35 result = numA / numB;

36 else if (numB == 0)

37 System.err.println("除数不能为0!");

38 else

39 System.err.println("运算符输入有误!");

40 returnresult;

41 }

42 }

48304ba5e6f9fe08f3fa1abda7d326ab.png

上面的程序将计算器的代码封装到一个方法中,供客户端调用,这样如果存在多个客户端,只需要调用这个方法即可,实现了代码的可复用。那么现在我们把这个工具类编译后,其他人就可以使用了,假如说现在需要添加一个新算法,求A的B次方,我们就需要修改这个类的源代码,在getResult中加入新的分支,然后重新编译,供客户端使用,难扩展。

级别3

48304ba5e6f9fe08f3fa1abda7d326ab.png

1 public abstract class Operation {

2

3 protected double numA;

4

5 protected double numB;

6

7 public double getNumA() {

8 return numA;

9 }

10

11 public void setNumA(double numA) {

12 this.numA = numA;

13 }

14

15 public double getNumB() {

16 return numB;

17 }

18

19 public void setNumB(double numB) {

20 this.numB = numB;

21 }

22

23 public abstract double getResult();

24 }

25

26

27 /* 加法 */

28 public class AddOperation extends Operation {

29

30 @Override

31 public double getResult() {

32 return numA + numB;

33 }

34

35 }

36

37

38 /* 减法 */

39 public class SubOperation extends Operation {

40

41 @Override

42 public double getResult() {

43 return numA - numB;

44 }

45

46 }

47

48

49 /* 乘法 */

50 public class MulOperation extends Operation {

51

52 @Override

53 public double getResult() {

54 return numA * numB;

55 }

56

57 }

58

59

60 /* 除法 */

61 public class DivOperation extends Operation {

62

63 @Override

64 public double getResult() {

65 if(numB == 0)

66 throw new RuntimeException("除数不能为0!");

67 return numA / numB;

68 }

69

70 }

48304ba5e6f9fe08f3fa1abda7d326ab.png

上面的代码先创建了一个抽象类Operation,然后创建了加减乘除四个子类,分别实现其运算方法,如果以后需要修改某种运算,只需要去修改相应的类即可,如果需要增加某种运算,只需要去实现Operation的getResult方法即可,那么,我们还需要一个创建运算类的工厂。

48304ba5e6f9fe08f3fa1abda7d326ab.png

1 public class OperationFactory {

2

3 public static Operation createOperation(String operate) {

4 Operation op = null;

5 if(operate == null)

6 throw new RuntimeException("运算符不能为空!");

7 else if(operate.equals("+"))

8 op = new AddOperation();

9 else if(operate.equals("-"))

10 op = new SubOperation();

11 else if(operate.equals("*"))

12 op = new MulOperation();

13 else if(operate.equals("/"))

14 op = new DivOperation();

15 else

16 throw new RuntimeException("运算符错误!");

17 return op;

18 }

19

20 }

48304ba5e6f9fe08f3fa1abda7d326ab.png

客户端代码

48304ba5e6f9fe08f3fa1abda7d326ab.png

1 public class OperationTest {

2

3 public static void main(String[] args) {

4 Operation op = null;

5 Scanner scanner = new Scanner(System.in);

6 try {

7 do {

8 System.out.println("输入数字A:");

9 double numA = scanner.nextDouble();

10 System.out.println("输入运算符(+、-、*、/):");

11 String operate = scanner.next();

12 System.out.println("输入数字B:");

13 double numB = scanner.nextDouble();

14

15 op = OperationFactory.createOperation(operate);

16 op.setNumA(numA);

17 op.setNumB(numB);

18

19 double result = op.getResult();

20 System.out.println("运算结果为:" + result);

21 System.out.println("是否继续操作(Y/N):");

22 } while(!scanner.next().equalsIgnoreCase("n"));

23 } catch (RuntimeException e) {

24 System.err.println("程序发生异常退出!");

25 e.printStackTrace();

26 }

27 }

28

29 }

48304ba5e6f9fe08f3fa1abda7d326ab.png

将创建对象的工作交给工厂负责,使客户端调用和运算类解耦,当我们更改运算类时,客户端代码不会收到影响,也不需要修改。同时将计算器程序中的多个分支判断拆成了各个类,当分支判断中逻辑过于复杂时,这样做是非常好的。使用面向对象语言的特性(封装、继承、多态),以优雅的方式解决了可复用、可维护、可扩展等问题。

UML

1352369520_6657.png

总结

一个小小的计算器程序竟然可以写的这么perfect,编程是一门技术,更是一门艺术。在编写代码的过程中,要牢记可复用、易维护、好扩展,这样,自己才能有所提高,才是真正的软件工程师。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值