二十三种设计模式之原型模式

一.什么是原型模式

‌原型模式是一种创建型对象设计模式,它通过复制一个已经创建的实例(即原型对象)来创建一个和原型对象相同的新对象。‌ 这种模式在面向对象软件设计中非常有用,因为它允许通过复制现有对象来快速生成多个相似的对象,而无需重新初始化每个对象。原型模式的工作原理是将一个原型对象传给需要创建新对象的类,该类通过请求原型对象的拷贝来实现创建过程。

二.原型模式的类图

三.cloneable接口

对于深拷贝和浅拷贝不是很理解的,可以参考下面的文章

参考博文:cloneable详细说明

cloneable接口存在于java.lang包中

官方手册解释

总之,cloneable是浅拷贝,在对引用类型进行拷贝时,对于引用类型成员变量来说,原型和复制品的地址都是同一个,这样就会造成要改全部改的情况。这时候就要重新开辟空间,实现深拷贝。

四.实例

创建一个输出框样式,使得打印的样式不同。有两种样式一种是下划线,另一种是四边都有框。其中,cloneable接口的实现是关键。product类实现了cloneable接口,underlinpen和MessageBox继承了product类,这样就可以调用clone方法复制开辟的对象空间,而不需要重新分配。

Manager.java

package framework;
import java.util.*;
public class Manager {
private HashMap showcase=new HashMap();
public void register(String name,product pro) {showcase.put(name, pro);
}
public product create(String pro) {product p=(product)showcase.get(pro);return p.createClone();
}
}

product.java

package framework;public interface product extends Cloneable{
public abstract void use(String s);
public abstract product createClone();
}

MessageBox.java

package style;
import framework.*;
public class MessageBox implements product{
private char decochar;
public MessageBox(char decochar) {this.decochar=decochar;
}
public void use(String s) {int length=s.getBytes().length;for(int i=0;i<length+4;i++) {System.out.print(decochar);}System.out.println("");System.out.println(decochar+" "+s+" "+decochar);for(int i=0;i<length+4;i++) {System.out.print(decochar);}System.out.println("");
}
@Override
public product createClone() {// TODO Auto-generated method stubproduct p=null;try {p=(product)clone();}catch(CloneNotSupportedException e) {e.printStackTrace();}return p;
}
}

underlinepen.java

package style;
import framework.*;
public class underlinepen implements product{
private char ulchar;
public underlinepen(char ulchar) {this.ulchar=ulchar;
}
public void use(String s) {int length=s.getBytes().length;System.out.println("'\'"+s+"\"");for(int i=0;i<length+4;i++) {System.out.print(ulchar);}System.out.println("");
}
@Override
public product createClone() {// TODO Auto-generated method stubproduct p=null;try {p=(product)clone();}catch(CloneNotSupportedException e) {e.printStackTrace();}return p;
}
}

输出结果:

五.为什么要使用原型模式?

原型模式的适用情况:

1.对象种类繁多,无法将它们整合到一个类中。

2.难以根据类生成实例时

3.想解耦框架,生成实例时

原型模式是一种创建型对象设计模式,它允许通过复制已有对象来创建新对象,而不需要使用显式的构造函数调用来创建。这种模式特别适用于对象创建成本较高或耗时较长的场景,通过复制一个现有对象的属性和方法来创建新对象,从而避免了昂贵的创建过程。

六.习题

习题6-1

我的答案:

将product改为c抽象类实现cloneable接口,将createClone方法写入product内。MessageBox和UnderlinePan继承product类。

product.java

package framework;public abstract class product implements  Cloneable{
public abstract void use(String s);
public product createClone() {product p=null;try {p=(product)clone();}catch(CloneNotSupportedException e) {e.printStackTrace();}return p;
}
}

MessageBox.java

package style;
import framework.*;
public class MessageBox extends product{
private char decochar;
public MessageBox(char decochar) {this.decochar=decochar;
}
public void use(String s) {int length=s.getBytes().length;for(int i=0;i<length+4;i++) {System.out.print(decochar);}System.out.println("");System.out.println(decochar+" "+s+" "+decochar);for(int i=0;i<length+4;i++) {System.out.print(decochar);}System.out.println("");
}}

underlinePan.java

package style;
import framework.*;
public class underlinepen extends product{
private char ulchar;
public underlinepen(char ulchar) {this.ulchar=ulchar;
}
public void use(String s) {int length=s.getBytes().length;System.out.println("'\'"+s+"\"");for(int i=0;i<length+4;i++) {System.out.print(ulchar);}System.out.println("");
}
}

参考答案:

习题6-2答案

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

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

相关文章

springboot修改组件扫描包位置

步骤很详细&#xff0c;直接上教程 问题分析 默认情况下组件扫描包范围为启动类所在包及其子包 解决方法 我们只需要在启动类上面加个注解配置扫描范围 效果演示 温馨提示 非必要不建议修改&#xff0c;按规范创建项目结构一般不会出现这个问题

Unity-Time类

目录 Time.timeScale Time.deltaTime Time.unscaledDeltaTime Time.time Time.frameCount Time.fixedDeltaTime Time.timeScale 时间缩放比例 时间停止 Time.timeScale 0; //回复正常 //Time.timeScale 1; //2倍速 …

AI+代码审核平台CodeSec获CCIA中国网络安全创新创业大赛总决赛三等奖

近日&#xff0c;由中央网信办指导&#xff0c;中国网络安全产业联盟&#xff08;CCIA&#xff09;主办的2024年中国网络安全创新创业大赛总决赛及颁奖典礼在国家网络安全宣传周落下帷幕。开源网安“AI代码审核平台CodeSec V4.0” 凭借在AI方向的技术创新、技术突破及功能应用创…

热门远程控制工具大盘点,职场必备

如果你想要进行远程数据操作那向日葵远程控制软件你肯定听说过吧。如果你是想要远程运维&#xff0c;远程办公&#xff0c;数据传输&#xff0c;这些远程控制工具都可以实现。这次我将介绍几款我身边小伙伴都在使用的远程控制工具。 1.向日葵远程控制 链接直达&#xff1a;ht…

Python数据分析工具(一):Requests的用法

Python的Requests库是一个非常流行的HTTP库&#xff0c;用于发送各种HTTP请求。它简化了与Web服务的交互&#xff0c;提供了易于使用的API。以下是一些基本的Requests用法示例&#xff1a; 安装Requests 首先&#xff0c;确保你已经安装了Requests库。如果还没有安装&#xf…

Python 数学建模——Prophet 时间序列预测

文章目录 前言原理使用方法&#xff08;初级&#xff09;代码实例Prophet 高级应用add_seasonality 添加自定义周期性add_regressor 添加外生变量交叉检验 前言 Prophet 是 Facebook 团队开发的一个时间序列分析工具&#xff0c;相比传统的 ARMA 时间序列分析&#xff0c;能够综…

常见 HTTP 状态码详解与Nginx 文件上传大小限制

在我们日常使用 Nginx 搭建网站或应用服务时&#xff0c;可能会遇到很多与文件上传和请求响应相关的问题。今天我们就来聊聊 如何限制文件上传的大小&#xff0c;并介绍一些常见的 HTTP 状态码 及其在 Nginx 中的处理方式。 一、文件上传大小限制 有时&#xff0c;我们需要限…

通过覆写 url_for 将 flask 应用部署到子目录下

0. 缘起 最近用 flask 写了一个 web 应用&#xff0c;需要部署到服务器上。而服务器主域名已经被使用了&#xff0c;只能给主域名加个子目录进行部署&#xff0c;比如主域名 example.org &#xff0c;我需要在 example.org/flask 下部署。这时 flask 应用里的内部连接们就出现…

github远程仓库环境搭建及使用

目录 1、创建一台虚拟机 centos 源的配置 备份源 修改源 重新加载缓存 安装软件 配置epel 2、关闭防火墙和selinux 关闭防火墙 临时关闭SELinux 永久关闭SELinux&#xff1a;编辑SELinux的配置文件 配置文件的修改内容 3、git是本地仓库&#xff0c;linux系统中一…

Qt常用控件——QDateTimeEdit

文章目录 QDateTimeEdit核心属性及信号时间计算器 QDateTimeEdit核心属性及信号 QDateEdit作为日期的微调框QTimeEdit作为时间的微调框QDateTimeEdit作为时间日期的微调框 它们的使用方式都是类似的&#xff0c;本篇以QDateTimeEdit作为示例 核心属性&#xff1a; 属性说明…

C# 在WPF中实现图表生成

在现代应用程序中,数据可视化是一个重要的功能,它可以帮助用户更直观地理解数据。在C# WPF(Windows Presentation Foundation)中,有多种方式可以生成图表。以下是五种常见的方法,每种方法都有其独特的优势和局限。 1. 使用System.Windows.Shapes命名空间 代码示例: &…

【CSS】样式水平垂直居中

行内元素&#xff1a; 如果被设置元素为文本、图片等行内元素时&#xff0c;水平居中是通过给父元素设置 text-align:center <body> <div class"txtCenter">我想要在父容器中水平居中显示。</div> </body>div是文本元素的父元素 因此我们对…

【秒达开源】多功能中文工具箱源码:自部署 全开源 轻量级跨平台 GPT级支持+高效UI+Docker

【秒达开源】多功能中文工具箱源码发布&#xff1a;自部署、全开源、轻量级跨平台&#xff0c;GPT级支持高效UI&#xff0c;Docker/便携版任选&#xff0c;桌面友好丰富插件生态 这是一款集大成之作&#xff0c;专为追求高效与便捷的用户量身打造。它不仅支持完全自部署&#…

Nginx节点健康检查与自动上下线管理脚本,推送告警到企业微信

文章目录 案例:Linux 定时任务调取脚本执行场景说明告警脚本(text)check_nginx_tcp_up.shcheck_nginx_tcp_up.logcheck_nginx_tcp_up_run.shcheck_nginx_tcp_up_run.log告警效果案例:Linux 定时任务调取脚本执行 由于需求是每 2 秒执行一次,但 Linux 定时任务最小单位是分…

远程访问电脑共享文件

远程访问电脑共享文件&#xff0c;可以通过多种方法实现&#xff0c;每种方法都有其特点和适用场景。以下是一些常见的方法及其步骤&#xff1a; 一、使用Microsoft远程桌面 启用远程桌面&#xff1a; 在目标电脑上&#xff0c;打开“开始”菜单&#xff0c;选择“设置”>“…

教育培训小程序开发,简单实用的入门指南

教育培训小程序可以帮助教育机构和个人老师提供更灵活的在线教学服务&#xff0c;满足学生的学习需求。对于初学者来说&#xff0c;开发一个功能齐全的教育培训小程序并不复杂&#xff0c;只需掌握一些基础的开发知识和工具即可。本文将带你了解如何使用微信小程序开发工具&…

5-【JavaWeb】JUnit 单元测试及JUL 日志系统

1. 使用 JUnit 进行单元测试 JUnit 是 Java 中非常流行的单元测试框架&#xff0c;MyBatis 与 JUnit 可以很好地结合&#xff0c;来测试持久层代码的正确性。 1.1 添加 JUnit 依赖 在使用 JUnit 之前&#xff0c;需要在 pom.xml 中引入 JUnit 依赖。 <dependency><…

SpringBoot开发——使用@Slf4j注解实现日志输出

文章目录 1、Lombok简介2、SLF4J简介3、实现步骤3.1 创建SpringBoot项目3.2 添加依赖3.3 使用 Slf4j 注解3.4 输出日志信息 4、结论 在现代Java开发中&#xff0c;日志记录是至关重要的。它不仅帮助开发者调试代码&#xff0c;还便于监控系统运行状态和性能。 Lombok 和 SLF4J …

【Android】Room—数据库的基本操作

引言 在Android开发中&#xff0c;数据持久化是一个不可或缺的部分。随着应用的复杂度增加&#xff0c;选择合适的数据存储方式变得尤为重要。Room数据库作为Android Jetpack架构组件之一&#xff0c;提供了一种抽象层&#xff0c;使得开发者能够以更简洁、更安全的方式操作SQ…

快速搭建最简单的前端项目vue+View UI Plus

1 引言 ‌‌Vue是一套用于构建Web前端界面的渐进式JavaScript框架。‌‌它以其易学易用、性能出色、灵活多变而深受开发者喜爱&#xff0c;并且与其他前端框架&#xff08;如‌React和‌Angular&#xff09;相比&#xff0c;在国内市场上受到了广泛的认可和使用。点击进入官方…