《大话设计模式》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()这样的语句。
《大话设计模式》java实现:第一章-简单工厂模式的更多相关文章
- 第一章 简单工厂模式 及 UML中类图的表示方法
写一个简单计算器程序时,可以写一个操作类,然后加.减.乘.除操作分别继承它,复写操作计算结果的方法.写一个简单工厂类,通过输入的操作符,使用操作类来new一个相应的操作类的子类对象.这样,工厂就实例化 ...
- 设计模式之第2章-抽象工厂模式(Java实现)
设计模式之第2章-抽象工厂模式(Java实现) “上次是我的不对,贿赂作者让我先讲来着,不过老婆大人大人有大量,不与我计较,这次还让我先把上次未讲完的应用场景部分给补充上去,有妻如此,夫复何求.”(说 ...
- 第2章 简单工厂模式(Sample Factory)
原文 第2章 简单工厂模式(Sample Factory) 一般用到的场景:对象多次被实例引用,切有可能会发生变化 拿我们的简单三层举例子 先定义dal层 1 2 3 4 5 6 7 8 cl ...
- 大话设计模式C++实现-第1章-简单工厂模式
一.UML图 二.包括的角色 简单工厂模式包括三个角色: (1)工厂类Factory:工厂类是用来制造产品的. 因此,在Factory中有一个用于制造产品的Create函数或者Generate函数之类 ...
- Java 设计模式系列(二)简单工厂模式和工厂方法模式
Java 设计模式系列(二)简单工厂模式和工厂方法模式 实现了创建者和调用者的分离.分为:简单工厂模式.工厂方法模式.抽象工厂模式 简单工厂模式.工厂方法模式都很简单,就不详细介绍了. 一.简单工厂 ...
- 学习设计模式第二十七 - GoF之外简单工厂模式
示例代码来自<深入浅出设计模式>和<大话设计模式> 概述 简单工厂模式又被称为静态工厂模式,属于类的创建型模式.其实质是由一个工厂类根据传入的参量,动态决定应该创建出哪一个产品 ...
- (转)java反射机制及简单工厂模式
第一步,定义一个接口类 package factory.face; /** * 接口,为了保证返回的对象可以统一用 Product接受 * @author Administrator */ publi ...
- Javascript设计模式理论与实战:简单工厂模式
通常我们创建对象最常规的方法就是使用new关键字调用构造函数,这会导致对象之间的依赖性.工厂模式是一种有助于消除类之间依赖性的设计模式,它使用一个方法来决定要实例化哪一个类.本文详细介绍了简单工厂模式 ...
- 设计模式(C#)——02简单工厂模式
推荐阅读: 我的CSDN 我的博客园 QQ群:704621321 工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来.通俗来说,你只关心怎么用,不用关心怎么做 ...
- Java实验项目三——简单工厂模式
Program: 请采用采用简单工厂设计模式,为某个汽车销售店设计汽车销售系统,接口car至少有方法print(), 三个汽车类:宝马.奥迪.大众 (属性:品牌,价格),在测试类中根据客户要求购买的汽 ...
随机推荐
- java多线程之-自定义数据库连接池
1.背景 数据库链接池大家不陌生吧... 不多说了,直上代码... 2.连接池具体实现 1.jdbc链接的实例对象 /** * @author 姿势帝-博客园 * @address https://w ...
- 利用系统IO读取磁盘上指定BMP图片的宽和高,以及BMP图片的大小, 并输出到终端,要求图片名称通过命令行传递
/************************************************* * * file name:GetBmpInfo.c * author :momolyl@126. ...
- Java常用类——包装类 小白版个人推荐
包装类及自动装箱/拆箱 包装类是将Java中的八种基本数据类型封装成的类,所有数据类型都能很方便地与对应的包装类相互转换,以解决应用中要求使用数据类型,而不能使用基本数据类型的情况. int a = ...
- 网络问题mark
复杂且混乱的网络环境, 主内网是192.168.0.254(网关), 中间混杂无数网段 , 无数dhcp, 同时还有0段的外网(跟254没关系) 现在是有一台服务器 , 192.168.0.47 , ...
- 检测 NAT 类型
使用 pystun3 pystun3 是一个用于获取 NAT 类型和外部 IP 的 Python STUN 客户端 安装: pip install pystun3 使用: pystun3 结果: NA ...
- Linux/macOS 查看网络接口
Linux 显示网络设备的状态: $ nmcli device status DEVICE TYPE STATE CONNECTION enp0s5 ethernet connected Wired ...
- 【Java】之获取CSV文件数据以及获取Excel文件数据
一.获取CSV文件数据 import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Sheet; impor ...
- Python新手爬虫三:爬取PPT模板
爬取网站:第一PPT(http://www.1ppt.com/) 此网站真的良心 老样子,先上最后成功的源码(在D盘创建一个"D:\PPT"文件夹,直接将代码执行就可获取到PPT) ...
- JDK有用的新特性-Switch
目录 箭头表达式,新的 case 标签 yeild 返回值 Java Record Switch 的三个方面,参考: JEP 361 支持箭头表达式 支持 yied 返回值 支持 Java Recor ...
- 技术教程 —— 如何利用 SEI 实现音画同步?
摘要:利用 SEI 解决数据流录制回放过程中的音画不同步问题. 文|即构 Web SDK 开发团队 今年 6 月, ZEGO 即构科技推出了行业内首套数据流录制 PaaS 方案,打破传统录制服务 ...