大家好,我是馆长!从今天开始馆长开始对java设计模式的创建型模式中的单例模式、原型模式、工厂方法、抽象工厂、建造者的原型模式进行讲解和说明。
原型模式(Prototype Pattern)
定义
原型模式是一种创建型设计模式,Prototype模式允许一个对象再创建另外一个可定制的对象,根本无需知道任何如何创建的细节,工作原理是:通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝它们自己来实施创建。
解决问题
它主要面对的问题是:“某些结构复杂的对象”的创建工作;由于需求的变化,这些对象经常面临着剧烈的变化,但是他们却拥有比较稳定一致的接口。这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。
实现
由于Java 提供了对象的 clone() 方法,所以用 Java 实现原型模式很简单。原型模式的克隆分为 浅克隆 和 深克隆 。
浅拷贝:当拷贝对象包含基本数据类型(如int、long)或者不可变的对象(如字符串、基本类型的包装类)时,会直接将这些属性复制到新的对象中。而原型对象中的引用对象会把内存中的地址复制给克隆对象。对于非基本类型属性,仍指向原有属性所指向的对象的内存地址。
深拷贝:不管原型对象属性是简单数据类型还是引用对象类型都会完全的复制一份到新的对象中。两个对象之间互不影响。属性中引用的其他对象也会被克隆,不再指向原有对象地址。
结构
原型模式包含以下主要角色。
1.抽象原型类:规定了具体原型对象必须实现的接口(Cloneable 接口)。
2.具体原型类:实现抽象原型类的 clone() 方法,它是可被复制的对象。
3.访问类:使用具体原型类中的 clone() 方法来复制新的对象。
注意:
1.抽象原型类可以利用Cloneable 接口扩展,也可以直接实现Cloneable接口。尽量设计为抽象的基类。
2.复制一般去重写clone() 方法,进行类的返回。
代码实现:浅克隆
//抽象类 实现 Cloneable
@Data
public abstract class Shape implements Cloneable {
private String id;
protected String type;
//具体业务操作方法
abstract void draw();
public Object clone() {
Object clone = null;
try {
clone = super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return clone;
}
}
//抽象类的 具体实现
public class Circle extends Shape {
public Circle(){
type = "Circle";
}
//具体业务在具体实现中 定义
@Override
public void draw() {
System.out.println("Shape:" + this.type +
"具体业务,画了个Circle ");
}
}
//具体实现2
public class Rectangle extends Shape {
public Rectangle() {
type = "Rectangle";
}
@Override
public void draw() {
System.out.println("Shape:" + this.type +
"具体业务,画了个Rectangle ");
}
}
//具体实现3
public class Square extends Shape {
public Square(){
type = "Square";
}
//具体业务3的实现
@Override
public void draw() {
System.out.println("Shape:" + this.type +
" 具体业务,画了个 Square");
}
}
//模拟原型库信息
public class ShapeData {
private static Hashtable<String, Shape> shapeMap
= new Hashtable<>();
public static Shape getShape(String shapeId) {
Shape cachedShape = shapeMap.get(shapeId);
return (Shape) cachedShape.clone();
}
// 添加具体业务,如:添加三种形状
public static void loadCache() {
Circle circle = new Circle();
circle.setId("c");
shapeMap.put(circle.getId(), circle);
Square square = new Square();
square.setId("s");
shapeMap.put(square.getId(), square);
Rectangle rectangle = new Rectangle();
rectangle.setId("r");
shapeMap.put(rectangle.getId(), rectangle);
}
}
//模拟应用客户端
public class ClientDemo {
public static void main(String[] args) {
//初始化 原型库
ShapeData.loadCache();
Shape clonedShape = ShapeData.getShape("s");
clonedShape.draw();
Shape clonedShape2 = ShapeData.getShape("c");
clonedShape2.draw();
Shape clonedShape3 = ShapeData.getShape("r");
clonedShape3.draw();
}
}
深克隆:
1.Serializable接口,利用序列化
//序列化 -深克隆
public Object deepClone(){
//创建流对象
ByteArrayInputStream bis=null;
ByteArrayOutputStream bos=null;
ObjectInputStream ois=null;
ObjectOutputStream oos=null;
try{
bos=new ByteArrayOutputStream();
oos=new ObjectOutputStream(bos);
oos.writeObject(this);
bis=new ByteArrayInputStream(bos.toByteArray());
ois=new ObjectInputStream(bis);
Square o = (Square) ois.readObject();
return o;
} catch (ClassNotFoundException | IOException e) {
e.printStackTrace();
return null;
}
- 就是在克隆对象的时候,对该对象的对象字段进行克隆,然后进行重新赋值。
protected Object clone() throws CloneNotSupportedException {
//需要可用的类
PClass deep=null;
deep=super.clone();
PClass d=(PClass) deep;
//克隆类中的对象实体
d.sClass= (sClass) sClass.clone();
return d;
}
好了,关于原型模式的说明,馆长就先讲到这里。谢谢各位看官!!
23 种设计模式不是孤立存在的,很多模式之间存在一定的关联关系,在大的系统开发中常常同时使用多种设计模式,或者模式与模式之间的组合进行生成更加强大的程序功能。