《大话设计模式》java实现:第一章-简单工厂模式

在《大话设计模式》中,示例代码使用C#实现,所以我这里使用Java实现一遍书中的设计模式。

第一章是使用简单工厂实现计算器。

遇到了一个问题:在Operation父类中,我们可以定义两个操作数作为成员变量,在类初始化时直接传参,那么GetResult()函数可以直接调用成员变量返回值,而不需要再次传参。也可以不定义成员变量,而是在调用GetRsult()时再传参。那么该如何选择?

  1. 使用成员变量:需要设置每一个运算子类的初始化函数,并修改工厂类,在工厂类初始化运算类的时候传入两个操作数和运算符。初始化函数这部分都是重复的,且需要额外的空间存储运算符。
package gof;

import java.util.Scanner;

/*
 * 《大话设计模式》第一章,简单工厂制作计算器
 */

public class SimpleFactory {
	public static void main(String[] args) {
		try (//用户界面
		Scanner input = new Scanner(System.in)) {
			System.out.printf("请输入数字1:");
			double number1=input.nextDouble();
			System.out.printf("请输入运算符:");
			String operator=input.next();
			System.out.printf("请输入数字2:");
			double number2=input.nextDouble();
			
			System.out.printf("请输入使用哪一个操作:\n1.简单封装\n2.简单工厂模式\n");
			int choose=input.nextInt();
			switch (choose) {
			case 1: {
				System.out.printf("答案是:"+simpleEncapsulation(number1, number2, operator));
				return;
			}
			case 2:{
				System.out.printf("答案是:"+polymorphsimOperation(number1, number2, operator));
				return;
			}
			default:
				throw new IllegalArgumentException("没有这个选项: " + choose);
			}
			
		}
	}
	
	//使用简单封装
	static double simpleEncapsulation(double number1, double number2, String operator) {
		return OperationEncapsulation.getResult(number1, number2, operator);
	}
	
	//使用简单工厂模式
	static double polymorphsimOperation(double number1, double number2, String operator) {
		Operation operation=OperationFactory.getOperation(number1,number2,operator);
		try {
			return operation.getResult();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return -1;
	}
}

/*
 * 1.使用客户端与操作分离,简单封装
 */
class OperationEncapsulation{
	public static double getResult(double number1, double number2, String operator) {
		switch (operator) {
		case "+": {
			return number1+number2;
		}
		case "-":{
			return number1-number2;
		}
		case "*":{
			return number1*number2;
		}
		case "/":{
			if(number2!=0) return number1+number2;
		}
		default:
			System.out.println("非法运算符:"+operator);
			//throw new IllegalArgumentException("非法运算符:" + operator);
		}
		return 0;
	}
}

/*
 * 2. 封装,继承,多态
 * 使用简单工厂解决多态带来的如何实例化指定类的问题
 */

//父类
abstract class Operation{
	double number1;
	double number2;
	//String operator;
	
	public Operation(double number1, double number2) {
		this.number1=number1;
		this.number2=number2;
	}	
	
	public double getNumber1() {
		return number1;
	}
	public void setNumber1(double number1) {
		this.number1 = number1;
	}
	public double getNumber2() {
		return number2;
	}
	public void setNumber2(double number2) {
		this.number2 = number2;
	}
	
	abstract double getResult();
}

// 加减乘除类
class OperationAdd extends Operation{
	public OperationAdd(double number1, double number2) {
		super(number1, number2);
	}

	public double getResult() {
		return number1+number2;
	}
}

class OperationSub extends Operation{
	public OperationSub(double number1, double number2) {
		super(number1, number2);
	}

	public double getResult() {
		return number1-number2;
	}
}

class OperationMul extends Operation{
	public OperationMul(double number1, double number2) {
		super(number1, number2);
	}

	public double getResult() {
		return number1*number2;
	}
}

class OperationDiv extends Operation{
	public OperationDiv(double number1, double number2) {
		super(number1, number2);
	}

	public double getResult() {
		if (number2==0) {
		   return 0;
		}
		return number1/number2;
	}
}

//简单工厂类,判断实例化哪一个子类
class OperationFactory{
	static Operation getOperation(Double number1, Double number2, String operator) {
		switch (operator) {
		case "+": {
			return new OperationAdd(number1,number2);
		}
		case "-": {
			return new OperationSub(number1,number2);
		}
		case "*": {
			return new OperationMul(number1,number2);
		}
		case "/": {
			return new OperationDiv(number1,number2);
		}
		default:
			System.out.println("非法运算符:"+operator);
			//throw new IllegalArgumentException("非法运算符: " + operator);
		}
		return null;
	}
}
  1. 不使用成员变量:重复的代码会大幅减少,每个运算类只需要定义GetResult(),但是客户端调用GetResult()的时候需要传两次参,原本只需要把全部参数交给工厂类,只传一次参。
package gof;

import java.util.Scanner;

/*
 * 《大话设计模式》第一章,简单工厂制作计算器
 */

public class SimpleFactory {
	public static void main(String[] args) {
		try (//用户界面
		Scanner input = new Scanner(System.in)) {
			System.out.printf("请输入数字1:");
			double number1=input.nextDouble();
			System.out.printf("请输入运算符:");
			String operator=input.next();
			if (operator!="+"&&operator!="-"&&operator!="*"&&operator!="/") {
				System.out.printf("运算符非法,重新输入运算符:");
				operator=input.next();
			}
			System.out.printf("请输入数字2:");
			double number2=input.nextDouble();
			
			System.out.printf("请输入使用哪一个操作:\n1.简单封装\n2.简单工厂模式\n");
			int choose=input.nextInt();
			switch (choose) {
			case 1: {
				System.out.printf("答案是:"+simpleEncapsulation(number1, number2, operator));
				return;
			}
			case 2:{
				System.out.printf("答案是:"+polymorphsimOperation(number1, number2, operator));
				return;
			}
			default:
				throw new IllegalArgumentException("没有这个选项: " + choose);
			}
			
		}
	}
	
	//使用简单封装
	static double simpleEncapsulation(double number1, double number2, String operator) {
		return OperationEncapsulation.getResult(number1, number2, operator);
	}
	
	//使用简单工厂模式
	static double polymorphsimOperation(double number1, double number2, String operator) {
		Operation operation=OperationFactory.getOperation(operator);
		try {
			return operation.getResult(number1, number2);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return -1;
	}
}

/*
 * 1.使用客户端与操作分离,简单封装
 */
class OperationEncapsulation{
	public static double getResult(double number1, double number2, String operator) {
		switch (operator) {
		case "+": {
			return number1+number2;
		}
		case "-":{
			return number1-number2;
		}
		case "*":{
			return number1*number2;
		}
		case "/":{
			if(number2!=0) return number1+number2;
		}
		default:
			//System.out.println("非法运算符:"+operator);
			throw new IllegalArgumentException("非法运算符:" + operator);
		}
	}
}

/*
 * 2. 封装,继承,多态
 * 使用简单工厂解决多态带来的如何实例化指定类的问题
 */

//父类
abstract class Operation{
	abstract double getResult(double number1, double number2);
}

// 加减乘除类
class OperationAdd extends Operation{
	public double getResult(double number1, double number2) {
		return number1+number2;
	}
}

class OperationSub extends Operation{
	public double getResult(double number1, double number2) {
		return number1-number2;
	}
}

class OperationMul extends Operation{
	public double getResult(double number1, double number2) {
		return number1*number2;
	}
}

class OperationDiv extends Operation{
	public double getResult(double number1, double number2) {
		if (number2==0) {
		   return 0;
		}
		return number1/number2;
	}
}

//简单工厂类,判断实例化哪一个子类
class OperationFactory{
	static Operation getOperation(String operator) {
		switch (operator) {
		case "+": {
			return new OperationAdd();
		}
		case "-": {
			return new OperationSub();
		}
		case "*": {
			return new OperationMul();
		}
		case "/": {
			return new OperationDiv();
		}
		default:
			System.out.println("非法运算符:"+operator);
			throw new IllegalArgumentException("非法运算符: " + operator);
		}
	}
}

工厂类解耦代码,使得增加和修改功能变得方便。但是客户端调用的时候需要额外再调用一次工厂类,调用工厂类实质上替换了new Operation()这样的语句。

posted @   米小白  阅读(43)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示