设计模式(5):原型模式

一.原型模式

  • 通过 n e w 产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式。 \color{red}{通过new产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式。} 通过new产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式。
  • 就是java中的克隆技术,以某个对象为原型,复杂出新的对象。显然,新的对象具备原型对象的特点。
  • 优势: 效率高(直接克隆,避免了重新执行构造过程步骤)。
  • 克隆类似new,但是不同于new。new创建新的对象属性采用的是默认值。克隆出的对象的属性值完全和原型对象相同。并且克隆出的新对象改变不会影响原型对象。然后,再改变克隆对象的值。
  • 原型模式一般很少单独出现,一般是和工厂方法模式一起出现,通过 c l o n e 方法创建一个对象,然后由工厂方法提供给调用者。 \color{red}{原型模式一般很少单独出现,一般是和工厂方法模式一起出现,通过clone方法创建一个对象,然后由工厂方法提供给调用者。} 原型模式一般很少单独出现,一般是和工厂方法模式一起出现,通过clone方法创建一个对象,然后由工厂方法提供给调用者。

二.原型模式实现

  • cloneable接口和clone方法;
  • 利用序列化和反序列化实现深克隆。

三.浅克隆和深克隆

  • 所谓浅克隆、深克隆指的是:克隆对象和原型对象属性对象引用是否同一个,是同一个就是浅克隆,否则就是深克隆。


四.代码展示

  • 1.浅克隆代码

/**
 * 克隆羊  多利 对象
 */
public class Sheep implements Cloneable{
	private String name;
	private Date birthday;
	@Override
	protected Object clone() throws CloneNotSupportedException {
		//ֱ直接调用Object对象的clone()方法
		Object obj=super.clone();   
		return obj;
	}
	public Sheep() {
	}
	public Sheep(String name, Date birthday) {
		this.name = name;
		this.birthday = birthday;
	}
	public String getName() {
		return name;
	}
	public Date getBirthday() {
		return birthday;
	}
	public void setName(String name) {
		this.name = name;
	}
	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}
}
  • 浅克隆调用

/**
 * 原型模式------>浅复制(浅克隆)
 */
public class App {
	public static void main(String[] args) throws CloneNotSupportedException {
		Date date=new Date(123123123L);
		Sheep s1=new Sheep("多利",date);
		Sheep s2=(Sheep) s1.clone();
		System.out.println(s1+"\t"+s1.getName()+"---->"+s1.getBirthday());
		//这里更改后 s2 克隆也相应更改
		date.setTime(321213543123L);
		System.out.println(s1+"\t"+s1.getName()+"---->"+s1.getBirthday());
		
		//可以更改s2的属性
		s2.setName("多多利");
		System.out.println(s2+"\t"+s2.getName()+"---->"+s2.getBirthday());
	}
}
  • 浅克隆调用结果

com.reyco.prototype.Sheep@7852e922	多利---->Fri Jan 02 18:12:03 CST 1970
com.reyco.prototype.Sheep@7852e922	多利---->Fri Mar 07 01:59:03 CST 1980
com.reyco.prototype.Sheep@55f96302	多多利---->Fri Mar 07 01:59:03 CST 1980
  • 浅克隆调用结果:原型对象的引用属性改变后,克隆对象也会跟着改变。



  • 2. 深克隆代码

/**
 * 原型模式------>深复制(深克隆)
 */
public class Sheep2 implements Cloneable{
	private String name;
	private Date birthday;	
	@Override
	protected Object clone() throws CloneNotSupportedException {
		Object obj=super.clone();    //直接调用Object对象的clone()方法	
		//添加以下代码实现深复制
		Sheep2 s=(Sheep2) obj; 
		s.birthday=(Date) this.birthday.clone();		
		return obj;
	}
	
	public Sheep2() {
	}
	public Sheep2(String name, Date birthday) {
		this.name = name;
		this.birthday = birthday;
	}
	public String getName() {
		return name;
	}
	public Date getBirthday() {
		return birthday;
	}
	public void setName(String name) {
		this.name = name;
	}
	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}
}
  • 深克隆调用

/**
 * 原型模式------>深复制(深克隆)
 * @author Administrator
 */
public class App2 {
	public static void main(String[] args) throws CloneNotSupportedException {
		Date date=new Date(123123123L);
		Sheep2 s=new Sheep2("多利",date);
		Sheep2 s2=(Sheep2) s.clone();
		System.out.println(s.getName()+"---->"+s.getBirthday());
		//这里更改后 s2克隆不会更改
		date.setTime(321213543123L);
		System.out.println(s.getName()+"---->"+s.getBirthday());
		
		//可以更改s2的属性
		s2.setName("多多利");
		System.out.println(s2.getName()+"---->"+s2.getBirthday());
	}
}
  • 深克隆调用结果

多利---->Fri Jan 02 18:12:03 CST 1970
多利---->Fri Mar 07 01:59:03 CST 1980
多多利---->Fri Jan 02 18:12:03 CST 1970
  • 深克隆调用结果:原型对象的引用属性改变后,克隆对象不会跟着改变。

五.序列化和反序列化实现深克隆

  • 代码

/**
 * 序列化和反序列化实现深克隆必须实现Serializable接口
 */
public class Sheep implements Serializable{
	private String name;
	private Date birthday;
	public Sheep() {
	}
	public Sheep(String name, Date birthday) {
		this.name = name;
		this.birthday = birthday;
	}
	public String getName() {
		return name;
	}
	public Date getBirthday() {
		return birthday;
	}
	public void setName(String name) {
		this.name = name;
	}
	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}
}


public static void main(String[] args) throws  Exception {
	Date date=new Date(123123123L);
	Sheep s=new Sheep("多利",date);
	System.out.println(s.getName()+"---->"+s.getBirthday());
	
	//使用序列化和反序列化实现深复制
	ByteArrayOutputStream bos=new ByteArrayOutputStream();
	ObjectOutputStream oos=new ObjectOutputStream(bos);
	oos.writeObject(s);
	byte[] bytes =bos.toByteArray();	
	ByteArrayInputStream bis=new ByteArrayInputStream(bytes);
	ObjectInputStream ois=new ObjectInputStream(bis);
	Sheep s2=(Sheep) ois.readObject();
	//这里更改后 s2克隆不会更改
	date.setTime(321213543123L);
	System.out.println(s.getName()+"---->"+s.getBirthday());
	
	//可以更改s2的属性
	s2.setName("多多利");
	System.out.println(s2.getName()+"---->"+s2.getBirthday());
}

相关推荐

  1. 设计模式(5):原型模式

    2024-03-28 10:44:02       36 阅读
  2. C++11 设计模式5. 原型模式

    2024-03-28 10:44:02       27 阅读
  3. 5设计模式之适配器模式/原型模式

    2024-03-28 10:44:02       33 阅读
  4. 设计模式专题之原型模式5. 矩形原型

    2024-03-28 10:44:02       35 阅读
  5. 设计模式原型模式

    2024-03-28 10:44:02       63 阅读
  6. 设计模式——原型模式

    2024-03-28 10:44:02       50 阅读
  7. 设计模式-原型模式

    2024-03-28 10:44:02       58 阅读
  8. 设计模式-原型模式

    2024-03-28 10:44:02       51 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-28 10:44:02       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-28 10:44:02       106 阅读
  3. 在Django里面运行非项目文件

    2024-03-28 10:44:02       87 阅读
  4. Python语言-面向对象

    2024-03-28 10:44:02       96 阅读

热门阅读

  1. 项目搭建之统一返回值

    2024-03-28 10:44:02       42 阅读
  2. 5.88 BCC工具之tcpsynbl.py解读

    2024-03-28 10:44:02       39 阅读
  3. stm32重写printf函数串口调试---环境:stm32+hal+cubeide

    2024-03-28 10:44:02       42 阅读
  4. MySQL添加数据的方式

    2024-03-28 10:44:02       44 阅读
  5. 力扣练习 3.27

    2024-03-28 10:44:02       41 阅读
  6. python爬虫基础----字符串高级

    2024-03-28 10:44:02       38 阅读
  7. 云计算运维工程师

    2024-03-28 10:44:02       37 阅读
  8. 【uniapp】Vue3移动端滚动加载 分页组件的封装

    2024-03-28 10:44:02       40 阅读
  9. mysql_数据_增删改查

    2024-03-28 10:44:02       40 阅读