前言
前面我们把抽象工厂设计模式给大家介绍完,这一次我给大家带来了原型设计模式。
一、什么是原型模式
原型模式:原型模式是创建型模式,是使用原型实例指定待创建对象的类型,并通过复制这个原型来创建新的对象。它有两个角色:抽象原型和具体原型。
老样子,使用一个实例让大家感受一下原型模式。
二、应用实例
实例描述:在使用某OA系统时,有些岗位的员工发现他们每周的工作都大同小异,因此在填写工作周报时很多内容都是重复的,为了提高工作周报的创建效率,大家迫切地希望有一种机制能够快速创建相同或者相似的周报,包括创建周报的附件。试使用原型模式对该OA系统中的工作周报创建模块进行改进。且需要能查询比较最近几周的周报的变化情况。新建解决方案,新建一个控制台应用程序,编写合适的设计模式来实现代码,实现以上需求的案例。
在完成实例之前还要给大家介绍一下浅克隆与深克隆,以及圆形管理器。
首先,浅克隆就是指原型对象被复制时,只复制它本身和其中包含的基本数据类型的成员变量,引用数据类型的成员变量不会被复制。而深克隆,无论是基本数据类型还是引用数据类型,都会复制。
原型管理器是针对抽象原型类而来的,用来管理抽象原型,可以把它想象成一个笼子,把抽象原型想象成笼子里的动物,笼子就是为了方便管理动物而创建的。
原型模式的类图
代码实现
抽象原型
package prototype;
import java.io.*;
/**
* 抽象周报类
*/
public abstract class Weekly implements Serializable {
private String name;
private String department;
private String position;
private String week;
private String monday;
private String tuesday;
private String wednesday;
private String thursday;
private String friday;
private String saturday;
private String sunday;
private String problem;
private String experience;
private Annex annex;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDepartment() {
return department;
}
public void setDepartment(String department) {
this.department = department;
}
public String getPosition() {
return position;
}
public void setPosition(String position) {
this.position = position;
}
public String getWeek() {
return week;
}
public void setWeek(String week) {
this.week = week;
}
public String getMonday() {
return monday;
}
public void setMonday(String monday) {
this.monday = monday;
}
public String getTuesday() {
return tuesday;
}
public void setTuesday(String tuesday) {
this.tuesday = tuesday;
}
public String getWednesday() {
return wednesday;
}
public void setWednesday(String wednesday) {
this.wednesday = wednesday;
}
public String getThursday() {
return thursday;
}
public void setThursday(String thursday) {
this.thursday = thursday;
}
public String getFriday() {
return friday;
}
public void setFriday(String friday) {
this.friday = friday;
}
public String getSaturday() {
return saturday;
}
public void setSaturday(String saturday) {
this.saturday = saturday;
}
public String getSunday() {
return sunday;
}
public void setSunday(String sunday) {
this.sunday = sunday;
}
public String getProblem() {
return problem;
}
public void setProblem(String problem) {
this.problem = problem;
}
public String getExperience() {
return experience;
}
public void setExperience(String experience) {
this.experience = experience;
}
public Annex getAnnex() {
return annex;
}
public void setAnnex(Annex annex) {
this.annex = annex;
}
public abstract void action();
/**
* 深克隆方法
* @return 克隆后的对象
* @throws Exception 异常
*/
public Weekly deepClone() throws Exception {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(this);
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
return (Weekly)objectInputStream.readObject();
}
@Override
public String toString() {
return "工作周报\n" +
"姓名:" + name + '\n' +
"部门:" + department + '\n' +
"职位:" + position + '\n' +
"时间:" + week + '\n' +
"周一:" + monday + '\n' +
"周二:" + tuesday + '\n' +
"周三:" + wednesday + '\n' +
"周四:" + thursday + '\n' +
"周五:" + friday + '\n' +
"周六:" + saturday + '\n' +
"周日:" + sunday + '\n' +
"遇到的问题:" + problem + '\n' +
"收获和体会:" + experience + '\n' +
"附件:" + annex;
}
}
package prototype;
import java.io.Serializable;
/**
* 附件类
*/
public class Annex implements Serializable {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "附件名:" + name + '\n' +
"这里是附件的内容!!!";
}
}
原型管理器
package prototype;
import java.util.HashMap;
import java.util.Map;
/**
* 周报的原型管理器
*/
public class WeeklyPrototypeManager {
private Map<String,Weekly> weekly = new HashMap<>();
public WeeklyPrototypeManager() {
Annex annex = new Annex();
annex.setName("16周工作周报附件");
Weekly sixteenthJobWeekly = new WeekSixteenthJobWeekly();
sixteenthJobWeekly.setName("Cool_foolisher");
sixteenthJobWeekly.setDepartment("研发一部");
sixteenthJobWeekly.setPosition("经理助理");
sixteenthJobWeekly.setWeek("第16周");
sixteenthJobWeekly.setMonday("整理上周各项目进展报告,向经理汇报总结果");
sixteenthJobWeekly.setTuesday("电话拜访客户,收集并汇报客户在产品使用过程中的问题");
sixteenthJobWeekly.setWednesday("联系企业内训讲师,初审内训大纲,安排内训时间,地点等");
sixteenthJobWeekly.setThursday("整理研发项目的文档,主持并参与项目经理会议");
sixteenthJobWeekly.setFriday("收集各项目组进展报告,配合经理抽查项目完成情况");
sixteenthJobWeekly.setSaturday("加班,协助组织并参与企业内训");
sixteenthJobWeekly.setSunday("休息");
sixteenthJobWeekly.setProblem("一切顺利!");
sixteenthJobWeekly.setExperience("这周好忙,周一至周五都加班!");
sixteenthJobWeekly.setAnnex(annex);
weekly.put("16周工作周报",sixteenthJobWeekly);
}
/**
* 添加对象到原型管理器的方法
* @param name 对象名
* @param weekly 对象
*/
public void addWeekly(String name, Weekly weekly) {
this.weekly.put(name,weekly);
}
/**
* 获取克隆对象
* @param name 克隆对象原型的名字
* @return 克隆后的对象
* @throws Exception
*/
public Weekly getWeekly(String name) throws Exception {
return weekly.get(name).deepClone();
}
}
具体原型
package prototype;
/**
* 第十六周工作周报
*/
public class WeekSixteenthJobWeekly extends Weekly{
@Override
public void action() {
System.out.println(super.toString());
}
}
测试类
package prototype;
/**
* 测试类
*/
public class Demo {
public static void main(String[] args) throws Exception {
WeeklyPrototypeManager weeklyPrototypeManager = new WeeklyPrototypeManager();
Weekly weekly = weeklyPrototypeManager.getWeekly("16周工作周报");
System.out.println("原工作周报");
System.out.println(weekly); // 原工作周报
weekly.setWeek("第17周");
weekly.setWednesday("与经理一起参加公司中高层干部会议,讨论公司规划");
weekly.setSaturday("休息");
weekly.getAnnex().setName("17周工作周报附件");
System.out.println();
System.out.println("新工作周报");
System.out.println(weekly); // 新工作周报
}
}
运行结果
三、总结
以上就是原型设计模式的所有内容,接着我们来总结一下它的优缺点吧!
优点:
- 当创建的对象实例复杂时,用原型设计模式可以简化对象的创建过程,通过克隆一个已有实例可以提高新实例的创建效率。
- 扩展性好,新增或删除产品对原系统没有影响。
缺点:
- 需要为每一个类写一个克隆方法,对于已有的类进行改造时,需要修改源代码,违背了开闭原则。
- 在实现深克隆的时候,需要编写复杂的代码,实现起来比较困难。
最后,如果觉得我的这篇文章对您有帮助,欢迎大家给我点赞,对于原型模式有疑问的话,欢迎大家在评论区留言!!!本人也是刚刚学习编程的小菜鸟,文章如有写的不对的地方,欢迎大佬指正!!!