什么是原型模式
什么是原型模式,就是根据一个已经存在的对象实例,复制创建出多个对象实例的设计方法。已经存在的对象实例就是原型对象。原型模式属于创建型的设计模式。
当创建对象的代价交高时,可是使用原型模式复制拷贝对象,这样更做效率更高。
原型模式复制对象一般会用到Object类的clone方法。在Java中实现对象拷贝或克隆,使用clone()方法。
能够实现克隆的Java类必须实现一个标识接口Cloneable,表示这个Java类支持复制。如果一个类没有实现这个接口但是调用了clone()方法,Java编译器将抛出一个CloneNotSupportedException异常。
原型模式的几种使用场景
1、通过 new 产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式,创建原型对象后缓存,再使用该种对象时,返回它的拷贝。
2、一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用。
3、如果想要让生成实例的框架不再依赖于具体的类,这时,不能指定类名来生成实例,而要事先“注册”一个“原型”实例,然后通过复制该实例来生成新的实例。
原型模式代码实现
将创建一个抽象类 Animal和扩展了 Animal类的实体类Cat、Dog。下一步是定义类 AnimalCache,该类把 Animal 对象存储在一个 Hashtable 中,并在请求的时候返回它们的克隆。
1、先定义一个原型抽象类,可以是接口,实现Cloneable接口。
public abstract class Animal implements Cloneable{
// 名字
protected String name;
// 重量
protected float weight;
// 叫声,定义为抽象的
abstract void bark();
// 克隆,此处直接使用object的clone来进行对象拷贝
public Object clone(){
Object clone = null;
try {
clone = super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return clone;
}
}
2、创建两个具体的实体类,继承或实现上面的原型抽象类或接口。
public class Cat extends Animal{
public Cat(String name, float weight){
this.name = name;
this.weight = weight;
}
@Override
void bark() {
System.out.println("猫叫。。。。。");
}
}
public class Dog extends Animal{
public Dog(String name, float weight){
this.name = name;
this.weight = weight;
}
@Override
void bark() {
System.out.println("狗叫。。。。。");
}
}
3、创建一个类,从数据库获取实体类,并把它们存储在一个 Hashtable 中。
public class AnimalCache {
private static Hashtable<String, Animal> animalMap
= new Hashtable<String, Animal>();
public static Animal getAnimal(String name) {
Animal cachedAnimal = animalMap.get(name);
return (Animal) cachedAnimal.clone();
}
public static void loadCache() {
Cat cat = new Cat("tom",50);
animalMap.put("cat",cat);
Dog dog = new Dog("小六",100);
animalMap.put("dog",dog);
}
}
4、创建一个PrototypePatternTest 使用 AnimalCache 类来获取存储在 Hashtable 中的形状的克隆。
public class PrototypePatternTest {
public static void main(String[] args) {
AnimalCache.loadCache();
Animal dog1 = AnimalCache.getAnimal("dog");
Animal dog2 = AnimalCache.getAnimal("dog");
System.out.println(dog1);
System.out.println(dog2);
dog2.bark();
Animal cat2 = AnimalCache.getAnimal("cat");
cat2.bark();
}
}
执行程序,输出结果如下:
com.herp.pattern.prototype.Dog@4554617c
com.herp.pattern.prototype.Dog@74a14482
狗叫。。。。。
猫叫。。。。。
可以看到两个,获取了两次dog对象,每次获取到的都是不同的对象。同时也是原型对象的拷贝。
原型模式类图分析
对应原型模式中具体角色:
Animal:抽象的原型类,可以为抽象类或接口,负责定义用于复制现有实例来生成新实例的方法,也就是克隆或拷贝对象的方法。
Cat和Dog类:具体的原型类。实现复制现有实例并生成新实例的方法。也可以不实现,直接使用抽象原型中实现的拷贝方法。
AnimalCache类:客户类,使用者,负责通过调用原型类的克隆方法生成新对象。
PrototypePatternTest 属于测试类main入口。
(完)
往期设计模式文章回顾。
工厂模式超详解(代码示例)
Java面试必备:手写单例模式
微信公众号