原型模式是创建型模式。
设计意图:用原型实例指定创建对象的类型,并通过拷贝这个原型来创建新的对象。
我们使用构建简历的样例的类图来说明原型模式。
类图:
原型模式主要用于对象的复制。它的核心是就是类图中的原型类Prototype。这里我们定义了一个抽象的原型接口,声明了用于clone自己的方法,这里我们已创建简历为详细原型类,Prototype类须要具备下面两个条件:
- 实现Cloneable接口。在java语言有一个Cloneable接口,它的作用仅仅有一个。就是在执行时通知虚拟机能够安全地在实现了此接口的类上使用clone方法。
在java虚拟机中,仅仅有实现了这个接口的类才干够被拷贝,否则在执行时会抛出CloneNotSupportedException异常。
- 重写Object类中的clone方法。
Java中,全部类的父类都是Object类,Object类中有一个clone方法,作用是返回对象的一个拷贝,可是其作用域protected类型的。一般的类无法调用,因此。Prototype类须要将clone方法的作用域改动为public类型。
原型模式是一种比較简单的模式,也非常easy理解,实现一个接口,重写一个方法即完毕了原型模式。在实际应用中,原型模式非常少单独出现。经常与其它模式混用,他的原型类Prototype也经常使用抽象类来替代,这里我们在原型类上加了一个接口。该接口类继承的Cloneable接口,这样我们能够在我们自己接口中更灵活的控制详细原型类的逻辑是什么。
package com.prototype; /** * @author gaoxu * 实践出真知! */ public interface IPrototype extends Cloneable{ public Prototype clone(); public void show(); }
package com.prototype; /**原型抽象类。採用原型抽象类。能够使详细原型类有很多其它的可复用的属性实现 * @author gaoxu * 实践出真知。 */ public abstract class Prototype implements IPrototype{ String name = ""; String mobile = ""; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getMobile() { return mobile; } public void setMobile(String mobile) { this.mobile = mobile; } @Override public Prototype clone() { Prototype prototype = null; try { prototype = (Prototype) super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return prototype; } public String toString(){ return "mobile="+mobile+",name="+name; } }
package com.prototype; /** * 简历原型实现类 * * @author gaoxu 实践出真知。 */ public class Resume extends Prototype { @Override public void show() { System.out.println(""+toString()); } }
package com.prototype; /** * @author gaoxu * 实践出真知!原型模式的长处和适用场景:*/ public class Client { /** * @param args */ public static void main(String[] args) { Resume resume = new Resume(); resume.setName("高旭"); resume.setMobile("1390000111"); Resume resume1 = (Resume) resume.clone(); Resume resume2 = (Resume) resume.clone(); System.out.println(resume.toString()); System.out.println(resume1.toString()); System.out.println(resume2.toString()); } }
最大的长处就是创建对象性能好。比new要快不少,由于Object类的clone方法是一个本地方法,它直接操作内存中的二进制流,特别是复制大对象时,性能的区别很明显。所以须要反复创建对象的场景基本都能够适用。
原型模式的注意事项
- 使用原型模式复制对象不会调用类的构造方法。由于对象的复制是通过调用Object类的clone方法来完毕的,它直接在内存中复制数据。不用又一次初始化,直接获得对象执行时的状态。
不但构造方法中的代码不会执行,甚至连訪问权限都对原型模式无效。
单例模式中,仅仅要将构造方法的訪问权限设置为private型。就能够实现单例。可是clone方法直接无视构造方法的权限。所以,单例模式与原型模式是冲突的,所以不能把单例模式的类对象进行拷贝,那样就不是单例了。