创建型-综合题-Prototype
发表于更新于
创建型-综合题-Prototype
Rif题目
Java设计模式练习题:原型模式 - 周报克隆系统
一、案例背景
在一些企业中,员工需要每周提交工作周报,内容通常包括本周完成的任务、问题记录、附件等。通常每周的周报结构大致相同,员工只需要在上一周周报基础上稍作修改即可。为了避免每次都从头填写,企业希望实现一个“克隆周报”的系统,使员工可以复制上一份周报进行编辑。
该系统需要支持以下功能:
- 创建一份原始周报;
- 使用克隆方法复制周报对象;
- 修改副本中的部分内容,不影响原始周报;
- 附件对象也应被一并复制。
二、任务说明
1. 请使用原型设计模式完成如下功能:
· 定义周报类 WeeklyLog,包含字段:name、date、content 和附件 attachment(类型为 Attachment)。
· 实现深克隆功能,使克隆周报对象后,其附件对象与原始周报互不影响。
· 实现原型接口 Cloneable 或通过 Serializable + IO 实现深克隆。
· 编写测试类 Client,克隆一份周报并比较原对象与副本是否为不同对象,附件是否独立。
三、结构图(文字表示)
[WeeklyLog] ← 周报类,实现深克隆(包含附件)
[Attachment] ← 附件类
[Client] ← 客户端,进行克隆操作
四、示例运行结果
周报是否相同? false
附件是否相同? false
原始周报内容:张三 - 第12周 - 完成模块A设计
克隆周报内容:张三 - 第12周 - 完成模块A设计
五、提示建议
• 实现 Serializable 接口并使用对象流进行深克隆。
• 使用 clone() 方法实现浅克隆可用于对比理解。
• 比较原始对象和克隆对象的地址以及内部引用地址。
代码实现
PlantUML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| @startuml !theme plain
interface Serializable
class Attachment { - name: String - type: String - size: long + Attachment(name: String, type: String, size: long) + getName(): String + setName(name: String): void + getType(): String + setType(type: String): void + getSize(): long + setSize(size: long): void + toString(): String }
class WeeklyLog { - name: String - date: String - content: String - attachment: Attachment + WeeklyLog(name: String, date: String, content: String, attachment: Attachment) + getName(): String + setName(name: String): void + getDate(): String + setDate(date: String): void + getContent(): String + setContent(content: String): void + getAttachment(): Attachment + setAttachment(attachment: Attachment): void + deepClone(): WeeklyLog + toString(): String }
class Client_4 { + {static} main(args: String[]): void }
Serializable <|.. Attachment Serializable <|.. WeeklyLog
WeeklyLog *-- Attachment : contains
Client_4 ..> WeeklyLog Client_4 ..> Attachment
@enduml
|
源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
| import java.io.*;
class Attachment implements Serializable { private String name; private String type; private long size; public Attachment(String name, String type, long size) { this.name = name; this.type = type; this.size = size; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getType() { return type; } public void setType(String type) { this.type = type; } public long getSize() { return size; } public void setSize(long size) { this.size = size; } @Override public String toString() { return "Attachment [Name: " + name + ", Type: " + type + ", Size: " + size + " Bytes]"; } }
class WeeklyLog implements Serializable { private String name; private String date; private String content; private Attachment attachment; public WeeklyLog(String name, String date, String content, Attachment attachment) { this.name = name; this.date = date; this.content = content; this.attachment = attachment; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDate() { return date; } public void setDate(String date) { this.date = date; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } public Attachment getAttachment() { return attachment; } public void setAttachment(Attachment attachment) { this.attachment = attachment; } public WeeklyLog deepClone() { WeeklyLog clonedLog = null; try { ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(this); ObjectInputStream ois = new ObjectInputStream(bis); clonedLog = (WeeklyLog) ois.readObject(); oos.close(); bos.close(); ois.close(); bis.close(); } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); System.err.println("Deep cloning failed: " + e.getMessage()); } return clonedLog; } @Override public String toString() { return name + " - " + date + " - " + content; } }
public class Client_4 { public static void main(String[] args) { Attachment originalAttachment = new Attachment("DesignDoc.pdf", "PDF", 102400); WeeklyLog originalLog = new WeeklyLog("张三", "第12周", "完成模块A设计", originalAttachment); System.out.println("Original Weekly Log:"); System.out.println(originalLog); System.out.println(originalLog.getAttachment()); System.out.println("------------------------------------"); WeeklyLog clonedLog = originalLog.deepClone(); if (clonedLog != null) { clonedLog.setContent("完成模块B开发"); clonedLog.getAttachment().setName("ImplementationReport.docx"); clonedLog.getAttachment().setType("DOCX"); clonedLog.getAttachment().setSize(204800); System.out.println("Cloned Weekly Log (after modification):"); System.out.println(clonedLog); System.out.println(clonedLog.getAttachment()); System.out.println("------------------------------------"); System.out.println("Are WeeklyLogs the same object? " + (originalLog == clonedLog)); System.out.println("Are Attachments the same object? " + (originalLog.getAttachment() == clonedLog.getAttachment())); System.out.println(); System.out.println("Original Weekly Log Content: " + originalLog); System.out.println("Cloned Weekly Log Content: " + clonedLog); System.out.println("Original Attachment: " + originalLog.getAttachment()); System.out.println("Cloned Attachment: " + clonedLog.getAttachment()); } } }
|