原型模式

合集下载

13、原型模式(原型设计模式)详解

13、原型模式(原型设计模式)详解

13、原型模式(原型设计模式)详解原型模式的定义与特点原型(Prototype)模式的定义如下:⽤⼀个已经创建的实例作为原型,通过复制该原型对象来创建⼀个和原型相同或相似的新对象。

在这⾥,原型实例指定了要创建的对象的种类。

⽤这种⽅式创建对象⾮常⾼效,根本⽆须知道对象创建的细节。

例如,Windows 操作系统的安装通常较耗时,如果复制就快了很多。

在⽣活中复制的例⼦⾮常多,这⾥不⼀⼀列举了。

原型模式的优点:⾃带的原型模式基于内存⼆进制流的复制,在性能上⽐直接 new ⼀个对象更加优良。

可以使⽤深克隆⽅式保存对象的状态,使⽤原型模式将对象复制⼀份,并将其状态保存起来,简化了创建对象的过程,以便在需要的时候使⽤(例如恢复到历史某⼀状态),可辅助实现撤销操作。

原型模式的缺点:需要为每⼀个类都配置⼀个 clone ⽅法clone ⽅法位于类的内部,当对已有类进⾏改造的时候,需要修改代码,违背了开闭原则。

当实现深克隆时,需要编写较为复杂的代码,⽽且当对象之间存在多重嵌套引⽤时,为了实现深克隆,每⼀层对象对应的类都必须⽀持深克隆,实现起来会⽐较⿇烦。

因此,深克隆、浅克隆需要运⽤得当。

原型模式的结构与实现由于 Java 提供了对象的 clone() ⽅法,所以⽤ Java 实现原型模式很简单。

1. 模式的结构原型模式包含以下主要⾓⾊。

1. 抽象原型类:规定了具体原型对象必须实现的接⼝。

2. 具体原型类:实现抽象原型类的 clone() ⽅法,它是可被复制的对象。

3. 访问类:使⽤具体原型类中的 clone() ⽅法来复制新的对象。

其结构图如图 1 所⽰。

图1 原型模式的结构图2. 模式的实现原型模式的克隆分为浅克隆和深克隆。

浅克隆:创建⼀个新对象,新对象的属性和原来对象完全相同,对于⾮基本类型属性,仍指向原有属性所指向的对象的内存地址。

深克隆:创建⼀个新对象,属性中引⽤的其他对象也会被克隆,不再指向原有对象地址。

原型模式原理

原型模式原理

原型模式原理
原型模式是一种创建对象的设计模式,它通过复制现有的对象来创建新的对象,而不是通过传统的构造函数来创建对象。

这种模式的核心思想是利用一个原型对象来实现对象的复制,从而避免了重复创建对象的过程。

在原型模式中,有一个原型对象和一个具体的子类。

子类通过实现原型对象的接口来继承原型对象的行为。

当需要创建一个新的对象时,可以通过复制原型对象来创建一个新的对象。

这个新的对象具有与原型对象相同的属性和行为,但它是一个独立的对象,不是原型对象的副本。

原型模式的优点是可以提高系统的性能和效率,减少对象的创建和销毁。

因为新对象是通过复制现有的对象来创建的,所以不需要执行复杂的构造函数和初始化过程。

此外,原型模式还可以实现对象的动态扩展和修改,因为新对象可以在运行时通过复制原型对象来创建。

原型模式的缺点是需要额外的内存来存储原型对象,并且在复制对象时可能会导致性能损失。

此外,如果对象的状态比较复杂,复制对象可能会比较耗时。

在实际应用中,原型模式通常用于创建大量相似的对象,例如在游戏开发中创建大量的游戏角色。

它也可以用于实现一些复杂的对象创建过程,例如在图像处理中创建图像的副本。

总之,原型模式是一种简单而有效的对象创建模式,它可以提高系统的性能和效率,并且可以实现对象的动态扩展和修改。

但是,在使用原型模式时需要注意对象的复制过程和内存消耗。

面向对象设计的基本原则和模式

面向对象设计的基本原则和模式

面向对象设计的基本原则和模式面向对象设计是一种软件开发的方法论,它将现实世界中的事物抽象成对象,然后通过对象之间的交互来完成软件系统的设计和开发。

面向对象设计的基本原则和模式是其核心,它们是设计和开发高质量、可维护、可扩展软件系统的基石。

本文将会首先介绍面向对象设计的基本原则,然后再介绍面向对象设计的基本模式。

一、面向对象设计的基本原则面向对象设计的基本原则是一些通用的、普遍适用的软件设计规则,它们有助于设计出高质量、可维护、可扩展的软件系统。

下面是面向对象设计的基本原则:1.单一责任原则(SRP)单一责任原则是面向对象设计的一个基本原则,它规定一个类应该只有一个引起它变化的原因。

换句话说,一个类应该只有一个职责。

这样可以降低类的复杂度,使得类更容易理解、维护和重用。

2.开放-封闭原则(OCP)开放-封闭原则是指一个软件实体(类、模块、函数等)应该对扩展开放,对修改封闭。

这意味着当需要改变一个软件实体的行为时,不应该修改它的源代码,而是应该通过扩展它来实现。

3.里氏替换原则(LSP)里氏替换原则是指一个子类型(派生类)必须能够替换掉它的父类型(基类)而不影响系统的功能性和可靠性。

这意味着一个接口实现的任何地方都可以被子类型替换。

4.依赖倒置原则(DIP)依赖倒置原则是指高层模块不应该依赖于低层模块,二者都应该依赖于抽象。

具体来说就是,抽象不应该依赖于细节,而细节应该依赖于抽象。

5.接口隔离原则(ISP)接口隔离原则是指一个类不应该依赖它不需要的接口,换句话说,一个类应该尽可能多地使用它所需要的接口,而不是多余的接口。

6.迪米特原则(LoD)迪米特原则是指一个对象应该尽可能少地了解其他对象,它应该只与其直接的朋友通信。

这可以降低对象之间的耦合度,使得系统更易于维护和扩展。

以上就是面向对象设计的基本原则,它们是设计和开发高质量、可维护、可扩展软件系统的重要指导。

下面我们将介绍面向对象设计的基本模式。

软件开发技术-原型模式

软件开发技术-原型模式

2.原型模式结构及功能
• 原型管理器角色:该角色用于创建具体的 原型类对象,并且记录每一个被创建的对 象并且把已经创建过的对象保存下来。换 句话说就是先创建对象并将其保存下来 (由管理器完成)然后利用Clone()方法来 创建新对象
3.原型模式示例
原型模式示例
• 背景:
前几天,我很不幸把屋门的钥匙给弄 丢了,结果进不了家门。万幸的是,舍友那儿 还有一把,于是第二天我拿了她的那把去配钥 匙。另外,她还让我顺便给她配一把橱柜的钥 匙。现在配个钥匙真是简单,把钥匙给他,他 直接找一个合适的钥匙胚子,把我的钥匙夹在 配钥匙机的一端,胚子夹在另一端,一开电源, 一把标尺比着我的钥匙齿型走一遍,砂轮就在 胚子上复制出一把钥匙来!一分钟不到,两把 新钥匙就搞定了!
软件开发技术
原型模式
目录Content
1.原型模式的概念及特点 2.原型模式结构及功能
3.原型模式示例
4.原型模式总结
1.原型模式的概念及特点
原型模式定义
• 原型模式就是通过一个原型对象来表明要 创建的对象类型,然后用复制这个原型对 象的方法来创建更多同类型的对象。
• 原型模式允许一个对象再创建另外一个可 定制的对象,根本无需知道任何如何创建 的细节。
1.原型模式的概念及特点
原型模式与工厂模式的异同
• 原型模式应用于希望系统独立于产品的创 建、表示和构成时,这和工厂模式很类似。 事实上,和工厂模式相同的是,原型模式 同样对客户隐藏了对象的创建工作,但是, 与工厂模式通过对一个类进行实例化来构 造新对象不同的是,原型模式是通过拷贝 一个现有对象生成新对象的。工厂模式适 用于产品种类有限的情况下,当产品数量 巨大或需要提供动态产品增删等性能时, 使用原型模式具有更强的适应性。

原型模式(PrototypePattern)

原型模式(PrototypePattern)

原型模式(PrototypePattern)⼀、什么是原型模式原型模式(Prototype Pattern)也是⼀种创建型模式,它关注的是⼤量相似对象的创建问题。

我们经常会遇到这样的情况:在系统中要创建⼤量的对象,这些对象之间具有⼏乎完全相同的功能,只是在细节上有⼀点⼉差别。

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

结构图原型模式的基本实现原型类:1public abstract class Prototype2 {3private int id;45public Prototype(int id)6 {7this.id = id;8 }910public int Id11 {12get { return id; }13 }1415public abstract Prototype Clone();16 }具体的原型类:1public class ConcretePrototype : Prototype2 {3public ConcretePrototype(int id) : base(id) { }45public override Prototype Clone()6 {7return (Prototype)this.MemberwiseClone();8 }9 }客户端代码:1public class Client2 {3public static void Main(string[] args)4 {5 ConcretePrototype cp1 = new ConcretePrototype(1);6 ConcretePrototype cp2 = cp1.Clone() as ConcretePrototype;78 Console.WriteLine(cp1.Id);9 Console.WriteLine(cp2.Id);1011 Console.Read();12 }13 }对于.NET⽽⾔,那个原型抽象类Prototype是⽤不着的,因为克隆实在是太常⽤了,所以.NET在System命名空间中提供了ICloneable接⼝,其中就是唯⼀的⼀个⽅法Clone(),这样你就只需要实现这个接⼝就可以完成原型模式了。

MOOC课程之原型模式

MOOC课程之原型模式

创建型模式: 原型模式原型模式当创建一个类的实例非常耗时或者非常复杂时,可使用原型模式:创建原型实例的副本并适当对其修改。

定义/意图:•定义可通过原型实例创建的对象类型•通过复制原型创建新的对象原型模式原型模式参与者•Prototype声明用于克隆自身的接口•ConcretePrototype实现克隆自身的操作原型模式•Client通过让原型克隆自身创建新对象克隆方法利用clone方法创建任意java对象的副本。

Jobj j1 = (Jobj)j0.clone();克隆方法的四个限制1、克隆方法总是返回一个Object类型的对象,因此必须将其强制类型转换为正在克隆对象的实际类型。

克隆方法• 2. 该方法为protect类型方法,只能在类内部或在包含该类的包内调用。

• 3. 只能克隆实现了Cloneable接口的对象。

• 4. 不能被克隆的对象会抛出CloneNotSupported异常。

例子例子左边的列表框•程序启动时被加载•显示最初数据•名字按性别排序,性别一致按时间排序右边的列表框•点击Clone按钮时被加载•显示排序后数据•名字仅按时间排序例子:原型模式public class SwimData implements Cloneable { public Object clone() {try{return super.clone();} catch(Exception e) {System.out.println(e.getMessage());return null;}}}例子:原型模式在方法内进行类型转换public SwimData cloneMe() {try{return (SwimData)super.clone();} catch(Exception e) {System.out.println(e.getMessage());return null;}}例子:class Swimmer { String name; int age;String club; float time; boolean female;例子:原型模式public class SwimData implements Cloneable {Vector swimmers;public SwimData(String filename) { String s = "";swimmers = new Vector();//open data file例子:原型模式InputFile f = new InputFile(filename)s= f.readLine();//read in and parse each linewhile(s != null) {swimmers.addElement(new Swimmer(s));s= f.readLine();}f.close(); }例子swList.removeAll(); //clear listfor (int i= 0; i< sdata.size(); i++) { sw= sdata.getSwimmer(i); swList.addItem(sw.getName()+""+sw.getTime());}例子sxdata= (SwimData)sdata.clone(); sxdata.sortByTime(); //re-sort cloneList.removeAll(); //clear list//now display sorted values from clone for(int i=0; i< sxdata.size(); i++) {sw= sxdata.getSwimmer(i); cloneList.addItem(sw.getName()+""+sw.getTime());}浅克隆Java中的克隆是原始类的浅克隆深克隆通过Serializable接口实现数据的深克隆深克隆允许拷贝具有任意复杂度的类的实例,并且两份拷贝实例间具有完全独立的数据。

23种设计模式的经典运用

23种设计模式的经典运用

23种设计模式的经典运用介绍设计模式是解决软件设计中常见问题的可重复使用的解决方案。

本文将介绍23种经典的设计模式,并给出它们在实际开发中的应用示例。

通过学习这些设计模式,您将增加对软件设计的理解,并能够更好地解决问题。

创建型设计模式1.工厂方法模式(F a c t o r y M e t h o d)工厂方法模式通过定义一个创建对象的接口,但由子类决定实例化具体类。

这种方法可以延迟实例化过程,具有更高的灵活性和可扩展性。

应用场景:-在一个系统中,希望客户端与具体类的实例化解耦。

-希望通过增加具体类的扩展来增加系统的灵活性。

2.抽象工厂模式(A b s t r a c t F a c t o r y)抽象工厂模式提供一个接口,用于创建相关或依赖对象组。

这种模式将对象的实例化推迟到子类中,从而实现了解耦。

应用场景:-当一个系统独立于其产品的创建、组合和表示时。

-当需要一个系列的相互依赖的对象而无需指定其具体类时。

3.单例模式(S i n gl e t o n)单例模式确保一个类只有一个实例,并提供一个全局访问点。

这种模式常用于控制对资源的访问,例如数据库连接或日志文件。

应用场景:-当需要一个类的唯一实例,并且该实例需要被多个客户端共享时。

-当需要限制系统中特定类的实例数量时。

4.原型模式(P r o to t y p e)原型模式通过复制现有对象来创建新对象。

这种模式对于创建需要消耗大量资源的对象非常有用,可以通过克隆现有对象来提高性能。

应用场景:-当一个系统的某些对象的创建比较昂贵时。

-当需要避免构造函数调用,而直接通过复制现有对象来创建新对象时。

5.建造者模式(B ui l d e r)建造者模式将一个复杂对象的构建过程与其表现分离,使得相同的构建过程可以创建不同的表现。

应用场景:-当想要构建一些复杂对象时,如生成器。

-当需要创建对象的过程具有多个步骤,并且每个步骤都可以按需选择或省略时。

结构型设计模式6.适配器模式(A da p t e r)适配器模式将一个类的接口转换为客户端所期望的另一个接口。

第3章 Adobe XD的原型模式

第3章 Adobe XD的原型模式

第3章Adobe XD原型设计模式3.1 原型模式◼完成屏幕设计后,您可以将各屏幕互相连接,以便直观地了解用户如何体验您的应用程序或网站。

◼Adobe XD 允许您创建交互式原型,直观地展示如何在屏幕或线框之间导航。

您可以预览交互,验证用户体验并对设计进行迭代,从而节省开发时间。

您还可以录制交互过程并与利益相关者分享,以获取他们的反馈。

放大/缩小并查看原型特定部分的细节。

◼设置“主页”屏幕◼“主页”屏幕是您的应用程序或网站的第一个屏幕。

您的用户会通过“主页”屏幕开始在应用程序或网站中进行导航。

◼此外,如果您在预览原型时并没有选择任何内容,预览将从“主页”屏幕开始。

也就是说,默认情况下,您的“主页”屏幕会被设置为第一个添加连线的画板。

◼切换到“原型”模式。

◼单击要设置为“主页”屏幕的画板。

左上角会出现一个灰色的主页图标。

◼点击“主页”图标。

它会变成蓝色,提示该画板或屏幕现已成功设置为“主页”屏幕。

◼设置“主页”屏幕◼将交互式元素链接到目标屏幕◼在开始链接画板或屏幕之前,请适当地命名画板。

这样做有助于您确定要将指定屏幕链接到哪个屏幕。

◼切换到“原型”模式。

◼单击要链接的对象。

◼对象上出现带箭头的连接手柄。

将鼠标悬停在手柄上,光标会变为连接器。

◼设置“主页”屏幕◼单击并开始拖动鼠标,可以看到连接器。

在目标画板或屏幕上释放鼠标。

◼当您连接第一个元素时,该元素所在的画板将设为主画板。

◼在“属性检查器”中显示的“交互”面板中,可以指定以下内容:◼过渡和持续时间:如果您想要在过渡到另一个画板时让滚动位置保持不变,请选择“保留滚动位置”。

这个选项对于导航栏或固定页脚的原型设计非常有用。

如果用户在原始画板中滚动,下一个画板会识别原始画板中的滚动位置。

通过单击画板或画板中的任何元素,您可以控制滚动位置,从而在从一个屏幕切换到下一个屏幕时保留原始位置。

此控件可防止在项目文件中反复来回滚动。

例如,如果用户在画板A 上向下滚动到y=1,000,那么过渡到画板B 后,默认位置也会是y=1,000。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

<?php/*** 原型模式* 用原型实例指定创建对象的种类.并且通过拷贝这个原型来创建新的对象*/abstract class Prototype{private $_id = null;public function __construct($id){$this->_id = $id;}public function getID(){return $this->_id;}public function __clone() // magic function{$this->_id += 1;}public function getClone(){return clone $this;}}class ConcretePrototype extends Prototype{}$objPrototype = new ConcretePrototype(0);// $this->_id=0$objPrototype1 = clone$objPrototype;// $this->_id=1echo $objPrototype1->getID()."<br/>";//1$objPrototype2 = $objPrototype;echo $objPrototype2->getID()."<br/>";//0$objPrototype3 = $objPrototype->getClone();echo $objPrototype3->getID()."<br/>";//1原型模式通过复制已经存在的实例来返回新的实例,而不是新建实例,并且原型(被复制的实例)是可定制的;原型模式多用于创建复杂的或耗时的实例,这种情况下,复制一个已经存在的实例是程序运行更高效无疑是一种好办法;概念:用原型实例创建对象的种类,并通过拷贝这些原型创建的对象;结构图:主要角色:抽象原型角色(Prototype):声明一个克隆自身的接口具体原型角色(ConcretePrototype):实现一个克隆自身的操作Prototype模式优点:1、可以在运行时刻增加和删除产品2、可以改变值或结构以指定新对象3、减少子类的构造4、用类动态配置应用Prototype模式的缺点:Prototype是的最主要的缺点就是每一个类必须包含一个克隆方法;而且这个克隆方法需要对类的功能进行检测,这对于全新的类来说较容易,但对已有的类进行改造时将不是件容易的事情;代码实现:<?php/*** 原型模式* 用原型实例指定创建对象的种类.并且通过拷贝这个原型来创建新的对象* @author lzs*//*** 声明一个克隆自身的接口,即抽象原型角色* @author lzs**/interface Prototype{public function copy();}/*** 实现克隆自身的操作,具体原型角色* @author lzs*/class ConcretePrototype implements Prototype{private $name;function __construct($name){$this->name = $name;}function getName(){return $this->name;}function setName($name){$this->name = $name;}//克隆function copy(){// 浅拷贝//return clone $this;// 深拷贝$serialize_obj = serialize($this); //序列化$clone_obj = unserialize($serialize_obj); //反序列化return $clone_obj;}}/*** 测试深拷贝的类*/class Test{public $array;}/*** 客户端* @author lzs*/class Client{/*** 实现原型模式* @return string 取出数据*/public static function main(){/*** 浅拷贝*/// $pro = new ConcretePrototype('prototype');// $pro2 = $pro->copy();// echo '1:'.$pro->getName().'<br />2:'.$pro2->getName();/*** 深拷贝*/$test = new Test();$test->array = array('1','2','3');$pro1 = new ConcretePrototype($test);$pro2 = $pro1->copy();print_r($pro1->getName());echo '<br />';print_r($pro2->getName());}}Client::main();浅拷贝结果:1:prototype2:prototype深拷贝结果:Test Object ( [array] => Array ( [0] => 1 [1] => 2 [2] => 3 ) )Test Object ( [array] => Array ( [0] => 1 [1] => 2 [2] => 3 ) )浅拷贝:被拷贝对象的所有变量都含有与原对象相同的值,而且对其他对象的引用仍然是指向原来的对象。

即浅拷贝只负责当前对象实例,对引用的对象不做拷贝。

深拷贝:被拷贝对象的所有的变量都含有与原来对象相同的值,除了那些引用其他对象的变量。

那些引用其他对象的变量将指向一个被拷贝的新对象,而不再是原有那些被引用对象。

即深拷贝把要拷贝的对象所引用的对象也都拷贝了一次,而这种对被引用到的对象拷贝叫做间接拷贝。

深拷贝要深入到多少层,是一个不确定的问题。

在决定以深拷贝的方式拷贝一个对象的时候,必须决定对间接拷贝的对象是采取浅拷贝还是深拷贝还是继续采用深拷贝。

因此,在采取深拷贝时,需要决定多深才算深。

此外,在深拷贝的过程中,很可能会出现循环引用的问题。

利用序列化来做深拷贝:利用序列化来做深拷贝,把对象写到流里的过程是序列化(Serilization)过程,但在业界又将串行化这一过程形象的称为“冷冻”或“腌咸菜”过程;原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

它允许一个对象再创建另外一个可定制的对象,根本无需知道任何如何创建的细节,其工作原理是通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝它们自己来实施创建。

它主要面对的问题是:“某些结构复杂的对象”的创建工作;由于需求的变化,这些对象经常面临着剧烈的变化,但是他们却拥有比较稳定一致的接口(from百度百科)。

原型模式对编程带来的最大好处是减少代码量的编写,间接好处是精简代码,结构清晰。

浅复制:clone出的新对象和源对象具有相同的引用class Object{public $attribute = 0;}class Source{public $obj;public function __construct($obj){$this->obj = $obj;}}$innerObj = new Object();$source = new Source($innerObj);$new = clone $source;var_dump (spl_object_hash($new->obj) === spl_object_hash($source->obj)); //true深复制:clone出的新对象和源对象的引用是不同的//添加__clone魔术方法class Source{public $obj;public function __construct($obj){$this->obj = $obj;}public function __clone(){$this->obj = clone $this->obj;}}$innerObj = new Object();$source = new Source($innerObj);$new = clone $source;var_dump (spl_object_hash($new->obj) === spl_object_hash($source->obj));//false如果对象引用里面还有引用,引用嵌套多层,如果向上吗要达到深复制的话,是不是每个里面都要加__clone方法呢(实际应用中出现这种情况其实要考虑用原型模式是不是合适了),其实可以用序列化方法。

class Object{public $attribute = 0;}class Source{public $obj;public function __construct($obj){$this->obj = $obj;}}$innerObj = new Object();$source = new Source($innerObj);$new = unserialize(serialize($source));var_dump (spl_object_hash($new->obj) === spl_object_hash($source->obj));//falsephp的对象复制:php的对象间的复制是属于浅拷贝,两个对象都有相同的引用,相互影响。

如下代码:$obj = new class1;$obj1 = $obj; // 浅复制$obj->property = 'new';echo $obj>property ; // 输出new 连贯改变所以,如何做到深拷贝?就需要用到php里的clone语句了,或者使用冷冻技术(serialize)以下代码形式参照自网络:<?php// 定义原型的接口interface prototype {function copy();}// 具体需要被复制的类class creator implements prototype{private $info = '';function __construct($info) {$this->info = $info;}function getinfo() {return $this->info;}function setinfo($info) {$this->info = $info;}function copy() {/* 等价的方式$old_obj = serialize($this);return unserialize($old_obj);*/return clone $this;}}//复制前,设置下info属性$info = array('name'=>'jinde');$obj1 = new creator($info);$obj2 = $obj1->copy();// 复制后,再次设置$obj2->setinfo(array('name'=>'lili'));// 看值有没有发生变化,如果变化了,则没有进行深拷贝。

相关文档
最新文档