设计模式---原型模式

目录

一、什么是原型模式(Prototype)

二、原型模式的结构

三、原型模式的角色和职责

Prototype

ConcretePrototype

Client

四、原型模式应用场景

五、代码示例

六、理解原型模式

认识原型模式

原型模式功能

原型与new

原型实例和克隆的实例

Java中的克隆方法

浅克隆和深克隆

原型模式的特点

原型管理器

原型模式优缺点

七、思考原型模式

本质

何时选用


一、什么是原型模式(Prototype)

Prototype模式是一种对象创建型模式,它采取复制原型对象的方法来创建对象的实例。

使用 Prototype模式创建的实例,具有与原型一样的数据。

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

二、原型模式的结构

设计模式---原型模式

三、原型模式的角色和职责

Prototype

声明一个克隆自身的接口,用来约束想要克隆自己的类,要求他们都要实现这里定义的克隆方法

ConcretePrototype

实现类,真正实现克隆自身的功能

Client

客户端,首先获取原型实例对象,然后通过原型实例克隆自身来创建新的对象实例

四、原型模式应用场景

- 在创建对象的时候,我们不只是希望被创建的对象继承 其基类的基本结构,还希望继承原型对象的数据。

- 希望对目标对象的修改不影响既有的原型对象(深度克 隆的时候可以完全互不影响)。

- 隐藏克隆操作的细节。很多时候,对对象本身的克隆需 要涉及到类本身的数据细节。

五、代码示例

 

六、理解原型模式

认识原型模式

原型模式功能

1.通过克隆来创建新的对象实例

2.为克隆出来的新的对象实例复制原型实例属性的值

原型模式实现的主要功能就是:通过克隆来创建新的对象实例。一般来讲,新创建出来的实例的数据是和原型实例一样的。但是具体如何实现克隆,需要由程序自行实现,原型模式并没有统一的要求和实现算法

原型与new

原型模式从某种意义上来说,就像是new操作,克隆方法就是使用new来实现的,但请注意,只是“类似new”而不是就是“new”,除了new,还有赋值

克隆方法和new操作最明显的不同在于:new一个对象实例,一般属性是没有值的,或者是只有默认值的;如果是克隆得到的一个实例,通常属性是有值的,属性的值就是原型对象实例在克隆的时候,原型对象实例的属性的值

原型实例和克隆的实例

原型实例和克隆的实例,本质上是不同的实例,克隆完成后,他们之间是没有关联的,如果克隆完成后,克隆出来的实例的属性的值发生了改变,是不会影响到原型实例的。

Java中的克隆方法

Java语言中已经提供了clone方法,定义在object中。需要克隆功能的类,只需要实现java.lang.Cloneable接口,该接口没有需要实现的方法,是一个标识接口。

浅克隆和深克隆

1.浅克隆:只负责克隆按值传递的数据(比如基本类型数据,String类型数据)

2.深克隆:除了浅克隆克隆的数据外,还负责克隆引用类型的数据,基本上就是被克隆实例所有的属性的数据都会被克隆出来

深克隆还有一个特点,就是如果被克隆的对象里面的属性数据是引用类型,也就是属性的类型也是对象,那么需要一直递归的克隆下去。这也意味着,要想深克隆成功,就必须要整个克隆所涉及到的对象都要正确的实现克隆方法,如果其中有一个没有正确实现克隆,就会导致克隆失败。

原型模式的特点

1. 由原型对象自身创建目标对象。也就是说,对象创建这一动作发自原型对象本身。

2.目标对象是原型对象的一个克隆。也就是说,通过Prototype模式创建的对象,不仅仅与原型对象具有相同的结构,还与原型对象具有相同的值。

3.根据对象克隆深度层次的不同,有浅度克隆与深度克隆。

原型管理器

如果一个系统中原型的数目不固定,比如系统中的原型可以被动态的创建和销毁,那么就需要在系统中维护一个当前可用的原型的注册表,称为原型管理器;

其实如果把原型当作一个资源的话,原型管理器就相当于一个资源管理器,在系统开始运行的时候初始化,然后运行期间可以动态的添加资源和销毁资源。从这个角度看,原型管理器就可以相当于一个缓存资源的实现,只不过里面缓存和管理的是原型实例而已。

有了原型管理器过后,一般情况下,除了向原型管理器里面添加原型对象的时候是通过new来创造的对象,其余时候都是通过向原型管理器来请求原型实例,然后通过克隆方法来获取新的对象实例,这样就可以实现动态管理,或者动态切换具体的实现对象实例。

原型模式优缺点

1.对客户端隐藏具体的实现类型

2.在运行时动态地切换具体实现类型

3.深克隆方法实现比较困难

七、思考原型模式

本质

克隆生成对象

何时选用

1.如果一个系统想要独立于他想要使用的对象时,可以使用原型模式,让系统只面向接口编程,在系统需要新的对象的时候,可以通过克隆原型来得到

2.如果需要实例化的类是在运行时动态指定时,可以使用原型模式,通过克隆原型来得到需要的实例