原型模式:做到是原型,那肯定是自己本身才是原型,原型模式属于对象的创建模式。

   关于原型模式的实现方式分2种:

         (1)简单形式、(2)登记形式,这两种表现形式仅仅是原型模式的不同实现。

 package inter.method;
/**
* 提供一个具有复制本身的接口
* @author zengrong
*
*/
public interface Prototype { public Object clone();
}
 package impl.method;

 import inter.method.Prototype;

 public class ConcretePrototype1 implements Prototype {
/**
* 接口类对象使用了object,所有在复写时候,类型就随便都是可以的
*/
public Prototype clone(){
//最简单的克隆,新建一个自身对象,由于没有属性就不再复制值了
Prototype prototype = new ConcretePrototype1();
return prototype;
}
}
 package impl.method;

 import inter.method.Prototype;

 /**
* 客户端
* @author zengrong
*
*/
public class Client { /**
* 需要创建的原型
*/ private Prototype prototype; public Client( Prototype prototype){
this.prototype=prototype;
}
/**
* 创建原型
*/
public void create () {
Prototype cloneprototype = (Prototype) prototype.clone();
}
}

第二种原型模式:登记模式。就是价将原先进行实例的方式是客户端和原型直接联系,这样耦合性高,解决办法就是设置一个管理器进行来管理生成这些原型,

 package inter.pro.two;

 import java.util.HashMap;
import java.util.Map; /**
* 原型管理器
* @author zengrong
*,作为对所有原型对象的登记,
*这个角色提供必要的方法,
*供外界增加新的原型对象和取得已经登记过的原型对象。
*/
public class PromManger {
/**
* 用来记录原型
*/
private static Map<String,PrototypeTwo> map = new HashMap<String,PrototypeTwo>(); private PromManger(){}//私有化构造 /**
* 设置一个方法来进行向原型集合中添加
*/
public synchronized static void setPrototypes(String prototypeId,PrototypeTwo prototypeTwo) {
map.put(prototypeId, prototypeTwo); }
/**
* 从原型管理器里面删除某个原型注册
* @param prototypeId 原型编号
*/
public synchronized static void removePrototype(String prototypeId){
map.remove(prototypeId);
} /**
* 获取原型
*/
public synchronized static PrototypeTwo getPrototypeTwo( String prototypeId) {
PrototypeTwo prototypeTwo = map.get(prototypeId);
if(prototypeTwo==null){
System.out.println("该原型还没有进行登记注册------无法获取---");
}
return prototypeTwo;
} }
 package inter.pro.two;

 public class PrototypeCol implements PrototypeTwo {
private String name;
public PrototypeTwo clone(){
PrototypeCol prototype = new PrototypeCol();
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;
}
}
 package inter.pro.two;
/**
*
* @author zengrong
*
*/
public interface PrototypeTwo {
/**
* 具体的原型
* @return
*/
public PrototypeTwo clone();
public String getName();
public void setName(String name); }

简单原型和登记原型对比:

      在原型数量很少的情况下,采用第一种方式,客户端呢保存原型,

      但是在数量不确定的情况下,采用第二中方式,在复制一个原型对象之前,客户端可以查看管理员对象是否已经有一个满足要求的原型对象。如果有,可以直接从管理员类取得这个对象引用;如果没有,客户端就需要自行复制此原型对象。

在Java中有个方法和这个其实是一样的,Java中得克隆方法;

  Java的所有类都是从java.lang.Object类继承而来的,而Object类提供protected Object clone()方法对对象进行复制,子类当然也可以把这个方法置换掉,提供满足自己需要的复制方法。对象的复制有一个基本问题,就是对象通常都有对其他的对象的引用。当使用Object类的clone()方法来复制一个对象时,此对象对其他对象的引用也同时会被复制一份

  Java语言提供的Cloneable接口只起一个作用,就是在运行时期通知Java虚拟机可以安全地在这个类上使用clone()方法。通过调用这个clone()方法可以得到一个对象的复制。由于Object类本身并不实现Cloneable接口,因此如果所考虑的类没有实现Cloneable接口时,调用clone()方法会抛出CloneNotSupportedException异常。

克隆满足的条件

clone()方法将对象复制了一份并返还给调用者。所谓“复制”的含义与clone()方法是怎么实现的。一般而言,clone()方法满足以下的描述:

  (1)对任何的对象x,都有:x.clone()!=x。换言之,克隆对象与原对象不是同一个对象。

  (2)对任何的对象x,都有:x.clone().getClass() == x.getClass(),换言之,克隆对象与原对象的类型一样。

  (3)如果对象x的equals()方法定义其恰当的话,那么x.clone().equals(x)应当成立的。

  在JAVA语言的API中,凡是提供了clone()方法的类,都满足上面的这些条件。JAVA语言的设计师在设计自己的clone()方法时,也应当遵守着三个条件。一般来说,上面的三个条件中的前两个是必需的,而第三个是可选的。

在这里其实涉及到一个值传递和引用传递!

 

  

5.设计模式----prototype原型模式的更多相关文章

  1. 一天一个设计模式——Prototype 原型模式

    一.模式说明 看了比较多的资料,对原型模式写的比较复杂,个人的理解就是模型复制,根据现有的类来直接创建新的类,而不是调用类的构造函数. 那为什么不直接调用new方法来创建类的实例呢,主要一个原因是如果 ...

  2. 设计模式:Prototype 原型模式 - 同学你抄过别人的作业么?-clone()方法的使用

    原型模式: 通过某个类的实例来创建对象 使用原型模式的好处: 好处是什么呢?当我们需要多次重复的创建一个类的示例的时候,我们可以使用new但是,new不仅仅耗费内存而且,如果new 某个类的构造方法中 ...

  3. C++设计模式-Prototype原型模式

    作用: 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. Prototype模式提供了一个通过已存在对象进行新对象创建的接口(Clone), Clone()实现和具体的语言相关,在C+ ...

  4. 设计模式_11_原型模式(prototype)深拷贝、浅拷贝

    设计模式_11_原型模式(prototype) 浅拷贝: package designPatternOf23; /** * 定义:用原型实例,指定创建对象的种类,并通过拷贝这些原型创建新的对象 * P ...

  5. 乐在其中设计模式(C#) - 原型模式(Prototype Pattern)

    原文:乐在其中设计模式(C#) - 原型模式(Prototype Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 原型模式(Prototype Pattern) 作者:weba ...

  6. C#设计模式之六原型模式(Prototype)【创建型】

    一.引言 在开始今天的文章之前先说明一点,欢迎大家来指正.很多人说原型设计模式会节省机器内存,他们说是拷贝出来的对象,这些对象其实都是原型的复制,不会使用内存.我认为这是不对的,因为拷贝出来的每一个对 ...

  7. C#设计模式之五原型模式(Prototype Pattern)【创建型】

    一.引言 在开始今天的文章之前先说明一点,欢迎大家来指正.很多人说原型设计模式会节省机器内存,他们说是拷贝出来的对象,这些对象其实都是原型的复制,不会使用内存.我认为这是不对的,因为拷贝出来的每一个对 ...

  8. C#设计模式(6)——原型模式(Prototype Pattern) C# 深浅复制 MemberwiseClone

    C#设计模式(6)——原型模式(Prototype Pattern)   一.引言 在软件系统中,当创建一个类的实例的过程很昂贵或很复杂,并且我们需要创建多个这样类的实例时,如果我们用new操作符去创 ...

  9. 设计模式05: Prototype 原型模式(创建型模式)

    Prototype 原型模式(创建型模式) 依赖关系的倒置抽象不应该依赖于实现细节,细节应该依赖于抽象.对所有的设计模式都是这样的. -抽象A直接依赖于实现细节b -抽象A依赖于抽象B,实现细节b依赖 ...

随机推荐

  1. Git 历险记(三)——创建一个自己的本地仓库

    如果我们要把一个项目加入到Git的版本管理中,可以在项目所在的目录用git init命令建立一个空的本地仓库,然后再用git add命令把它们都加入到Git本地仓库的暂存区(stage or inde ...

  2. log4j教程 12、日志记录到数据库

    log4j API提供 org.apache.log4j.jdbc.JDBCAppender 对象,它能够将日志信息在指定的数据库. JDBCAppender 配置: Property 描述 buff ...

  3. Protractor(angular定制的e2e)的简易入门

    这周项目终于上了e2e的测试,之前一直都没有测试的概念. 感谢我的领导和同志引入这样的理念和思想. 多的不说. 具体的环境搭建可以参考 http://jackhu.top/article/5607fa ...

  4. IOS开发通过代码方式使用AutoLayout (NSLayoutConstraint + Masonry) 转载

    http://blog.csdn.net/he_jiabin/article/details/48677911 随着iPhone6/6+设备的上市,如何让手头上的APP适配多种机型多种屏幕尺寸变得尤为 ...

  5. Pro Tools安装图文教程

    Pro Tools安装图文教程   Avid Pro Tools是Digidesign公司出品的一款音质最佳.音频制作强大的软件,能够在Mac或PC上为影片编曲.录制.编辑和混制高品质音乐或声音,生成 ...

  6. 【BIEE】07_调整BIEE柱子的显示顺序

    现在有报表如下: 但是我们觉得这种显示不好看,想把非优秀员工的柱子放在前边显示,那么如何调整呢? 调整步骤: [编辑分析] 我们将此处条形图下的两个标签顺序重新调整一下 从上图可以看出,效果明显!

  7. (一)Thymeleaf用法——Thymeleaf简介

    1. thymeleaf认识 参考官方文档(Project version: 3.0.5.RELEASE)   1.1 介绍 Thymeleaf是面向Web和独立环境的现代服务器端Java模板引擎,能 ...

  8. E - Hangover(1.4.1)

    Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u Submit cid=1006#sta ...

  9. 手动建立storybook

    1. Add @storybook/react npm i --save-dev @storybook/react 2. Add react, react-dom, and babel-core np ...

  10. (三)spark算子 分为3大类

    ation算子通过sparkContext执行提交作业的runJob,触发rdd的DAG执行 (foreach) foreach(f) 会对rdd中的每个函数进行f操作,下面的f操作就是打印输出没有元 ...