Java设计模式之简单工厂模式实验(软件工程综合实践课程第二周)
实验目的
1 .理解软件设计的相关理论 ;
2 .理解面向对象设计原则;
实验内容
1 .简单工厂模式实验:
(1) 参考讲义上的代码,利用简单工厂模式完成计算器应用程序;
(2) 画出计算器程序简单工厂模式的 UML 图,理解各个类之间的关系;
2 .自行设计
(1) 自行设计一个父类和几个子类,利用简单工厂模式完成相应的功能;
文章目录
- 1 .简单工厂模式实验
- com.java.Entity包实现
- com.java.Entity包参考代码
- com.java.factory包实现
- com.java.factory包参考代码
- com.java.test包实现
- com.java.test包参考代码
- UML类图
- 运行结果:
- 项目结构
- 2 .自行设计
- 简单工厂模式设计方案:
- 简单工厂模式下相关参考代码
- com.java.Entity包参考代码
- com.java.Factory包参考代码
- com.java.test包参考代码
- 项目结构
- 运行结果
1 .简单工厂模式实验
题目要求大致是将Comupter_1.java文件使用简单工厂模式进行重构
原来的Comupter_1.java:
import java.util.Scanner;public class Computer_1 {public static void main(String[] args) {try{Scanner input =new Scanner(System.in);System.out.print("请输入数字A: ");String strNumberA = input.nextLine();System.out.print("请选择运算符号(+、-、*、/): ");String strOperate = input.nextLine();System.out.print("请输入数字B: ");String strNumberB = input.nextLine();String strResult = "";switch (strOperate){case "+":strResult = Double.toString( Double.valueOf(strNumberA) + Double.valueOf(strNumberB));break;case "-":strResult = Double.toString(Double.valueOf(strNumberA) - Double.valueOf(strNumberB));break;case "*":strResult = Double.toString(Double.valueOf(strNumberA) / Double.valueOf(strNumberB));break;case "/":if (Double.valueOf(strNumberB) != 0)strResult = Double.toString( Double.valueOf(strNumberA) / Double.valueOf(strNumberB));elsestrResult = "除数不能为零";break;}System.out.println("结果是" + strResult);}catch (Exception e){System.out.println("除数不能为零");}}
}
原来的java文件“客户端”(输入数字和符号)和“服务端”(具体的运算)都堆在一起,耦合度较高,不够优雅
因此运用继承,多态,简单工厂模式等对该代码进行重构,使其耦合度降低,更易于维护
com.java.Entity包实现
首先为“加减乘除”四种运算创建不同的子类继承父类Com
各个子类重写父类的getResult()方法用于对数字进行不同运算返回结果
com.java.Entity包参考代码
com.java.Entity.Com.java(父类)
package com.java.Entity;/*** @projectName: x* @package: com.java.Entity* @className: Com* @author: GCT* @description: TODO* @date: 2022/9/7 17:12* @version: 1.0*/
public class Com {private String strNumberA;private String strNumberB;public String getStrNumberA() {return strNumberA;}public void setStrNumberA(String strNumberA) {this.strNumberA = strNumberA;}public String getStrNumberB() {return strNumberB;}public void setStrNumberB(String strNumberB) {this.strNumberB = strNumberB;}public String getResult(){return "";}
}
com.java.Entity.AddCal.java(加法):
package com.java.Entity;/*** @projectName: x* @package: com.java.Entity* @className: AddCal* @author: GCT* @description: TODO* @date: 2022/9/7 17:18* @version: 1.0*/
public class AddCal extends Com{@Overridepublic String getResult() {return Double.toString( Double.valueOf(getStrNumberA()) + Double.valueOf(getStrNumberB()));}
}
com.java.Entity.MinusCal.java(减法):
package com.java.Entity;/*** @projectName: g* @package: com.java.Entity* @className: MinusCal* @author: GCT* @description: TODO* @date: 2022/9/7 17:18* @version: 1.0*/
public class MinusCal extends Com{@Overridepublic String getResult() {return Double.toString( Double.valueOf(getStrNumberA()) - Double.valueOf(getStrNumberB()));}
}
com.java.Entity.MultiCal.java
package com.java.Entity;/*** @projectName: g* @package: com.java.Entity* @className: MultiCal* @author: GCT* @description: TODO* @date: 2022/9/7 17:18* @version: 1.0*/
public class MultiCal extends Com{@Overridepublic String getResult() {return Double.toString( Double.valueOf(getStrNumberA()) * Double.valueOf(getStrNumberB()));}
}
com.java.Entity.DevideCal.java
package com.java.Entity;/*** @projectName: g* @package: com.java.Entity* @className: DevideCal* @author: GCT* @description: TODO* @date: 2022/9/7 17:19* @version: 1.0*/
public class DevideCal extends Com{@Overridepublic String getResult() {if (Double.valueOf(getStrNumberB()) != 0){return Double.toString( Double.valueOf(getStrNumberA()) / Double.valueOf(getStrNumberB()));}else {return "除数不能为零";}}
}
com.java.factory包实现
核心思想:
然后是工厂类ComFactory,编写返回Com类型的getCalObj方法,之所以要返回Com类型,是因为Com类型是加减乘除四个子类的父类,因此可以新建一个Com()的实例com,然后根据传入不同的运算符为com设置该运算符对应的运算子类,最终return com,返回的com在set了numberA和numberB后,使用getResult即可返回对应运算后的结果(运用到了多态的思想,将子类向上转型)
com.java.factory包参考代码
com.java.factory.ComFactory.java
package com.java.factory;import com.java.Entity.*;/*** @projectName: z* @package: com.java.factory* @className: ComFactory* @author: GCT* @description: TODO* @date: 2022/9/7 17:13* @version: 1.0*/
public class ComFactory {// 用了多态的思想public static Com getCalObj(String strOperate){Com com = new Com();switch (strOperate){case "+":com = new AddCal();break;case "-":com = new MinusCal();break;case "*":com = new MultiCal();break;case "/":com = new DevideCal();break;}return com;}
}
com.java.test包实现
这个就是在终端接收输入和结果输出的代码,注意对于分母为0情况的输出(见注释)
com.java.test包参考代码
com.java.test.Computer_test.java
package com.java.test;import com.java.Entity.Com;
import com.java.Entity.DevideCal;
import com.java.factory.ComFactory;import java.util.Scanner;/*** @projectName: g* @package: com.java.test* @className: Computer_test* @author: GCT* @description: TODO* @date: 2022/9/7 17:12* @version: 1.0*/
public class Computer_test {public static void main(String[] args) {try{Scanner input =new Scanner(System.in);System.out.print("请输入数字A: ");String strNumberA = input.nextLine();System.out.print("请选择运算符号(+、-、*、/): ");String strOperate = input.nextLine();System.out.print("请输入数字B: ");String strNumberB = input.nextLine();
// String strResult = "";Com calObj = ComFactory.getCalObj(strOperate);calObj.setStrNumberA(strNumberA);calObj.setStrNumberB(strNumberB);String strResult = calObj.getResult();
// switch (strOperate)
// {// case "+":
// strResult = Double.toString( Double.valueOf(strNumberA) + Double.valueOf(strNumberB));
// break;
// case "-":
// strResult = Double.toString(Double.valueOf(strNumberA) - Double.valueOf(strNumberB));
// break;
// case "*":
// strResult = Double.toString(Double.valueOf(strNumberA) * Double.valueOf(strNumberB));
// break;
// case "/":
// if (Double.valueOf(strNumberB) != 0)
// strResult = Double.toString( Double.valueOf(strNumberA) / Double.valueOf(strNumberB));
// else
// strResult = "除数不能为零";
// break;
// }if (strResult.equals("除数不能为零")){// 对分母为0的情况的处理方法:
// 若分母为0,DevideCal中会返回"除数不能为零"字符串,而不进行除法运算
// 1、手动抛出一个异常让程序捕获,从而跳到catch中输出"除数不能为零" throw new Exception();
// 2、直接输出"除数不能为零" System.out.println("除数不能为零");// throw new Exception();System.out.println("除数不能为零");}else{System.out.println("结果是" + strResult);}}catch (Exception e){System.out.println("除数不能为零");}}
}
UML类图
运行结果:
项目结构
2 .自行设计
需求描述: 一个模拟买卖披萨的项目:要便于披萨种类的扩展,便于维护
l)披萨的种类很多(比如ChinesePizza、GreekPizza,MexicoPizza等)
2)披萨的制作有prepare,bake,cut,box等步骤 3)完成披萨店订购功能。
首先看看传统方式:
传统方式的优缺点:
1)优点是比较好理解,简单易操作。
2)缺点是违反了设计模式的ocp原则,即对扩展开放,对修改关闭。即当我们给类增加新功能的时候,尽量不修 改代码,或者尽可能少修改代码,
例如:我们这时要新增加一个Pizza的种类,只要是订购Pizza的代码都需要修改,可维护性和拓展性等不佳 4)改进的思路分析
3)分析:修改代码可以接受,但是如果我们在其它的地方也有创建Pizza的代码,就意味着,也需要修改,而创建Pizz 的代码,往往有多处。
思路:把创建Pizza对象封装到一个类中,这样我们有新的Pizza种类时,只需要修改该类就可,其它有创建到Pizza对象的代码就不需要修改了—>简单工厂模式
简单工厂模式设计方案:
简单工厂模式下相关参考代码
com.java.Entity包参考代码
com.java.Entity.Pizza.java(父类):
package com.java.Entity;/*** @projectName: g* @package: com.java.Entity* @className: Pizza* @author: GCT* @description: TODO* @date: 2022/9/7 19:41* @version: 1.0*///将Pizza类做成抽象父类
public abstract class Pizza {protected String name;//准备原材料, 不同的披萨不一样,因此做成抽象方法public abstract void prepare();public void bake() {System.out.println(name + "正在烘焙中....");}public void cut() {System.out.println(name + "正在切割中....");}//打包public void box() {System.out.println(name + "正在打包中....");}public void done(){System.out.println(name+ "已完成!");}public void setName(String name) {this.name = name;}
}
com.java.Entity.ChinesePizza.java:
package com.java.Entity;/*** @projectName: g* @package: com.java.Entity* @className: ChinesePizza* @author: GCT* @description: TODO* @date: 2022/9/7 19:40* @version: 1.0*/public class ChinesePizza extends Pizza {@Overridepublic void prepare() {System.out.println("正在准备中国披萨.....");}}
com.java.Entity.GreekPizza.java:
package com.java.Entity;/*** @projectName: g* @package: com.java.Entity* @className: GreekPizza* @author: GCT* @description: TODO* @date: 2022/9/7 19:40* @version: 1.0*/public class GreekPizza extends Pizza {@Overridepublic void prepare() {System.out.println("正在准备希腊披萨.....");}}
com.java.Entity.MexicoPizza.java:
package com.java.Entity;/*** @projectName: g* @package: com.java.Entity* @className: MexicoPizza* @author: GCT* @description: TODO* @date: 2022/9/7 19:41* @version: 1.0*/public class MexicoPizza extends Pizza {@Overridepublic void prepare() {System.out.println("正在准备墨西哥披萨.....");}}
com.java.Factory包参考代码
com.java.Factory.SimpleFactory.java:(工厂类)
package com.java.Factory;/*** @projectName: g* @package: com.java.Factory* @className: SimpleFactory* @author: GCT* @description: TODO* @date: 2022/9/7 19:43* @version: 1.0*/import com.java.Entity.ChinesePizza;
import com.java.Entity.GreekPizza;
import com.java.Entity.MexicoPizza;
import com.java.Entity.Pizza;//简单工厂类
public class SimpleFactory {//更加orderType 返回对应的Pizza 对象public Pizza createPizza(String orderType) {Pizza pizza = null;System.out.println("正在使用简单工厂模式1");if (orderType.equals("greek")) {pizza = new GreekPizza();pizza.setName(" 希腊披萨");} else if (orderType.equals("cheese")) {pizza = new ChinesePizza();pizza.setName(" 奶酪披萨 ");} else if (orderType.equals("pepper")) {pizza = new MexicoPizza();pizza.setName("胡椒披萨");}return pizza;}//简单工厂模式 也叫 静态工厂模式public static Pizza createPizza2(String orderType) {Pizza pizza = null;System.out.println("正在使用简单工厂模式2(createPizza2为静态方法)");if (orderType.equals("Greek")) {pizza = new GreekPizza();pizza.setName("希腊披萨");} else if (orderType.equals("Chinese")) {pizza = new ChinesePizza();pizza.setName("中国披萨");} else if (orderType.equals("Mexico")) {pizza = new MexicoPizza();pizza.setName("墨西哥披萨");}return pizza;}}
com.java.test包参考代码
com.java.test.OrderPizza.java:
package com.java.test;/*** @projectName: g* @package: com.java.test* @className: OrderPizza* @author: GCT* @description: TODO* @date: 2022/9/7 19:44* @version: 1.0*/import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;import com.java.Entity.Pizza;
import com.java.Factory.SimpleFactory;public class OrderPizza {// 构造器
// 不使用简单工厂模式
// public OrderPizza() {// Pizza pizza = null;
// String orderType; // 订购披萨的类型
// do {// orderType = getType();
// if (orderType.equals("Greek")) {// pizza = new GreekPizza();
// pizza.setName("希腊披萨");
// } else if (orderType.equals("Chinese")) {// pizza = new ChinesePizza();
// pizza.setName("中国披萨");
// } else if (orderType.equals("Mexico")) {// pizza = new MexicoPizza();
// pizza.setName("墨西哥披萨");
// }
// else {// break;
// }
// //输出pizza 制作过程
// pizza.prepare();
// pizza.bake();
// pizza.cut();
// pizza.box();
// pizza.done();
//
// } while (true);
// }//定义一个简单工厂对象SimpleFactory simpleFactory;Pizza pizza = null;//构造器public OrderPizza(SimpleFactory simpleFactory) {setFactory(simpleFactory);}public void setFactory(SimpleFactory simpleFactory) {String orderType = ""; //用户输入的类型this.simpleFactory = simpleFactory; //设置简单工厂对象do {orderType = getType();pizza = this.simpleFactory.createPizza(orderType);//输出pizzaif(pizza != null) { //订购成功pizza.prepare();pizza.bake();pizza.cut();pizza.box();pizza.done();} else {System.out.println("订购披萨失败");break;}}while(true);}// 写一个方法,让用户输入订购披萨的种类private String getType() {try {Scanner input =new Scanner(System.in);System.out.print("请输入pizza的种类(Chinese,Greek,Mexico):");String str = input.nextLine();return str;} catch (Exception e) {e.printStackTrace();return "";}}}
com.java.test.OrderPizza2.java:
package com.java.test;/*** @projectName: g* @package: com.java.test* @className: OrderPizza2* @author: GCT* @description: TODO* @date: 2022/9/7 19:44* @version: 1.0*/import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;import com.java.Entity.Pizza;
import com.java.Factory.SimpleFactory;public class OrderPizza2 {Pizza pizza = null;String orderType = "";// 构造器public OrderPizza2() {do {orderType = getType();pizza = SimpleFactory.createPizza2(orderType);// 输出pizzaif (pizza != null) { // 订购成功pizza.prepare();pizza.bake();pizza.cut();pizza.box();pizza.done();} else {System.out.println(" 订购披萨失败 ");break;}} while (true);}// 写一个方法,可以获取客户希望订购的披萨种类private String getType() {try {Scanner input =new Scanner(System.in);System.out.print("请输入pizza的种类(Chinese,Greek,Mexico):");String str = input.nextLine();return str;} catch (Exception e) {e.printStackTrace();return "";}}
}
com.java.test.PizzaStore.java:
package com.java.test;/*** @projectName: g* @package: com.java.test* @className: PizzaStore* @author: GCT* @description: TODO* @date: 2022/9/7 19:44* @version: 1.0*///相当于一个客户端,发出订购
public class PizzaStore {public static void main(String[] args) {// 不使用简单工厂模式//new OrderPizza();//使用简单工厂模式1
// new OrderPizza(new SimpleFactory());
// System.out.println("程序已退出");//使用简单工厂模式2(createPizza2为静态方法)new OrderPizza2();}}
项目结构
运行结果
Java设计模式之简单工厂模式实验(软件工程综合实践课程第二周)相关推荐
- Java设计模式之 简单工厂模式和工厂方法实验报告书
目录 Java设计模式之 1 简单工厂模式和工厂方法实验报告书 1 实验四:简单工厂模式和工厂方法 2 一.实验目的 2 二.实验内容 2 三.实验步骤 2 3.1简单工厂模式:女娲 2 3.2简单工 ...
- Java设计模式之简单工厂模式(Simple Factory)
[Java与模式]简单工厂模式(Simple Factory---吴义) 首先说明,Java与模式一系列的文章均是参考阎宏博士的<Java与模式>一书,加上自身的一些体会的探索,产生如下文 ...
- Java设计模式之 抽象工厂模式实验报告书
目录 Java设计模式之 1 抽象工厂模式实验报告书 1 实验四:抽象工厂模式 2 一.实验目的 2 二.实验内容 2 三.实验步骤 2 3.1抽象工厂模式:电器工厂 2 3.2 car 6 3.3 ...
- java设计模式之简单工厂模式
定义: 由一个工厂对象决定创建出哪一种产品类的实例 类型:属于创建型,但不属于GOF23中设计模式 工厂模式分为三种: 1.简单工厂模式(静态工厂方法模式) 2.工厂方法模式(多态性工厂模式) 3.抽 ...
- java设计模式:简单工厂模式
一.什么是简单工厂模式 简单工厂模式属于类的创建型模式,又叫做静态工厂方法模式.通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类. 二.简单工厂模式的角色和职责 1.工厂(C ...
- JAVA设计模式笔记(简单工厂模式)
有一个水果加工工厂,我们的需求是实现加工水果的功能.常见的做法是创建一个水果抽象类,写一个抽象的加工方法,然后创建具体的水果类去继承抽象类,再去实现抽象方法,最后客户端再去新建对象实例. public ...
- 设计模式之工厂方法模式、抽象工厂模式的概念和实现及使用“反射技术+读取配置文件”的方法对工厂模式进行改进(软件工程综合实践课程第三周个人作业)
文章目录 一.实验目的 二.知识总结 1.工厂方法模式简介 2.抽象工厂模式简介 3.工厂模式小结 4.利用"反射技术+读取配置文件"的方法改进程序 三.实验内容 1. 工厂模式实 ...
- 工厂模式 java场景_研磨设计模式之简单工厂模式(场景问题)
简单工厂不是一个标准的设计模式,但是它实在是太常用了,简单而又神奇,所以还是需要好好掌握的,就当是对学习设计模式的热身运动吧.为了保持一致性,我们尽量按照学习其它模式的步骤来进行学习. 1 场景问题 ...
- 设计模式之简单工厂模式(Java 实现)
设计模式之简单工厂模式(Java 实现) 本文首发于http://www.imooc.com/wiki/Designlesson/factory.html 简单工厂模式是平时开发过程中最常见的设计模式 ...
最新文章
- 基于图像的三维模型重建——稠密点云重建
- IEC61850电能质量1~50次谐波有效值建模
- 那些年我们程序员欠下的技术债
- 厉害了!不用一行代码,手把手教你制作漂亮词云!
- springboot web 服务器选择
- 数据缺失的补充与修改
- 信息学奥赛一本通(1410:最大质因子序列)
- linux怎么查看数据库性能,正确评估SQL数据库性能,你必须知道的原理和方法!...
- 双蓝牙(HC-05、HC-06)AT指令配对教程
- T3及报税软件报表使用无线打印机打印凭证没反应
- PDF文件如何旋转页面保存
- Windows批处理学习(一)——MS-DOS命令
- 小仙女讲JVM(1)—综述
- 黑马程序员JAVAEE企业级开发应用教程笔记
- juniper官网相关网址
- JavaSSM笔记(二)SpringMvc基础
- 基于传感器时钟跟踪的ADS-B异常和入侵的检测
- mp4视频无法播放的解决方法
- Mac上制作Centos7系统U盘安装盘
- 在字符串中查找子字符串
热门文章
- 二进制差分码规则_一篇文章弄明白Node.js与二进制数据流
- 视源股份(CVTE)亮相世界顶级计算机视觉盛会CVPR 2017
- zuul 详解,带视频
- 基础实验8-1.2 直捣黄龙 (Dijkstra算法)
- 【转载】人体经络图(详细图片、清晰穴位)
- 日本“妻子机器人”爆火,除了不能生孩子,拥有3项“专属服务
- 专访陈勇: 敏捷开发现状及发展之路
- 好!好!好! 好文章!
- 拼多多成于“性价比”,困于“性价比”
- Double precision