回顾
七大设计原则
开闭原则(对修改关闭、对扩展开放):学习设计模式或者设计原则,就是为了去扩展代码功能的时候不去修改代码。
理式替换原则(继承):不要破坏类的继承关系,其实就是不要轻易去改动父类已经实现的代码。
接口隔离原则(接口):保证类实现的接口要单一,也是为了方便类的扩展和维护(也是为了开闭原则)
依赖倒置原则(面向接口或者面向继承编程):为了降低类之间的耦合性,尽量的不去面向细节或者实现进行编程。
单一职责原则(类):保证类本身功能职责单一,这样就会减少类的改动几率
合成复用原则(组合或者聚合)
最少认知原则(类与类之间的关系):不要与陌生人交流。如果两个类之间不存在依赖关系,他们直接在沟通的时候
最好通过第三者去沟通
设计模式(三类23种)
创建型:将对象的创建和对象的使用分离。
new Student();
student.study(); 、
工厂模式:简单工厂、工厂方法、抽象工厂 批量生产(属性一致)
构建者模式:私人定制(属性不一致)
单例模式:只会生产一个产品(最复杂)
原型模式:给我一个对象,我会产生一样的对象
结构型(7种):适配器模式、装饰模式、代理模式、外观模式、桥接模式、组合模式、享元模式
行为型(11种):模板方法模式、策略模式、观察者模式、中介者模式、状态模式、责任链模式、命令模式、迭代器模式、访问者模式、解释器模式、备忘录模式。
原型模式(copy)
作用:就是给我一个原型,我给你一个对象。
使用原型模式复制出来的对象,和原先的对象,都是在堆空间中互相独立的对象。
s1 = Student();
s2 = s1;
使用场景:
有一个数据对象Student
A线程需要对该对象进行一些操作
B线程也需要对该对象进行一些操作。
以上两个操作都各自需要自己的Student对象。
BeanUtils.copy()。
深拷贝和浅拷贝的理解
浅拷贝:原型对象和复制出来的新对象,他们的引用类型新的属性如果地址值相同则是浅拷贝
Student{
int age;
Teacher t;
}
Student studentA = new Student();
Student studentB = new Student();
深拷贝:原型对象和复制出来的新对象,他们的引用类型新的属性如果地址值不相同则是深拷贝
浅拷贝和深拷贝的实现分析
浅拷贝:
1.只需要给原型对象(也就是被复制的对象)实现一个Cloneable接口
(是一个空接口,是一个标记接口),就可以了
2.需要调用super.clone方法产生新的对象(其实就是Object对象的方法)
深拷贝:
需要使用到对象序列化流进行对象的读取和写出。
经过对象序列化流的读取和写出过程所经历已经是两个不同的对象了。
1.需要实现Serializable接口
演示代码:
原型演示Demo
package com.wang.a_prototype;
import java.io.IOException;
import java.io.Serializable;
public class PrototypeDemo {
/**
* @param args
* @throws CloneNotSupportedException
* @throws IOException
* @throws ClassNotFoundException
*/
public static void main(String[] args) throws CloneNotSupportedException, ClassNotFoundException, IOException {
// 创建原型对象
Prototype prototype = new Prototype();
prototype.setName("娲女");
prototype.setObject(new SerializableObject());
System.out.println("原始对象" + prototype.getName());
System.out.println("原始对象" + prototype.getObject());
Prototype shallowPrototype = (Prototype) prototype.shallowClone();
System.out.println("浅拷贝对象" + shallowPrototype.getName());
System.out.println("浅拷贝对象" + shallowPrototype.getObject());
Prototype deepPrototype = (Prototype) prototype.deepClone();
System.out.println("深拷贝对象" + deepPrototype.getName());
System.out.println("深拷贝对象" + deepPrototype.getObject());
}
}
class SerializableObject implements Serializable {
private static final long serialVersionUID = 5350661554590717448L;
}
原型模式(get/set方法省略)
package com.wang.a_prototype;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class Prototype implements Cloneable, Serializable {
private static final long serialVersionUID = -6884435299359730024L;
/**
* 简单数据类型
*/
private String name;
/**
* 引用类型
*/
private SerializableObject object;
/**
* 浅复制
*
* @return
* @throws CloneNotSupportedException
*/
public Object shallowClone() throws CloneNotSupportedException {
// super.clone 其实就是调用了Object对象的clone方法
// Object对象的clone方法是调用了native方法去在JVM中实现复制。
Prototype prototype = (Prototype) super.clone();
return prototype;
}
/**
* 深拷贝 要实现深拷贝,需要采用流的形式读入当前对象的二进制流输入,再写出二进制数据对应的对象
*
* @return
* @throws IOException
* @throws ClassNotFoundException
*/
public Object deepClone() throws IOException, ClassNotFoundException {
/**
* 将对象序列化到二进制流
*/
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
/**
* 从二进制流中读出产生的新对象。
*/
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return ois.readObject();
}
}