研磨设计模式day09原型模式

目录

场景

代码实现

有何问题

解决方案

代码改造 

模式讲解

原型与new

原型实例与克隆出来的实例

浅度克隆和深度克隆

原型模式的优缺点

思考

何时选用?

相关模式 


场景

代码实现

定义订单接口 

package com.zsp.bike.day08原型模式;/*** 订单的接口*/
public interface OrderApi {/*** 获取订单数量* @return*/public int getOrderProductNum();/*** 设置订单产品数量* @param num 订单产品数量*/public void setOrderProductNum(int num);
}

个人订单实现

package com.zsp.bike.day08原型模式;/*** 个人订单对象*/
public class PersonalOrder implements OrderApi{/*** 订购人员姓名*/private String customerName;/*** 产品编号*/private String productId;/*** 订单产品数量*/private int orderProductNum = 0;@Overridepublic int getOrderProductNum() {return this.orderProductNum;}@Overridepublic void setOrderProductNum(int num) {this.orderProductNum = num;}@Overridepublic String toString() {return "PersonalOrder{" +"customerName='" + customerName + '\'' +", productId='" + productId + '\'' +", orderProductNum=" + orderProductNum +'}';}public String getCustomerName() {return customerName;}public void setCustomerName(String customerName) {this.customerName = customerName;}public String getProductId() {return productId;}public void setProductId(String productId) {this.productId = productId;}}

企业订单实现

package com.zsp.bike.day08原型模式;/*** 企业订单对象*/
public class EnterpriseOrder implements OrderApi{/*** 企业名称*/private String enterpriseName;/*** 产品编号*/private String productId;/*** 订单产品数量*/private int orderProductNum = 0;@Overridepublic int getOrderProductNum() {return this.orderProductNum;}@Overridepublic void setOrderProductNum(int num) {this.orderProductNum = num;}public String getEnterpriseName() {return enterpriseName;}public void setEnterpriseName(String enterpriseName) {this.enterpriseName = enterpriseName;}public String getProductId() {return productId;}public void setProductId(String productId) {this.productId = productId;}@Overridepublic String toString() {return "EnterpriseOrder{" +"enterpriseName='" + enterpriseName + '\'' +", productId='" + productId + '\'' +", orderProductNum=" + orderProductNum +'}';}
}

通用的订单处理

package com.zsp.bike.day08原型模式;/*** 处理订单的业务对象*/
public class OrderBusiness {/*** 创建订单的方法* @param order 订单的接口对象*/public void saveOrder(OrderApi order){// 业务要求,当订单数量大于1000,把订单分成两份订单//1.判断产品数量是否大于1000while (order.getOrderProductNum() > 1000){// 2.如果大于,还需要继续拆分// 2.1 再新建一份订单,跟传入的订单除了数量不一样外,其他都相同OrderApi newOrder = null;// 如果属于个人订单if (order instanceof PersonalOrder){// 创建相应的新的订单对象PersonalOrder p2 = new PersonalOrder();// 然后进行赋值,但是产品数量为1000PersonalOrder p1 = (PersonalOrder)order;p2.setCustomerName(p1.getCustomerName());p2.setProductId(p1.getProductId());p2.setOrderProductNum(1000);// 再设置给newOrdernewOrder = p2;// 如果属于企业订单    }else if(order instanceof EnterpriseOrder){// 创建相应的订单对象EnterpriseOrder e2 = new EnterpriseOrder();// 然后进行赋值,但是产品数量为1000EnterpriseOrder e1 = (EnterpriseOrder)order;e2.setEnterpriseName(e1.getEnterpriseName());e2.setProductId(e1.getProductId());e2.setOrderProductNum(1000);// 再设置给newOrdernewOrder = e2;}// 2.2 原来的订单保留,把数量设置成减少1000order.setOrderProductNum(order.getOrderProductNum() - 1000);// 然后是业务功能处理,省略了,打印输出看一下System.out.println("拆分生成订单==" + newOrder);}//3.不超过1000,那就直接业务功能处理,省略了,打印输出看一下System.out.println("订单==" + order);}
}

客户端使用

package com.zsp.bike.day08原型模式;public class Client {public static void main(String[] args) {// 创建订单对象,这里为了演示,直接new了PersonalOrder op = new PersonalOrder();// 设置订单数据op.setOrderProductNum(2925);op.setProductId("P0001");op.setCustomerName("张三");// 这里获取业务处理的类,也直接new了OrderBusiness ob = new OrderBusiness();ob.saveOrder(op);}
}

有何问题

 简述:

1.订单处理的对象太过依赖与具体实现,划分的很细。

2.如果要增加一种新类型订单,就要增加新的订单类型支持,就要修改这个订单处理逻辑。

解决方案

原型模式

定义:

解决思路:

代码改造 

1.在订单接口里面写一个克隆自己的方法

package com.zsp.bike.day08原型模式;/*** 订单的接口*/
public interface OrderApi {/*** 获取订单数量* @return*/public int getOrderProductNum();/*** 设置订单产品数量* @param num 订单产品数量*/public void setOrderProductNum(int num);/*** 克隆方法* @return 订单原型的实例*/public OrderApi cloneOrder();
}

2.如何克隆?

千万不能return this;这么做客户端获取的都是同一个实例,都是指向同一个内存空间的,对克隆出来的对象实例进行修改会影响到原型对象实例。

 应该新建一个实例,把所有属性的值复制到新实例中。

个人订单对象修改

package com.zsp.bike.day08原型模式;/*** 个人订单对象*/
public class PersonalOrder implements OrderApi{/*** 订购人员姓名*/private String customerName;/*** 产品编号*/private String productId;/*** 订单产品数量*/private int orderProductNum = 0;@Overridepublic int getOrderProductNum() {return this.orderProductNum;}@Overridepublic void setOrderProductNum(int num) {this.orderProductNum = num;}@Overridepublic OrderApi cloneOrder() {PersonalOrder order = new PersonalOrder();order.setOrderProductNum(this.orderProductNum);order.setCustomerName(this.customerName);order.setProductId(this.productId);return order;}@Overridepublic String toString() {return "PersonalOrder{" +"customerName='" + customerName + '\'' +", productId='" + productId + '\'' +", orderProductNum=" + orderProductNum +'}';}public String getCustomerName() {return customerName;}public void setCustomerName(String customerName) {this.customerName = customerName;}public String getProductId() {return productId;}public void setProductId(String productId) {this.productId = productId;}}

 企业订单修改

package com.zsp.bike.day08原型模式;/*** 企业订单对象*/
public class EnterpriseOrder implements OrderApi{/*** 企业名称*/private String enterpriseName;/*** 产品编号*/private String productId;/*** 订单产品数量*/private int orderProductNum = 0;@Overridepublic int getOrderProductNum() {return this.orderProductNum;}@Overridepublic void setOrderProductNum(int num) {this.orderProductNum = num;}@Overridepublic OrderApi cloneOrder() {EnterpriseOrder order = new EnterpriseOrder();order.setOrderProductNum(this.orderProductNum);order.setEnterpriseName(this.enterpriseName);order.setProductId(this.productId);return order;}public String getEnterpriseName() {return enterpriseName;}public void setEnterpriseName(String enterpriseName) {this.enterpriseName = enterpriseName;}public String getProductId() {return productId;}public void setProductId(String productId) {this.productId = productId;}@Overridepublic String toString() {return "EnterpriseOrder{" +"enterpriseName='" + enterpriseName + '\'' +", productId='" + productId + '\'' +", orderProductNum=" + orderProductNum +'}';}
}

 处理订单的业务对象修改

package com.zsp.bike.day08原型模式;/*** 处理订单的业务对象*/
public class OrderBusiness {/*** 创建订单的方法* @param order 订单的接口对象*/public void saveOrder(OrderApi order){// 业务要求,当订单数量大于1000,把订单分成两份订单//1.判断产品数量是否大于1000while (order.getOrderProductNum() > 1000){// 2.如果大于,还需要继续拆分// 2.1 再新建一份订单,跟传入的订单除了数量不一样外,其他都相同OrderApi newOrder = order.cloneOrder();// 然后进行赋值,产品数量为1000newOrder.setOrderProductNum(1000);// 2.2 原来的订单保留,把数量设置成减少1000order.setOrderProductNum(order.getOrderProductNum() - 1000);// 然后是业务功能处理,省略了,打印输出看一下System.out.println("拆分生成订单==" + newOrder);}//3.不超过1000,那就直接业务功能处理,省略了,打印输出看一下System.out.println("订单==" + order);}
}

通过

 用订单的原型实例来指定对象的种类,通过克隆这个原型实例来创建出了一个新的对象实例。

模式讲解

原型模式的功能:

1.通过克隆来创建新的对象实例

2.为克隆出来的新的对象实例复制原型实例属性的值

原型与new

与new不同点在于,new出来的属性是没有值或者只有默认值,克隆出来的实例一般是有值的,它的值就是原型实例的属性的值。

原型实例与克隆出来的实例

克隆完成后,与原型实例是没有关联的,克隆出来的实例属性值发生变化不会影响原型实例。根源在于不是return this; 是复制的,是指向不同内存空间的

需要克隆的类,可以实现java.lang.Cloneable

浅度克隆和深度克隆

 

原型模式的优缺点

思考

原型模式的本质:克隆生成对象

创建型模式

何时选用?

相关模式 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/83913.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

跨境出海:如何轻松应对多账号管理

在如今的跨境电商时代,成功经营一个线上店铺不再仅仅需要商品和服务,还需要精通广告投放、营销策略等多个领域。 然而,老练的电商从业者知道,如果不重视平台账号的管理方法,可能会导致店铺或营销账号被关联&#xff0…

Idea配置Remote Host

一、打开RemoteHost窗口 双击shift打开全局搜索 搜索Tools→Deployment→Browse Remote Host或 idea项目顶部Tools→Deployment→Browse Remote Host 二、添加服务 右侧边栏打开RemoteHost,点击三个点,起个名字,选择type为SFTP&#xff…

二叉树、红黑树、B树、B+树

二叉树 一棵二叉树是结点的一个有限集合,该集合或者为空,或者是由一个根节点加上两棵别称为左子树和右子树的二叉树组成。 二叉树的特点: 每个结点最多有两棵子树,即二叉树不存在度大于2的结点。二叉树的子树有左右之分&#xf…

C++11 Lambda表达式

Lambda表达式简介 Lambda表达式是现代C在C11和更高版本中的一个新的语法糖。它是一种定义匿名函数对象的便捷方法,常用于封装传递给算法或异步方法的几行代码。Lambda表达式可以在调用或作为函数参数传递的位置处定义,可以捕获上下文中的变量供函数使…

目标检测(Object Detection):Fast R-CNN,YOLO v3

目录 目标检测(Object Detection) R-CNN SPPNet Fast R-CNN YOLO v1 YOLO v2 YOLO v3 目标检测(Object Detection) 任务是计算机视觉中非常重要的基础问题,也是解决图像分割、目标跟踪、图像描述等问题的基础。目标检测是检测输入图像是否存在给定类别的物体…

适配器模式实现stack和queue

适配器模式实现stack和queue 什么是适配器模式?STL标准库中stack和queue的底层结构stack的模拟实现queue的模拟实现 什么是适配器模式? 适配器是一种设计模式(设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结)&#xff…

浅谈泛在电力物联网发展形态与技术挑战

安科瑞 华楠 摘 要:泛在电力物联网是当前智能电网发展的一个方向。首先,总结了泛在电力物联网的主要作用和价值体现;其次,从智能电网各个环节概述了物联网技术在电力领域的已有研究和应用基础;进而,构思并…

OpenAI Function calling

开篇 原文出处 最近 OpenAI 在 6 月 13 号发布了新 feature,主要针对模型进行了优化,提供了 function calling 的功能,该 feature 对于很多集成 OpenAI 的应用来说绝对是一个“神器”。 Prompt 的演进 如果初看 OpenAI 官网对function ca…

AI + Milvus:将时尚应用搭建进行到底

在上一篇文章中,我们学习了如何利用人工智能技术(例如开源 AI 向量数据库 Milvus 和 Hugging Face 模型)寻找与自己穿搭风格相似的明星。在这篇文章中,我们将进一步介绍如何通过对上篇文章中的项目代码稍作修改,获得更…

MySQL 日志

目录 一、日志概述 二、二进制日志 1、开启二进制日志 2、查看二进制文件 3、删除二进制日志文件 4、恢复二进制日志 5、暂时停止二进制日志功能 三、错误日志 1、启动和设置错误日志 2、查看错误日志 3、删除错误日志 四、通用查询日志 五、慢查询日志 一、日志概…

如何实现24/7客户服务自动化?建设智能客服知识库

客户自助服务是指用户通过企业或者第三方建立的网络平台或者终端,实现相关的自定义处理。实现客户服务自动化,对提高客户满意度、维持客户关系至关重要。客户服务自动化可以帮助企业以更快的速度和更高的效率来满足客户的售后服务要求,以进一…

红利期已过?2023跨境电商还吃香吗?亚马逊还能做吗?

2022年,由于疫情反复和外部因素的影响,跨境电商的情况并不乐观。但这并不意味着跨境电商已经走到了绝境。随着贸易全球化的深入发展,平台规则不断完善,国家相继出台最新的扶持政策,为跨境电商企业带来了更多的发展机遇…