java设计模式之原型模式
创始人
2024-01-26 07:59:54
0

一:原型模式

1.什么是原型模式?
用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型对象相同的新对象。
基本介绍
1.原型模式(Prototype模式)是指:用原型实例指定创建对象的种类,并且通过拷贝这些原型,创建新的对象
2.原型模式是一种创建型设计模式,允许一个对象再创建另外一个可定制的对象,无需知道如何创建的细节
3.工作原理是:通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝它们自己来实施创建,即 对象.clone()
4.形象的理解:孙大圣拔出猴毛, 变出其它孙大圣

2.原型模式适合应用场景
1.如果你需要复制一些对象, 同时又希望代码独立于这些对象所属的具体类, 可以使用原型模式。
2.这一点考量通常出现在代码需要处理第三方代码通过接口传递过来的对象时。 即使不考虑代码耦合的情况, 你的代码也不能依赖这些对象所属的具体类, 因为你不知道它们的具体信息。
3.原型模式为客户端代码提供一个通用接口, 客户端代码可通过这一接口与所有实现了克隆的对象进行交互, 它也使得客户端代码与其所克隆的对象具体类独立开来。
4.Spring中原型bean的创建,就是原型模式的应用

3. 原型模式优缺点
优点:
1.你可以克隆对象, 而无需与它们所属的具体类相耦合。
2.你可以克隆预生成原型, 避免反复运行初始化代码。
3.你可以更方便地生成复杂对象。
4.你可以用继承以外的方式来处理复杂对象的不同配置。
缺点:
1.克隆包含循环引用的复杂对象可能会非常麻烦。

4.原型模式实现
原型模式的克隆分为浅克隆和深克隆。
浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原
有属性所指向的对象的内存地址。
深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。

二:原型模式代码实现

原型模式包含如下角色:
抽象原型类:规定了具体原型对象必须实现的的 clone() 方法。
具体原型类:实现抽象原型类的 clone() 方法,它是可被复制的对象。
访问类:使用具体原型类中的 clone() 方法来复制新的对象。
浅克隆

//具体原型类
public class Sheep implements Cloneable {private String name;private int age;private String color;private String address = "蒙古羊";public Sheep friend; //是对象, 克隆是会如何处理public Sheep(String name, int age, String color) {super();this.name = name;this.age = age;this.color = color;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getColor() {return color;}public void setColor(String color) {this.color = color;}@Overridepublic String toString() {return "Sheep [name=" + name + ", age=" + age + ", color=" + color + ", address=" + address + "]";}//克隆该实例//重写clone方法,或者用默认的clone方法也行,只不过调用时候需要抛异常@Overrideprotected Object clone()  {Sheep sheep = null;try {sheep = (Sheep)super.clone();} catch (Exception e) {System.out.println(e.getMessage());}return sheep;}
}//--访问类//可以看出都是克隆的原型,调用原型类的clone来复制对象public static void main(String[] args)  {System.out.println("原型模式完成对象的创建");Sheep sheep = new Sheep("tom", 1, "白色");sheep.friend = new Sheep("jack", 2, "黑色");Sheep sheep2 = (Sheep)sheep.clone(); //克隆Sheep sheep3 = (Sheep)sheep.clone(); //克隆Sheep sheep4 = (Sheep)sheep.clone(); //克隆Sheep sheep5 = (Sheep)sheep.clone(); //克隆System.out.println("sheep2 =" + sheep2 + "sheep2.friend=" + sheep2.friend.hashCode());System.out.println("sheep3 =" + sheep3 + "sheep3.friend=" + sheep3.friend.hashCode());System.out.println("sheep4 =" + sheep4 + "sheep4.friend=" + sheep4.friend.hashCode());System.out.println("sheep5 =" + sheep5 + "sheep5.friend=" + sheep5.friend.hashCode());}

在这里插入图片描述

深克隆(原型引用类型,并且原型和引用类型都需要实现序列化,和实现克隆接口)

//原型
public class DeepProtoType implements Serializable, Cloneable{public String name; //String 属性public DeepCloneableTarget deepCloneableTarget;// 引用类型public DeepProtoType() {super();}//深拷贝 - 方式 1 使用clone 方法@Overrideprotected Object clone() throws CloneNotSupportedException {Object deep = null;//这里完成对基本数据类型(属性)和String的克隆deep = super.clone(); //克隆引用类型,对引用类型的属性,进行单独处理DeepProtoType deepProtoType = (DeepProtoType)deep;deepProtoType.deepCloneableTarget  = (DeepCloneableTarget)deepCloneableTarget.clone();return deepProtoType;}//深拷贝 - 方式2 通过对象的序列化实现 (推荐)public Object deepClone() {//创建流对象ByteArrayOutputStream bos = null;ObjectOutputStream oos = null;ByteArrayInputStream bis = null;ObjectInputStream ois = null;try {//序列化bos = new ByteArrayOutputStream();oos = new ObjectOutputStream(bos);oos.writeObject(this); //当前这个对象以对象流的方式输出//反序列化bis = new ByteArrayInputStream(bos.toByteArray());ois = new ObjectInputStream(bis);DeepProtoType copyObj = (DeepProtoType)ois.readObject();return copyObj;} catch (Exception e) {e.printStackTrace();return null;} finally {//关闭流try {bos.close();oos.close();bis.close();ois.close();} catch (Exception e2) {System.out.println(e2.getMessage());}}}
//引用类型
public class DeepCloneableTarget implements Serializable, Cloneable {/*** */private static final long serialVersionUID = 1L;private String cloneName;private String cloneClass;//构造器public DeepCloneableTarget(String cloneName, String cloneClass) {this.cloneName = cloneName;this.cloneClass = cloneClass;}//因为该类的属性,都是String , 因此我们这里使用默认的clone完成即可@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}
	//访问类(深克隆的内存对象是不一致的)public static void main(String[] args) throws Exception {DeepProtoType p = new DeepProtoType();p.name = "宋江";p.deepCloneableTarget = new DeepCloneableTarget("大牛", "小牛");//方式1 完成深拷贝//		DeepProtoType p2 = (DeepProtoType) p.clone();
//		
//		System.out.println("p.name=" + p.name + "p.deepCloneableTarget=" + p.deepCloneableTarget.hashCode());
//		System.out.println("p2.name=" + p.name + "p2.deepCloneableTarget=" + p2.deepCloneableTarget.hashCode());//方式2 完成深拷贝DeepProtoType p2 = (DeepProtoType) p.deepClone();System.out.println("p.name=" + p.name + "p.deepCloneableTarget=" + p.deepCloneableTarget.hashCode());System.out.println("p2.name=" + p.name + "p2.deepCloneableTarget=" + p2.deepCloneableTarget.hashCode());}

在这里插入图片描述

相关内容

热门资讯

南宁创业 南宁创业 南宁创业扶...   南宁创业好项目1:早餐早点式样设计提示:1主食:面包、包子、馒头或其他糕点;2副食:咸菜或其他特...
上个月,在南宁的创业圈发生了一... GAME—BIKE我们首先带来的是“GAME—BIKE”。懂英语的一看就知道,这是个跟游戏跟自行车有...
为何95后都选择了创业小项目 ... 文|懂懂笔记“我还是选择和朋友一起创业,毕竟自由一些,也能够发挥专长。”今年春节后,计算机专业毕业的...
京喜无货源 2个月做到单店80... 大家好,我是大喵!直接步入正题,说白了大多数人创业的初衷就是赚钱,官方一点的说话就是实现经济独立和人...
【推荐】早餐店创业计划书 【推... 【推荐】早餐店创业计划书-word范文本文部分内容来自网络,本司不为其真实性负责,如有异议或侵权请及...
响水县小尖全民创业园项目 响水... 加强社会面控制能力,构建侦查网络化管理;积极组织民警进社区、进企业,开展矛盾化解调处工作;结对帮扶,...
响水县人民政府 镇区动态 小尖... 到5月底,小尖镇全民创业园二期工程已基本告竣,这是该镇精心打造全民创业高地的重要举措。该创业园已成为...
县城创业小项县城创业小项目搜索... 从一个创业者的角度我们看当前的经济形势,并没有发现当下的创业环境有什么根本性的改观。所以说,对待20...
90后小县城创业找项目那种好 ... 90后小县城创业找项目那种好面对这些借口我们要找到***合适的项目,***有效的方法就是找出出一个合...
女生创业有什么好项目有哪些 女... 女生创业者越来越多,那么对于初次创业的女生来说选好一个项目是非常重要的,下面是百分网小编整理的女生适...