《大话设计模式》java实现:第一章-简单工厂模式
1.《大话设计模式》java实现:第二章-策略模式
2.《大话设计模式》java实现:第一章-简单工厂模式
在《大话设计模式》中,示例代码使用C#实现,所以我这里使用Java实现一遍书中的设计模式。
第一章是使用简单工厂实现计算器。
遇到了一个问题:在Operation父类中,我们可以定义两个操作数作为成员变量,在类初始化时直接传参,那么GetResult()函数可以直接调用成员变量返回值,而不需要再次传参。也可以不定义成员变量,而是在调用GetRsult()时再传参。那么该如何选择?
- 使用成员变量:需要设置每一个运算子类的初始化函数,并修改工厂类,在工厂类初始化运算类的时候传入两个操作数和运算符。初始化函数这部分都是重复的,且需要额外的空间存储运算符。
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;
}
}
- 不使用成员变量:重复的代码会大幅减少,每个运算类只需要定义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()这样的语句。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)