[设计模式]原型模式

简介

原型模式 (Prototype)用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

原型模式是一种对象创建型模式可参考 设计模式 创建型模式)。

结构

图-原型模式结构图

Prototype:声明一个克隆自身的接口。 ConcretePrototype:实现克隆自身的具体操作。 Client:调用 Prototype 来克隆自身,从而创建一个新对象。

动机

当要实例化的类是在运行时刻指定时,例如,通过动态装载。 为了避免创建一个与产品类层次平行的工厂类层次时。 当一个类的实例只能有几个不同状态组合中的一种时。建立相应数目的原型并克隆它们可能比每次用合适的状态手工实例化该类更方便一些。 

浅拷贝与深拷贝

浅拷贝是指当对象的字段值被复制时,字段引用的对象不会被复制。 例如:如果一个对象有一个指向字符串的字段,并且我们对该对象做了一个浅拷贝,那麽两个对象将引用同一个字符串。 深拷贝是指当一个类拥有资源,当这个类的对象发生复制过程的时候,资源重新分配,这个过程就是深拷贝。

实例

原型模式主要用于对象的复制,它的核心是就是类图中的原型类Prototype。Prototype类需要具备以下两个条件:

  1. 实现Cloneable接口。在java语言有一个Cloneable接口,它的作用只有一个,就是在运行时通知虚拟机可以安全地在实现了此接口的类上使用clone方法。在java虚拟机中,只有实现了这个接口的类才可以被拷贝,否则在运行时会抛出CloneNotSupportedException异常。
  2. 重写Object类中的clone方法。Java中,所有类的父类都是Object类,Object类中有一个clone方法,作用是返回对象的一个拷贝,但是其作用域protected类型的,一般的类无法调用,因此,Prototype类需要将clone方法的作用域修改为public类型。

原型模式是一种比较简单的模式,也非常容易理解,实现一个接口,重写一个方法即完成了原型模式。在实际应用中,原型模式很少单独出现。经常与其他模式混用,他的原型类Prototype也常用抽象类来替代。 

代码

class Prototype implements Cloneable {
 public Prototype clone() {
         Prototype prototype = null;
 try {
             prototype = (Prototype)super.clone();
         } catch (CloneNotSupportedException e) {
             e.printStackTrace();
         }
 return prototype;
     }
 }
 
 class ConcretePrototype extends Prototype {
 public void show() {
         System.out.println("原型模式实现类");
     }
 }
 
 public class PrototypePattern {
 public static void main(String[] args) {
         ConcretePrototype cp = new ConcretePrototype();
 for(int i=0; i< 10; i++){  
             ConcretePrototype clonecp = (ConcretePrototype)cp.clone();  
             clonecp.show();  
         }  
     }
 }

推荐阅读

本文属于 设计模式系列

参考资料

《大话设计模式》 《HeadFirst设计模式》

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏C语言及其他语言

【每日一题】问题 1183: 人见人爱A+B

北大的acm上面已经有10来道A+B的题目了,相信这些题目曾经是大家的最爱,希望今天的这个A+B能给大家带来好运,也希望这个题目能唤起大家对ACM曾经的热爱。...

1372
来自专栏绿巨人专栏

学习Scala: 初学者应该了解的知识

2904
来自专栏微信公众号:Java团长

JAVA之旅(一)——基本常识,JAVA概念,开发工具,关键字/标识符,变量/常量,进制/进制转换,运算符,三元运算

比如6:6/2 = 3 余 0 3 / 2 = 1 余 1 那就是从个位数开始011,读起来就是110了

1801
来自专栏angularejs学习篇

angularjs学习第三天笔记(过滤器第二篇---filter过滤器及其自定义过滤器)

您好,我是一名后端开发工程师,由于工作需要,现在系统的从0开始学习前端js框架之angular,每天把学习的一些心得分享出来,如果有什么说的不对的地方,请多多指...

983
来自专栏Phoenix的Android之旅

说一个小bug

这个bug其实很简单,因为String是不可变内容的,想获得新值,必须重新赋值。正确应该是

1033
来自专栏CDA数据分析师

Python程序员鲜为人知但你应该知道的16个问题

这篇文章主要介绍了Python程序员代码编写时应该避免的16个“坑”,也可以说成Python程序员代码编写时应该避免的16个问题,需要的朋友可以参考。 1. ...

2047
来自专栏用户2442861的专栏

sizeof小览

http://blog.csdn.net/scythe666/article/details/47012347

851
来自专栏分布式系统和大数据处理

四种简单的排序算法

我觉得如果想成为一名优秀的开发者,不仅要积极学习时下流行的新技术,比如WCF、Asp.Net MVC、AJAX等,熟练应用一些已经比较成熟的技术,比如Asp.N...

1402
来自专栏编程

您真的会用switch吗?

C语言的理念,程序员应该知道自己正在干什么,而且保证自己的所作所为是正确的。 switch知多少 各个case和default的顺序可以是任意的,但习惯上总是d...

2137
来自专栏赵俊的Java专栏

LeetCode 657 Robot Return to Origin

这道题很简单,只需要假设当前节点是 0, 0,定义两个变量, i 和 j,默认值都为 0,每当向上 i + 1,向下 i - 1,向右 j + 1,向左 j -...

1042

扫码关注云+社区

领取腾讯云代金券