设计模式(1)--Prototype(原型模式)--创建型
1.模式定义:
2.使用场景:
3.模式实现:
(1)简单形式:
[1].客户(Client)角色:客户类提出创建对象的请求。
public class Client {
// 持有需要使用的原型接口对象
private Prototype prototype;
// 构造方法,传入需要使用的原型接口对象
public Client(Prototype prototype){
this.prototype = prototype;
}
public void operation(Prototype example){
//需要创建原型接口的对象
Prototype copyPrototype = prototype.clone();
}
}
[2].抽象原型(Prototype)角色:这是一个抽象角色,通常由一个Java接口或Java抽象类实现。此角色给出所有的具体原型类所需的接口。
public interface Prototype{
public Object clone();
}
[3].具体原型(Concrete Prototype)角色:被复制的对象。此角色需要实现抽象的原型角色所要求的接口。
public class ConcretePrototype1 implements Prototype {
public Prototype clone(){
//最简单的克隆,新建一个自身对象,由于没有属性就不再复制值了
Prototype prototype = new ConcretePrototype1();
return prototype;
}
}
public class ConcretePrototype2 implements Prototype {
public Prototype clone(){
//最简单的克隆,新建一个自身对象,由于没有属性就不再复制值了
Prototype prototype = new ConcretePrototype2();
return prototype;
}
}
(2)登记形式
[1].客户(Client)角色:客户类提出创建对象的请求。
public class Client {
public static void main(String[]args){
try{
Prototype p1 = new ConcretePrototype1();
PrototypeManager.setPrototype("p1", p1);
//获取原型来创建对象
Prototype p3 = PrototypeManager.getPrototype("p1").clone();
p3.setName("张三");
System.out.println("第一个实例:" + p3);
//有人动态的切换了实现
Prototype p2 = new ConcretePrototype2();
PrototypeManager.setPrototype("p1", p2);
//重新获取原型来创建对象
Prototype p4 = PrototypeManager.getPrototype("p1").clone();
p4.setName("李四");
System.out.println("第二个实例:" + p4);
//有人注销了这个原型
PrototypeManager.removePrototype("p1");
//再次获取原型来创建对象
Prototype p5 = PrototypeManager.getPrototype("p1").clone();
p5.setName("王五");
System.out.println("第三个实例:" + p5);
}catch(Exception e){
e.printStackTrace();
}
}
}
[2].抽象原型(Prototype)角色:这是一个抽象角色,通常由一个Java接口或Java抽象类实现。此角色给出所有的具体原型类所需的接口。
public interface Prototype{
public Prototype clone();
public String getName();
public void setName(String name);
}
[3].具体原型(Concrete Prototype)角色:被复制的对象。此角色需要实现抽象的原型角色所要求的接口。
public class ConcretePrototype1 implements Prototype {
private String name;
public Prototype clone(){
ConcretePrototype1 prototype = new ConcretePrototype1();
prototype.setName(this.name);
return prototype;
}
public String toString(){
return "Now in Prototype1 , name = " + this.name;
}
@Override
public String getName() {
return name;
}
@Override
public void setName(String name) {
this.name = name;
}
}
public class ConcretePrototype2 implements Prototype {
private String name;
public Prototype clone(){
ConcretePrototype2 prototype = new ConcretePrototype2();
prototype.setName(this.name);
return prototype;
}
public String toString(){
return "Now in Prototype2 , name = " + this.name;
}
@Override
public String getName() {
return name;
}
@Override
public void setName(String name) {
this.name = name;
}
}
[4].原型管理器(PrototypeManager)角色:创建具体原型类的对象,并记录每一个被创建的对象。
public class PrototypeManager {
/**
* 用来记录原型的编号和原型实例的对应关系
*/
private static Map<String,Prototype> map = new HashMap<String,Prototype>();
/**
* 私有化构造方法,避免外部创建实例
*/
private PrototypeManager(){}
/**
* 向原型管理器里面添加或是修改某个原型注册
* @param prototypeId 原型编号
* @param prototype 原型实例
*/
public synchronized static void setPrototype(String prototypeId , Prototype prototype){
map.put(prototypeId, prototype);
}
/**
* 从原型管理器里面删除某个原型注册
* @param prototypeId 原型编号
*/
public synchronized static void removePrototype(String prototypeId){
map.remove(prototypeId);
}
/**
* 获取某个原型编号对应的原型实例
* @param prototypeId 原型编号
* @return 原型编号对应的原型实例
* @throws Exception 如果原型编号对应的实例不存在,则抛出异常
*/
public synchronized static Prototype getPrototype(String prototypeId) throws Exception{
Prototype prototype = map.get(prototypeId);
if(prototype == null){
throw new Exception("您希望获取的原型还没有注册或已被销毁");
}
return prototype;
}
}
(3).浅克隆
[1].金箍棒:GoldRingedStaff.java
public class GoldRingedStaff {
private float height = 100.0f;
private float diameter = 10.0f;
/**
* 增长行为,每次调用长度和半径增加一倍
*/
public void grow(){
this.diameter *= 2;
this.height *= 2;
}
/**
* 缩小行为,每次调用长度和半径减少一半
*/
public void shrink(){
this.diameter /= 2;
this.height /= 2;
}
}
[2].大圣本身:Monkey.java
public class Monkey implements Cloneable {
//身高
private int height;
//体重
private int weight;
//生日
private Date birthDate;
//金箍棒
private GoldRingedStaff staff;
/**
* 构造函数
*/
public Monkey(){
this.birthDate = new Date();
this.staff = new GoldRingedStaff();
}
/**
* 克隆方法
*/
public Object clone(){
Monkey temp = null;
try {
temp = (Monkey) super.clone();
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
return temp;
}
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public Date getBirthDate() {
return birthDate;
}
public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
}
public GoldRingedStaff getStaff() {
return staff;
}
public void setStaff(GoldRingedStaff staff) {
this.staff = staff;
}
}
[3].克隆实现:TheGreatestSage.java
public class TheGreatestSage {
private Monkey monkey = new Monkey();
public void change(){
//克隆大圣本尊
Monkey copyMonkey = (Monkey)monkey.clone();
System.out.println("大圣本尊的生日是:" + monkey.getBirthDate());
System.out.println("克隆的大圣的生日是:" + monkey.getBirthDate());
System.out.println("大圣本尊跟克隆的大圣是否为同一个对象 " + (monkey == copyMonkey));
System.out.println("大圣本尊持有的金箍棒 跟 克隆的大圣持有的金箍棒是否为同一个对象? " + (monkey.getStaff() == copyMonkey.getStaff()));
}
public static void main(String[]args){
TheGreatestSage sage = new TheGreatestSage();
sage.change();
}
}
(4).深克隆
[1].金箍棒:GoldRingedStaff.java
public class GoldRingedStaff implements Serializable{
private float height = 100.0f;
private float diameter = 10.0f;
/**
* 增长行为,每次调用长度和半径增加一倍
*/
public void grow(){
this.diameter *= 2;
this.height *= 2;
}
/**
* 缩小行为,每次调用长度和半径减少一半
*/
public void shrink(){
this.diameter /= 2;
this.height /= 2;
}
}
[2].大圣本身:Monkey.java
public class Monkey implements Cloneable,Serializable {
//身高
private int height;
//体重
private int weight;
//生日
private Date birthDate;
//金箍棒
private GoldRingedStaff staff;
/**
* 构造函数
*/
public Monkey(){
this.birthDate = new Date();
staff = new GoldRingedStaff();
}
/**
* 克隆方法
*/
public Object clone(){
Monkey temp = null;
try {
temp = (Monkey) super.clone();
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
return temp;
}
}
public Object deepClone() throws IOException, ClassNotFoundException{
//将对象写到流里
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
//从流里读回来
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return ois.readObject();
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public Date getBirthDate() {
return birthDate;
}
public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
}
public GoldRingedStaff getStaff() {
return staff;
}
public void setStaff(GoldRingedStaff staff) {
this.staff = staff;
}
}
[3].克隆实现:TheGreatestSage.java
public class TheGreatestSage {
private Monkey monkey = new Monkey(); public void change() throws IOException, ClassNotFoundException{
Monkey copyMonkey = (Monkey)monkey.deepClone();
System.out.println("大圣本尊的生日是:" + monkey.getBirthDate());
System.out.println("克隆的大圣的生日是:" + monkey.getBirthDate());
System.out.println("大圣本尊跟克隆的大圣是否为同一个对象 " + (monkey == copyMonkey));
System.out.println("大圣本尊持有的金箍棒 跟 克隆的大圣持有的金箍棒是否为同一个对象? " + (monkey.getStaff() == copyMonkey.getStaff()));
}
public static void main(String[]args) throws IOException, ClassNotFoundException{
TheGreatestSage sage = new TheGreatestSage();
sage.change();
}
}
4.优缺点:
(1)原型模式的优点
(2)原型模式的缺点
设计模式(1)--Prototype(原型模式)--创建型的更多相关文章
- Prototype原型模式(创建型模式)
1.原型模式解决的问题 现在有一个抽象的游戏设施建造系统,负责构建一个现代风格和古典风格的房屋和道路. 前提:抽象变化较慢,实现变化较快(不稳定) 整个抽象的游戏设施建造系统相对变化较慢,本例中只有一 ...
- 设计模式(五):PROTOTYPE原型模式 -- 创建型模式
1.定义 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 2.适用场景 原型模式的主要思想是基于现有的对象克隆一个新的对象出来,一般是有对象的内部提供克隆的方法,通过该方法返回一个对 ...
- C#面向对象设计模式纵横谈——6.Prototype 原型模式(创建型模式)
动机(Motivation) 在软件系统中,经常面临着“某些结构复杂的对象”的创建工作.由于需求的变化,这些对象经常面临着剧烈的变化,但他们却拥有比较稳定一致的接口. 如何应对这种变化?如何向“客户程 ...
- 设计模式<1>------单例模式和原型模式------创建型
原文引自:http://www.cnblogs.com/lonelyxmas/p/3720808.html 单例模式 单例模式就是保证在整个应用程序的生命周期中,在任何时刻,被指定的类只有一个实例,并 ...
- Prototype原型(创建型模式)
依赖关系的倒置:抽象不应该依赖于实现的细节,实现细节应该依赖于抽象. 原型模式的定义 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象.prototype模式允许一个对象再创建另外一个可 ...
- Java设计模式:Prototype(原型)模式
概念定义 使用原型实例指定待创建对象的种类,并通过拷贝该原型来创建新的对象.Prototype模式允许一个原型对象克隆(复制)出多个与其相同的对象,而无需知道任何如何创建的细节. 应用场景 对象的创建 ...
- 设计模式(2)--Singleton--单例模式--创建型
1.模式定义: 单例模式确保一个类只有一个实例,而且自行实例化并向整个系统提供这个实例. 2.模式特点: (1)单例类只能有一个实例. (2)单例类必须自己创建自己的唯一实例. (3)单例类必须给所有 ...
- 设计模式(5)--Builder(建造模式)--创建型
1.模式定义: 建造模式是对象的创建模式.建造模式可以将一个产品的内部表象(internal representation)与产品的生产过程分割开来,从而可以使一个建造过程生成具有不同的内部表象的产品 ...
- FactoryMethod工厂方法模式(创建型模式)
1.工厂方法模式解决的问题 现在有一个抽象的游戏设施建造系统,负责构建一个现代风格和古典风格的房屋和道路. 前提:抽象变化较慢,实现变化较快(不稳定) 整个抽象的游戏设施建造系统相对变化较慢,本例中只 ...
随机推荐
- Example018主页加载时获取焦点
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- docker 17 安装
docker17 安装 新增一键安装命令: curl -sSL https://get.docker.com/ | sh 以下为手动安装过程 翻译自 Get Docker for Ubuntu Doc ...
- href 和 src 区别
去网上百度了一下,感觉还是没有清楚的定义,所以自己稍稍的总结了一下: 1 html标签分为行类元素 和块元素 在加空元素(也可以叫做替换元素img input iframe):当元素为替换元素的时候, ...
- Struts 框架 之 文件上传下载案例
Struts 框架 文件上传 1. 先准备 Struts 环境 (我使用的是struts 2.3.4版本) 导jar包:
- JavaMail 邮件开发
(api + 配置) 开发中,邮件的应用? -à 注册,填写生日: 后期系统会自动发送生日祝贺 -à 发货,发货提醒!邮件提醒! 邮件: 1. 发邮件:[程序中如何发邮件!] 2. 收邮件:[ ...
- Samba远程代码执行漏洞(CVE-2017-7494)本地复现
一.复现环境搭建 搭建Debian和kali两个虚拟机: 攻击机:kali (192.168.217.162): 靶机:debian (192.168.217.150). 二.Debian安装并配置s ...
- win10 Internet Explorer 11 停止工作处理
win10 Internet Explorer 11 停止工作处理:
- Spring Boot 系列(四)静态资源处理
在web开发中,静态资源的访问是必不可少的,如:图片.js.css 等资源的访问. spring Boot 对静态资源访问提供了很好的支持,基本使用默认配置就能满足开发需求. 一.默认静态资源映射 S ...
- Java项目集成SAP BO
SAP BO报表查看需要登录SAP BO系统,为了方便公司希望将BO报表集成到OA系统中,所以参考网上资料加上与SAP BO的顾问咨询整理出一套通过Java来集成SAP BO的功能. SAPBO中的报 ...
- Git操作大全[实际用到的都放在这里总结]
1.如何合并远程两个分支feature-rebuild和develop? g fetch g checkout -b develop origin/develop g merge feature-re ...