- 浏览: 447188 次
- 性别:
- 来自: 杭州
文章分类
- 全部博客 (162)
- easymock (3)
- 模板引擎 (3)
- JForum (4)
- web (9)
- spring (10)
- java (20)
- struts (9)
- uml (3)
- java pattern (19)
- JQuery (14)
- 多线程 (13)
- database (21)
- PS (3)
- ejb (6)
- 版本管理 svn , maven , ant (2)
- protocol (1)
- 测试 (1)
- ws (7)
- Apache (4)
- 脚本语言 (1)
- guice (1)
- 分布式 (4)
- 架构 (0)
- 经验 (1)
- 版本管理 svn (1)
- maven (1)
- ant (1)
- 书籍 (1)
- Linux (1)
最新评论
-
Master-Gao:
稍微明白了点,,有点萌萌哒
为什么匿名内部类参数必须为final类型 -
waw0931:
终于明白了,谢谢!
为什么匿名内部类参数必须为final类型 -
十三圆桌骑士:
提供了两个链接还是有用的。
安装Mondrian -
放方芳:
[flash=200,200][/flash]
Freemarker标签使用 -
放方芳:
[b][/b]
Freemarker标签使用
一. 原型模式简介
原型模式(Prototype Pattern)也是一种创建型模式,它关注的是大量相似对象的创建问题。我们经常会遇到这样的情况:在系统中要创建大量的对象,这些对象之间具有几乎完全相同的功能,只是在细节上有一点儿差别。
这样的情形经常遇到。三国系列游戏是我最喜欢的游戏系列之一。你有没有注意到那里边上百位英雄的头像基本上很相似?你仔细区分就会发现,虽然每个人都不同,但基本上只具有几种脸型:长方的、圆形的、细长的,然后配上不同的胡子、眉毛、眼睛、嘴,有的再加点儿伤疤或装饰物(比如给独眼龙夏侯敦加个单眼罩),就成了不同的人物头像!那么,为什么会这样的?因为根据研究表明,人类的脸谱基本上只有有限的几个类型,只不过在细节和组合方面存在些许差异。游戏制作者具有依据这个理论,只对人脸进行有限的几种建模,然后再通过组合、修饰,就可以产生无数的头像了。
用面向对象的方法来说就是,我们先建立一个原型,然后通过对原型进行复制和修饰的方法,就可以产生一个和原型相似的新对象。用GoF的话来说就是:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
二. 原型模式实例
前几天,我很
不幸把屋门的钥匙给弄丢了,结果进不了家门。万幸的是,GF那儿还有一把,于是第二天我拿了她的那把去配钥匙。另外,她还让我顺便给她配一把橱柜的钥匙。
现在配个钥匙真是简单,把钥匙给他,他直接找一个合适的钥匙胚子,把我的钥匙夹在配钥匙机的一端,胚子夹在另一端,一开电源,一把标尺比着我的钥匙齿型走
一遍,砂轮就在胚子上复制出一把钥匙来!一分钟不到,两把新钥匙就搞定了!
用OO来描述,我的
旧钥匙是一个原型。配钥匙的过程就是根据我提供的原型,再复制一份出来,就有了一个新的钥匙。两个钥匙完全一样,我也可以给新配的钥匙贴个标签,以表明是“我的”。用这样的方法,我可以对各种钥匙进行复制,也可以复制无限多份。OO分析的类图如下:
程序代码如下:
namespace
Prototype
{
// 抽象钥匙原型
public abstract class Key
{
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
private string owner;
public string Owner
{
get { return owner; }
set { owner = value; }
}
public Key( string name, string owner)
{
this .name = name;
this .owner = owner;
}
// 钥匙复制自身的抽象定义
public abstract Key Clone();
public override String ToString()
{
return this .Name + " , belongs to " + this .Owner;
}
}
// 大门钥匙
public class GateKey : Key
{
public GateKey( string owner) : base ( " Gate Key " , owner) { }
public override Key Clone()
{
return new GateKey( this .Owner);
}
}
// 橱柜钥匙
public class CabinetKey : Key
{
public CabinetKey( string owner) : base ( " Cabinet Key " , owner) { }
public override Key Clone()
{
return new CabinetKey( this .Owner);
}
}
// 客户调用方法
public class Client
{
public static void Main( string [] args)
{
Key oldGateKey, newGateKey, oldCabinetKey, newCabinetKey;
oldGateKey = new GateKey( " GF " );
newGateKey = oldGateKey.Clone();
newGateKey.Owner = " Me " ;
oldCabinetKey = new CabinetKey( " Me " );
newCabinetKey = oldCabinetKey.Clone();
newCabinetKey.Owner = " GF " ;
Console.WriteLine(oldGateKey);
Console.WriteLine(newGateKey);
Console.WriteLine(oldCabinetKey);
Console.WriteLine(newCabinetKey);
}
}
}
{
// 抽象钥匙原型
public abstract class Key
{
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
private string owner;
public string Owner
{
get { return owner; }
set { owner = value; }
}
public Key( string name, string owner)
{
this .name = name;
this .owner = owner;
}
// 钥匙复制自身的抽象定义
public abstract Key Clone();
public override String ToString()
{
return this .Name + " , belongs to " + this .Owner;
}
}
// 大门钥匙
public class GateKey : Key
{
public GateKey( string owner) : base ( " Gate Key " , owner) { }
public override Key Clone()
{
return new GateKey( this .Owner);
}
}
// 橱柜钥匙
public class CabinetKey : Key
{
public CabinetKey( string owner) : base ( " Cabinet Key " , owner) { }
public override Key Clone()
{
return new CabinetKey( this .Owner);
}
}
// 客户调用方法
public class Client
{
public static void Main( string [] args)
{
Key oldGateKey, newGateKey, oldCabinetKey, newCabinetKey;
oldGateKey = new GateKey( " GF " );
newGateKey = oldGateKey.Clone();
newGateKey.Owner = " Me " ;
oldCabinetKey = new CabinetKey( " Me " );
newCabinetKey = oldCabinetKey.Clone();
newCabinetKey.Owner = " GF " ;
Console.WriteLine(oldGateKey);
Console.WriteLine(newGateKey);
Console.WriteLine(oldCabinetKey);
Console.WriteLine(newCabinetKey);
}
}
}
这就是原型模式的典型实现:把一个现有对象作为原型,通过对原型进行复制产生新的对象。这样做的好处是:可以通过对原型对象的多次复制,可以产生无限的新对象。
1. Clone()方法
原型模式中复制模型对象是通过Clone()方法实现的。其
实,这个方法可以是任意名字,比如CloneKey()、CloneMe()等等。不过,一般应该使用Clone()方法,这样做有两个原因:一是出于习
惯,复制对象当然应该是Clone();二是,在许多语言中的基础类中,比如作为所有类基础的Object,都定义了Clone()方法。因此,实现原型
模式的方法一般应该是:原型类继承了ICloneable接口,在具体原型类中需要时间Clone()方法,完成对象的自我复制。(代码参加下面原型管理
器部分)
2 . 深复制和浅复制
复制有两种:深复制和浅复制。浅复制时,复制对象和原型对象共享对象所有的内部变量,两个对象具有一样的内存空间和生命周期。对原型对象的修改同时也修改了它的复制品,反之亦然。
Object类提供了一个简单的MemberwiseClone()方法来实现浅复制。因为任何一个类的基类都是Object,所以在C#中,实现浅复制非常简单:
public
class
GateKey : Key
{
public GateKey( string owner) : base ( " Gate Key " , owner) { }
public override Key Clone()
{
return (Key) this .MemberwiseClone();
}
}
{
public GateKey( string owner) : base ( " Gate Key " , owner) { }
public override Key Clone()
{
return (Key) this .MemberwiseClone();
}
}
3. 原型管理器
原型对象在原型模式中居于核心的地位。一个系统能产生的对象
的种类多少,取决于系统中存在多少原型。当一个系统中原型对象较多或数量不固定,需要能动态的增加或删除的时候,我们就需要提供一个注册表机制,让客户能
存储、检索和管理可用原型池——这个注册表称为原型管理器。
原型管理器一般是一个关联型存储器,比如哈希表,它包含一些基本操作可以通过关键字来注册、检索、删除原型。具有原型管理器的原型模式如下图所示:
示例代码:
namespace
Prototype
{
// 抽象钥匙原型
[Serializable]
public abstract class Key : ICloneable
{
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
private string owner;
public string Owner
{
get { return owner; }
set { owner = value; }
}
public Key( string name, string owner)
{
this .name = name;
this .owner = owner;
}
public override String ToString()
{
return this .Name + " , belongs to " + this .Owner;
}
public virtual Object Clone()
{
MemoryStream memoryStream = new MemoryStream();
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(memoryStream, this );
memoryStream.Position = 0 ;
return formatter.Deserialize(memoryStream);
}
}
// 大门钥匙
[Serializable]
public class GateKey : Key
{
public GateKey( string owner) : base ( " Gate Key " , owner) { }
}
// 万能 钥匙 :-)
[Serializable]
public class GeneralKey : Key
{
public GeneralKey( string name, string owner) : base (name, owner) { }
}
public class KeyManager
{
private System.Collections.Hashtable keys = new System.Collections.Hashtable();
public Key this [ string name]
{
set { keys.Add(name, value); }
get { return (Key)keys[name]; }
}
}
// 客户调用方法
public class Client
{
public static void Main( string [] args)
{
KeyManager keyManager = new KeyManager();
keyManager[ " gate " ] = new GateKey( " GF " );
keyManager[ " key2 " ] = new GeneralKey( " key2 " , " GF " );
keyManager[ " key3 " ] = new GeneralKey( " key3 " , " GF " );
keyManager[ " key4 " ] = new GeneralKey( " key4 " , " GF " );
keyManager[ " key5 " ] = new GeneralKey( " key5 " , " GF " );
Key newKey = (Key)keyManager[ " key2 " ].Clone();
newKey.Name = " Office " ;
newKey.Owner = " Me " ;
Console.WriteLine(newKey);
}
}
}
{
// 抽象钥匙原型
[Serializable]
public abstract class Key : ICloneable
{
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
private string owner;
public string Owner
{
get { return owner; }
set { owner = value; }
}
public Key( string name, string owner)
{
this .name = name;
this .owner = owner;
}
public override String ToString()
{
return this .Name + " , belongs to " + this .Owner;
}
public virtual Object Clone()
{
MemoryStream memoryStream = new MemoryStream();
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(memoryStream, this );
memoryStream.Position = 0 ;
return formatter.Deserialize(memoryStream);
}
}
// 大门钥匙
[Serializable]
public class GateKey : Key
{
public GateKey( string owner) : base ( " Gate Key " , owner) { }
}
// 万能 钥匙 :-)
[Serializable]
public class GeneralKey : Key
{
public GeneralKey( string name, string owner) : base (name, owner) { }
}
public class KeyManager
{
private System.Collections.Hashtable keys = new System.Collections.Hashtable();
public Key this [ string name]
{
set { keys.Add(name, value); }
get { return (Key)keys[name]; }
}
}
// 客户调用方法
public class Client
{
public static void Main( string [] args)
{
KeyManager keyManager = new KeyManager();
keyManager[ " gate " ] = new GateKey( " GF " );
keyManager[ " key2 " ] = new GeneralKey( " key2 " , " GF " );
keyManager[ " key3 " ] = new GeneralKey( " key3 " , " GF " );
keyManager[ " key4 " ] = new GeneralKey( " key4 " , " GF " );
keyManager[ " key5 " ] = new GeneralKey( " key5 " , " GF " );
Key newKey = (Key)keyManager[ " key2 " ].Clone();
newKey.Name = " Office " ;
newKey.Owner = " Me " ;
Console.WriteLine(newKey);
}
}
}
三. 原型模式的结构和角色
原型模式的一般结构如下:
-
Prototype:抽象原型角色,定义一个原型的抽象定义,其中包含一个复制自身的接口。
-
ConcretePrototypeA/B:具体原型角色,作为原型被复制的具体对象,需实现抽象原型所定义的接口。
-
Client:客户调用端,客户使用原型对象复制出需要的对象
包含原型管理器的原型模式的结构如下:
-
PrototypeManager:原型管理器角色,提供具体原型对象的增加、删除、浏览等管理功能。
四. 原型模式总结
原型模式应用于希望系统独立于产品的创建、表示和构成时,这
和工厂模式很类似。事实上,和工厂模式相同的是,原型模式同样对客户隐藏了对象的创建工作,但是,与工厂模式通过对一个类进行实例化来构造新对象不同的
是,原型模式是通过拷贝一个现有对象生成新对象的。工厂模式适用于产品种类有限的情况下,当产品数量巨大或需要提供动态产品增删等性能时,使用原型模式具
有更强的适应性。
原型模式适用于以下情况(GoF):
-
当要实例化的类是在运行时刻指定时,例如,通过动态装载;
-
为了避免创建一个与产品类层次平行的工厂类层次时;
-
当一个类的实例只能有几个不同状态组合中的一种时。建立相应数目的原型并克隆它们可能比每次用合适的状态手工实例化该类更方便一些。
发表评论
-
访问者模式 Visitor(转)
2012-06-25 14:49 1203一、引子 对于系统中一个已经完成的类层次结构,我们已 ... -
策略模式 Strategy
2012-06-21 10:30 1018策略模式(Strategy):它定义了一系列的算法,并将每一个 ... -
模板方法模式 Template Method
2012-06-21 10:21 927GOF给模板方法(Template Method)模式定义一个 ... -
状态模式 State
2012-06-19 15:37 1058State模式的定义: 不同的 ... -
备忘录模式 Memento(转)
2012-06-19 14:11 0备忘录模式(Memento) 属于对象的行为模式。 ... -
中介者模式 Mediator (转)
2012-06-19 11:11 0一、中介者模式简介 ... -
迭代器模式 iterator
2012-06-18 14:58 3303一、 引言 迭代这个名词对于熟悉Java的人来说绝对不陌 ... -
解释器模式 interpreter(转)
2012-06-18 13:48 0Interpreter模式也叫解释器模式,是由GoF提出的23 ... -
责任链模式 chain of responsibility(原)
2012-06-15 15:56 1064动机: 在开发过程中有一种情况:一个事件产生一个请求,这个请 ... -
享元模式 flyweight
2012-06-14 15:45 932个人理解:当系统内部需要使用大量的细粒度对象时,内存中每种类型 ... -
外观模式 Facade
2012-06-13 16:02 963先做个总结: 外观模式就是提供一个高层接口来集成、制定、调用 ... -
组合模式(Composite)
2012-06-13 15:33 2223The figure below shows a UML cl ... -
适配器模式(Adapter )
2012-06-13 14:46 981Adapter - Convert the interfac ... -
Bridge桥接模式
2012-06-08 15:24 800Bridge桥接模式是一种结构型模式,它主要应对的是:由于类 ... -
代理模式
2012-06-08 11:06 812代理模式:给某一对象提供代理对象,并由代理对象控制具体对象的引 ... -
设计模式(Design Pattern)的原则
2012-06-08 11:00 875设计模式(Design Pattern)的原则 1、&q ... -
设计模式之Decorator
2012-03-30 16:44 821设计模式之Decorator(油漆工) ... -
命令模式
2011-12-09 15:35 817优点: 解耦了发送者和接受者之间联系。 发送者调用一个 ... -
观察者模式
2011-12-09 10:50 972Define a one-to-many depend ... -
抽象工厂 理解
2011-10-14 18:22 1020抽象工厂模式 抽象工厂模式(英语:Abstra ...
相关推荐
**原型模式(Prototype Pattern)**是一种基于克隆的创建型设计模式,它的主要目的是为了提高创建新对象的效率,特别是当创建新对象的过程复杂或者资源消耗较大时。在原型模式中,一个已经创建的对象(称为原型)被...
原型模式(Prototype Pattern)是一种创建型设计模式,允许通过复制现有对象来创建新对象,而不是通过类构造器。这种模式常用于需要频繁创建相似对象的场景,能够提高性能并减少内存使用。 原型模式的组成 原型接口...
**原型模式(Prototype Pattern)详解** 在软件设计中,原型模式是一种创建型设计模式,它提供了一种通过复制已有对象来创建新对象的方式,避免了重复的构造过程,提高了代码的效率和可维护性。原型模式的核心思想...
原型模式(Prototype Pattern)是一种创建型设计模式,它通过复制现有对象来创建新的对象,而不是通过传统的构造函数或类来实例化对象。原型模式在需要创建大量相似对象且创建过程较为耗时或复杂时非常有用。 在...
**原型模式(Prototype Pattern)**是一种创建型设计模式,它允许我们通过复制现有的对象来创建新对象,而不是通过构造函数或工厂方法。这种模式的核心在于,它提供了一种更高效、更灵活的方式来创建新实例,特别是在...
**原型设计模式(Prototype Pattern)**是一种创建型设计模式,它允许我们通过复制现有的对象来创建新对象,而不是通过构造函数来实例化新对象。在面向对象编程中,当我们需要频繁地创建具有相同或相似属性的对象时,...
原型模式是一种创建型设计模式,它通过复制一个现有的对象来创建新的对象,而不是通过调用构造函数的方式。这种方式可以在运行时动态地创建和修改对象,而不需要知道具体的创建细节 。 原型模式的基本概念包括以下...
在Java中,原型模式通常通过实现一个原型接口或抽象类,并在具体类中提供克隆方法来实现。Java中有一个内置的Cloneable接口和Object类的clone()方法,它们可以被用来实现对象的克隆。但是,直接使用clone()方法需要...
在C++中,原型模式可以通过定义一个抽象基类(或接口),并在其中声明一个纯虚克隆方法来实现。然后,具体类将继承这个基类并实现克隆方法。由于C++没有内置的克隆机制像Java的Cloneable接口那样,因此我们需要手动...
**原型模式(Prototype Pattern)**是一种创建型设计模式,它提供了一种通过复制已有对象来创建新对象的方式,而不是通过构造函数。在某些情况下,当创建新对象的成本非常高时(例如,对象需要大量的初始化操作或者从...
### .NET设计模式(6):原型模式(Prototype Pattern) #### 概述 在软件工程领域,设计模式提供了一系列经过验证的解决方案,帮助开发者解决常见的软件设计问题。本篇文章聚焦于.NET框架下的“原型模式”...
适配器模式(Adapter Pattern) 提供者模式(Provider Pattern) 外观模式(Facade Pattern) 享元模式(Flyweight Pattern) 原型模式(Prototype Pattern) 责任链模式(Chain of Responsibility Pattern) 中介者模式...
原型模式(Prototype Pattern) 2. 结构型模式 适配器模式(Adapter Pattern) 桥接模式(Bridge Pattern) 过滤器模式(Filter、Criteria Pattern) 组合模式(Composite Pattern) 装饰器模式(Decorator ...
原型模式(Prototype Pattern)是其中一种行为设计模式,主要用于对象创建。它通过复制已有对象来创建新对象,而不是通过传统的构造函数来创建。在Java中,原型模式可以有效地提高性能,特别是在创建复杂对象时。 #...
**原型模式(Prototype Pattern)**是软件设计模式中的结构型模式之一,主要用来简化实例化过程,减少类的创建。在原型模式中,一个对象可以被用作创建其他新对象的模板,通过复制已有对象来创建新对象,而不是通过new...
原型模式(Prototype) 单件模式(Singleton) 结构型: 适配器模式(Adapter) 桥接模式(Bridge) 组合模式(Composite) 装饰者模式(Decorator) 外观模式(Facade) 蝇量模式(Flyweight) 代理模式(Proxy) 行为型: 责任链...
原型模式(Prototype Pattern) 结构型模式(Structural Pattern) 适配器模式(Adapter/Wrapper Pattern) 桥接模式(Bridge Pattern) 装饰模式(Decorator Pattern) 外观模式(Facade Pattern) 享元模式(Flyweight Pattern)
原型模式(Prototype Pattern)是软件设计模式中的一种结构型模式,它的主要目的是通过复制已有对象来创建新对象,从而减少创建新对象的成本。在原型模式中,类的实例化过程被替换为对已有实例的克隆操作,尤其适用...
本文将深入探讨一种常见的设计模式——原型模式(Prototype Pattern),并结合具体的iOS应用场景进行解析。 原型模式是一种创建型设计模式,它的主要思想是通过复制已有对象来创建新对象,而不是通过构造函数来创建...