diff --git a/README/images/设计模式-v2/image-20250202214232289.png b/README/images/设计模式-v2/image-20250202214232289.png new file mode 100644 index 0000000..6031b25 Binary files /dev/null and b/README/images/设计模式-v2/image-20250202214232289.png differ diff --git a/README/设计模式-v2.md b/README/设计模式-v2.md index e222a6c..1e8f978 100644 --- a/README/设计模式-v2.md +++ b/README/设计模式-v2.md @@ -961,9 +961,206 @@ CommandDemo.Computer(CPU=Low CPU, RAM=Low RAM, hardDrive=Low Driver) CommandDemo.Computer(CPU=High CPU, RAM=High RAM, hardDrive=High Driver) ``` +--- + +## 原型模式 + +![image-20250202214232289](./images/设计模式-v2/image-20250202214232289.png) + +需要三个角色:抽象原型类(Abstract Prototype)、具体原型类(Concrete Prototype)、访问类(Client) + +### 简单示例 + +提示:需要做深克隆,当类中还存在另一个类时 + +#### 错误示例代码 + +当我们对school对象进行设置时,对`resume1`进行设置结果`resume`也发生了改变。需要修改`Resume`类中的`clone`方法 + +```java +public class Prototype { + public static void main(String[] args) { + Resume resume = new Resume(); + resume.name = "Bunny"; + resume.position = "架构师"; + resume.salary = 15000; + + School school = new School(); + school.schoolName = "江南大学"; + school.time = "2025年2月2日21:38:07"; + resume.school = school; + System.out.println(resume); + + Resume resume1 = resume.clone(); + resume1.salary = 19000; + resume1.school.schoolName = "清华大学"; + System.out.println(resume1); + + Resume resume2 = resume.clone(); + resume2.salary = 20000; + System.out.println(resume2); + + System.out.println(resume1 == resume2);// false + System.out.println(resume1.school == resume2.school);// true + } + + @Data + static class Resume implements Cloneable { + private String name; + private String position; + private Integer salary; + private School school; + + @Override + public Resume clone() { + try { + return (Resume) super.clone(); + } catch (CloneNotSupportedException e) { + throw new AssertionError(); + } + } + } + + @Data + static class School implements Cloneable { + private String schoolName; + private String time; + + @Override + public School clone() { + try { + return (School) super.clone(); + } catch (CloneNotSupportedException e) { + throw new AssertionError(); + } + } + } +} +``` + +#### 运行结果: + +```java +Prototype.Resume(name=Bunny, position=架构师, salary=15000, school=Prototype.School(schoolName=江南大学, time=2025年2月2日21:38:07)) +Prototype.Resume(name=Bunny, position=架构师, salary=19000, school=Prototype.School(schoolName=清华大学, time=2025年2月2日21:38:07)) +Prototype.Resume(name=Bunny, position=架构师, salary=20000, school=Prototype.School(schoolName=清华大学, time=2025年2月2日21:38:07)) +false +true +``` + +#### 正确示例代码 + +##### 修改`conle` + +```java +@Data +static class Resume implements Cloneable { + private String name; + private String position; + private Integer salary; + private School school; + + @Override + public Resume clone() { + Resume resume = null; + try { + resume = (Resume) super.clone(); + if (school != null) { + resume.school = school.clone(); + } + } catch (CloneNotSupportedException e) { + throw new AssertionError(); + } + + return resume; + } +} +``` + +##### 示例 + +```java +public class Prototype { + public static void main(String[] args) { + Resume resume = new Resume(); + resume.name = "Bunny"; + resume.position = "架构师"; + resume.salary = 15000; + + School school = new School(); + school.schoolName = "江南大学"; + school.time = "2025年2月2日21:38:07"; + resume.school = school; + System.out.println(resume); + + Resume resume1 = resume.clone(); + resume1.salary = 19000; + resume1.school.schoolName = "清华大学"; + System.out.println(resume1); + + Resume resume2 = resume.clone(); + resume2.salary = 20000; + System.out.println(resume2); + + System.out.println(resume1 == resume2);// false + System.out.println(resume1.school == resume2.school);// false + } + + @Data + static class Resume implements Cloneable { + private String name; + private String position; + private Integer salary; + private School school; + + @Override + public Resume clone() { + Resume resume = null; + try { + resume = (Resume) super.clone(); + if (school != null) { + resume.school = school.clone(); + } + } catch (CloneNotSupportedException e) { + throw new AssertionError(); + } + + return resume; + } + } + + @Data + static class School implements Cloneable { + private String schoolName; + private String time; + + @Override + public School clone() { + try { + return (School) super.clone(); + } catch (CloneNotSupportedException e) { + throw new AssertionError(); + } + } + } +} +``` + +#### 运行结果: + +```java +Prototype.Resume(name=Bunny, position=架构师, salary=15000, school=Prototype.School(schoolName=江南大学, time=2025年2月2日21:38:07)) +Prototype.Resume(name=Bunny, position=架构师, salary=19000, school=Prototype.School(schoolName=清华大学, time=2025年2月2日21:38:07)) +Prototype.Resume(name=Bunny, position=架构师, salary=20000, school=Prototype.School(schoolName=江南大学, time=2025年2月2日21:38:07)) +false +false +``` + +--- + ## 责任链模式-未完成。。。 -主要有两个角色:抽象处理者(Handler)、具体处理者(ConcreteHandler) +主要有两个角色:抽象处理者(Handler)、具体处理者(Concrete Handler) ![image-20250202201204954](./images/设计模式-v2/image-20250202201204954.png) diff --git a/pattern/src/main/java/cn/bunny/pattern8/demo1/Prototype.java b/pattern/src/main/java/cn/bunny/pattern8/demo1/Prototype.java new file mode 100644 index 0000000..3b35d4c --- /dev/null +++ b/pattern/src/main/java/cn/bunny/pattern8/demo1/Prototype.java @@ -0,0 +1,63 @@ +package cn.bunny.pattern8.demo1; + +import lombok.Data; + +public class Prototype { + public static void main(String[] args) { + Resume resume = new Resume(); + resume.name = "Bunny"; + resume.position = "架构师"; + resume.salary = 15000; + + School school = new School(); + school.schoolName = "江南大学"; + school.time = "2025年2月2日21:38:07"; + resume.school = school; + System.out.println(resume); + + Resume resume1 = resume.clone(); + resume1.salary = 19000; + resume1.school.schoolName = "清华大学"; + System.out.println(resume1); + + Resume resume2 = resume.clone(); + resume2.salary = 20000; + System.out.println(resume2); + + System.out.println(resume1 == resume2);// false + System.out.println(resume1.school == resume2.school);// true + + } + + @Data + static class Resume implements Cloneable { + private String name; + private String position; + private Integer salary; + private School school; + + @Override + public Resume clone() { + try { + return (Resume) super.clone(); + } catch (CloneNotSupportedException e) { + throw new AssertionError(); + } + } + } + + @Data + static class School implements Cloneable { + private String schoolName; + private String time; + + @Override + public School clone() { + try { + return (School) super.clone(); + } catch (CloneNotSupportedException e) { + throw new AssertionError(); + } + } + } +} \ No newline at end of file diff --git a/pattern/src/main/java/cn/bunny/pattern8/demo2/Prototype.java b/pattern/src/main/java/cn/bunny/pattern8/demo2/Prototype.java new file mode 100644 index 0000000..1983ed1 --- /dev/null +++ b/pattern/src/main/java/cn/bunny/pattern8/demo2/Prototype.java @@ -0,0 +1,68 @@ +package cn.bunny.pattern8.demo2; + +import lombok.Data; + +public class Prototype { + public static void main(String[] args) { + Resume resume = new Resume(); + resume.name = "Bunny"; + resume.position = "架构师"; + resume.salary = 15000; + + School school = new School(); + school.schoolName = "江南大学"; + school.time = "2025年2月2日21:38:07"; + resume.school = school; + System.out.println(resume); + + Resume resume1 = resume.clone(); + resume1.salary = 19000; + resume1.school.schoolName = "清华大学"; + System.out.println(resume1); + + Resume resume2 = resume.clone(); + resume2.salary = 20000; + System.out.println(resume2); + + System.out.println(resume1 == resume2);// false + System.out.println(resume1.school == resume2.school);// false + } + + @Data + static class Resume implements Cloneable { + private String name; + private String position; + private Integer salary; + private School school; + + @Override + public Resume clone() { + Resume resume = null; + try { + resume = (Resume) super.clone(); + if (school != null) { + resume.school = school.clone(); + } + } catch (CloneNotSupportedException e) { + throw new AssertionError(); + } + + return resume; + } + } + + @Data + static class School implements Cloneable { + private String schoolName; + private String time; + + @Override + public School clone() { + try { + return (School) super.clone(); + } catch (CloneNotSupportedException e) { + throw new AssertionError(); + } + } + } +}