-
简介:
- Prototype原型模式是一种创建型设计模式,Prototype模式允许一个对象再创建另外一个可定制的对象,根本无需知道任何如何创建的细节,工作原理是:通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝它们自己来实施创建。
-
定义:
- 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
-
组成:
- 客户(Client)客户端,让原型对象克隆自身创建新对象
- 抽象原型类:声明克隆方法的接口,是所有具体原型类的公共父类,它可以是抽象类也可以是接口
- 具体原型类:它实现抽象原型类中声明的克隆方法,在克隆方法中返回自己的一个克隆对象
-
步骤:
-
定义一个消息模板类,用来统一通知消息的模板
-
package com.lvsling.prototype; /** * 活动通知模板 * @author Administrator * */ public class AdvTemplate { private String advSubject = "超市抽奖活动"; private String advContext = "超市国庆抽奖活动通知:只要购物就送奖励"; public String getAdvSubject() { return advSubject; } public void setAdvSubject(String advSubject) { this.advSubject = advSubject; } public String getAdvContext() { return advContext; } public void setAdvContext(String advContext) { this.advContext = advContext; }
} |
-
定义一个Mial类,也就是具体原型类,实现Cloneable(这里代表抽象原型类)接口
package com.lvsling.prototype; public class Mail implements Cloneable{ private String receiver; private String sbuject; private String appelation; private String contxt; private String tail;
public Mail(AdvTemplate advTemplate) { this.contxt = advTemplate.getAdvContext(); }
@Override protected Mail clone() throws CloneNotSupportedException { Mail mail = null; //使用此方法来获取对象引用 mail = (Mail) super.clone(); return mail; } public String getReceiver() { return receiver; } public void setReceiver(String receiver) { this.receiver = receiver; } public String getSbuject() { return sbuject; } public void setSbuject(String sbuject) { this.sbuject = sbuject; } public String getAppelation() { return appelation; } public void setAppelation(String appelation) { this.appelation = appelation; } public String getContxt() { return contxt; } public void setContxt(String contxt) { this.contxt = contxt; } public String getTail() { return tail; } public void setTail(String tail) { this.tail = tail; }
} |
-
定义一个Client客户端,让原型对象克隆而创建一个新对象。
package com.lvsling.prototype; public class ClientMain {
public static void main(String[] args) throws CloneNotSupportedException { Mail mail = new Mail(new AdvTemplate()); mail.setTail("华联超市"); Mail cloneMail = mail.clone(); cloneMail.setAppelation("张先生"); sendMail(cloneMail); }
public static void sendMail(Mail mail) { System.out.println("超市:"+mail.getTail()); System.out.println("收件人:"+mail.getAppelation()); System.out.println("标题:"+mail.getContxt()); } } |
-
控制台打印结果为:
超市:华联超市 收件人:张先生 标题:超市国庆抽奖活动通知:只要购物就送奖励 |
-
优点:
- 当创建对象的实例较为复杂的时候,使用原型模式可以简化对象的创建过程,通过复制一个已有的实例可以提高实例的创建效率。
- 扩展性好,由于原型模式提供了抽象原型类,在客户端针对抽象原型类进行编程,而将具体原型类写到配置文件中,增减或减少产品对原有系统都没有影响。
- 原型模式提供了简化的创建结构,工厂方法模式常常需要有一个与产品类等级结构相同的工厂等级结构,而原型模式不需要这样,圆形模式中产品的复制是通过封装在类中的克隆方法实现的,无需专门的工厂类来创建产品。
- 可以使用深克隆方式保存对象的状态,使用原型模式将对象复制一份并将其状态保存起来,以便在需要的时候使用(例如恢复到历史某一状态),可辅助实现撤销操作。
-
缺点:
- 需要为每一个类配置一个克隆方法,而且该克隆方法位于类的内部,当对已有类进行改造的时候,需要修改代码,违反了开闭原则。
- 在实现深克隆时需要编写较为复杂的代码,而且当对象之间存在多重签到引用时,为了实现深克隆,每一层对象对应的类都必须支持深克隆,实现起来会比较麻烦。
-
应用场景:
- 创建新对象成本较大(例如初始化时间长,占用CPU多或占太多网络资源),新对象可以通过复制已有对象来获得,如果相似对象,则可以对其成员变量稍作修改。
- 系统要保存对象的状态,而对象的状态很小。
- 需要避免使用分层次的工厂类来创建分层次的对象,并且类的实例对象只有一个或很少的组合状态,通过复制原型对象得到新实例可以比使用构造函数创建一个新实例更加方便。
-
总结:
- 以上是原型模式的理解,原型模式通过Object的clone()方法来实现的,是内存操作,无视构造方法和访问权限,直接获取新的对象。在了解一下深拷贝和浅拷贝就OK了