Java实现23种设计模式(三):原型模式
2020-06-10 本文已影响0人
依然慢节奏
二十三种设计模式分类
设计模式三大分类.jpg一、概述
原型(Prototype
)模式的定义如下:用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象。在这里,原型实例指定了要创建的对象的种类。用这种方式创建对象非常高效,根本无须知道对象创建的细节。
优点
1、性能提高。
2、逃避构造函数的约束。
缺点
1、配备克隆方法需要对类的功能进行通盘考虑,这对于全新的类不是很难,但对于已有的类不一定很容易,特别当一个类引用不支持串行化的间接对象,或者引用含有循环结构的时候。
2、必须实现 Cloneable
接口。
场景
1、资源优化场景。
2、类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等。
3、性能和安全要求的场景。
4、通过new
产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式。
5、一个对象多个修改者的场景。
6、一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用。
7、在实际项目中,原型模式很少单独出现,一般是和工厂方法模式一起出现,通过clone
的方法创建一个对象,然后由工厂方法提供给调用者。
二、实现
1. 结构图
原型模式包含以下主要角色:
- 抽象原型类:规定了具体原型对象必须实现的接口。
- 具体原型类:实现抽象原型类的
clone()
方法,它是可被复制的对象。 - 访问类:使用具体原型类中的
clone()
方法来复制新的对象。
PS
:UML
结构图可以参考,例子实现并不根据UML
图来完成,灵活实现即可;
2. 实现
package cn.missbe.model.prototype;
/**
* Copyright (c) 2020.
* Email: love1208tt@foxmail.com
*
* @author lyg 2020/4/29 下午9:36
* description:
* 原型模式:了解即可,用得不多
* 利用已有的一个原型对象,快速地生成和原型对象一样的实例
* Java中的拷贝:深拷贝、浅拷贝
**/
public class Main {
public static void main(String[] args) throws CloneNotSupportedException {
Location location = new Location("贝克街22号", "22号");
Person p = new Person("xx-uu", "18", location);
Person copy = (Person) p.clone();
System.out.println("RelationShip:" + (copy == p));
System.out.println("P:" + p);
System.out.println("Copy:" + copy);
}
}
/**必须实现Cloneable,不然会报CloneNotSupportedException异常*/
class Person implements Cloneable{
private String name;
private String age;
private Location location;
public Person(String name, String age, Location location) {
this.name = name;
this.age = age;
this.location = location;
}
@Override
protected Object clone() throws CloneNotSupportedException {
Person p = (Person) super.clone();
///深拷贝
p.location = (Location) location.clone();
return p;
}
@Override
public String toString() {
return "Person{" + "name='" + name + '\'' + ", age='" + age + '\'' + ", location=" + location + '}';
}
}
/**必须实现Cloneable,不然会报CloneNotSupportedException异常*/
class Location implements Cloneable{
private String street;
private String roomId;
public Location(String street, String roomId) {
this.street = street;
this.roomId = roomId;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString() {
return "Location{" + "street='" + street + '\'' + ", roomId='" + roomId + '\'' + '}';
}
}