原型模式 - 创建者模式
来源:互联网 发布:java script 编辑:程序博客网 时间:2024/05/29 03:15
个人理解:
模式类型:
Prototype 原型模式 - 创建者模式
意图:
specifying the kind of objects to create using a prototypical instance
creating new objects by copying this prototype
概述:
原型模式是一种创建型设计模式,它通过复制一个已经存在的实例来返回新的实例,而不是新建实例.被复制的实例就是我们所称的原型,这个原型是可定制的.
原型模式多用于创建复杂的或者耗时的实例, 因为这种情况下,复制一个已经存在的实例可以使程序运行更高效,或者创建值相等,只是命名不一样的同类数据.
原型模式中的拷贝分为"浅拷贝"和"深拷贝":
浅拷贝: 对值类型的成员变量进行值的复制,对引用类型的成员变量只复制引用,不复制引用的对象.
深拷贝: 对值类型的成员变量进行值的复制,对引用类型的成员变量也进行引用对象的复制.
注:使用原型模式复制对象不会调用类的构造方法。因为对象的复制是通过调用Object类的clone方法来完成的,它直接在内存中复制数据,因此不会调用到类的构造方法。不但构造方法中的代码不会执行,甚至连访问权限都对原型模式无效。还记得单例模式吗?单例模式中,只要将构造方法的访问权限设置为private型,就可以实现单例。但是clone方法直接无视构造方法的权限,所以,单例模式与原型模式是冲突的,在使用时要特别注意。
不是基本类型,所以成员变量不会被拷贝,需要我们自己实现深拷贝。
深拷贝与浅拷贝问题中,会发生深拷贝的有java中的8中基本类型以及他们的封装类型,另外还有String类型。其余的都是浅拷贝。
Prototype - declares an interface for cloning itself.
ConcretePrototype - implements the operation for cloning itself.
模式的应用场景:
使用原型模式创建对象比直接new一个对象在性能上要好的多,因为Object类的clone方法是一个本地方法,它直接操作内存中的二进制流,特别是复制大对象时,性能的差别非常明显。
使用原型模式的另一个好处是简化对象的创建,使得创建对象就像我们在编辑文档时的复制粘贴一样简单。
因为以上优点,所以在需要重复地创建相似对象时可以考虑使用原型模式。比如需要在一个循环体内创建对象,假如对象创建过程比较复杂或者循环次数很多的话,使用原型模式不但可以简化创建过程,而且可以使系统的整体性能提高很多。
结构图:
模式的优缺点:
使用原型模式复制对象不会调用类的构造方法。因为对象的复制是通过调用Object类的clone方法来完成的,它直接在内存中复制数据,因此不会调用到类的构造方法。不但构造方法中的代码不会执行,甚至连访问权限都对原型模式无效。还记得单例模式吗?单例模式中,只要将构造方法的访问权限设置为private型,就可以实现单例。但是clone方法直接无视构造方法的权限,所以,单例模式与原型模式是冲突的,在使用时要特别注意。
深拷贝与浅拷贝。Object类的clone方法只会拷贝对象中的基本的数据类型,对于数组、容器对象、引用对象等都不会拷贝,这就是浅拷贝。如果要实现深拷贝,必须将原型模式中的数组、容器对象、引用对象等另行拷贝。
代码(其实读UML图要比代码还要一目了然):
2、Rectangle.java
Square.java
3、ShapeCache.java 【Create a class to get concrete classes from database and store them in a Hashtable.】
4、PrototypePatternDemo.java 【PrototypePatternDemo uses ShapeCache class to get clones of shapes stored in aHashtable.】
5、输出:
所有模式:
创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
补充模式:空对象模式
参考/转自:
http://blog.csdn.net/zhengzhb/article/details/7393528
http://www.tutorialspoint.com/design_pattern/prototype_pattern.htm
http://www.oodesign.com/prototype-pattern.html
http://blog.csdn.net/chjttony/article/details/7477346
模式类型:
Prototype 原型模式 - 创建者模式
意图:
specifying the kind of objects to create using a prototypical instance
creating new objects by copying this prototype
概述:
原型模式是一种创建型设计模式,它通过复制一个已经存在的实例来返回新的实例,而不是新建实例.被复制的实例就是我们所称的原型,这个原型是可定制的.
原型模式多用于创建复杂的或者耗时的实例, 因为这种情况下,复制一个已经存在的实例可以使程序运行更高效,或者创建值相等,只是命名不一样的同类数据.
原型模式中的拷贝分为"浅拷贝"和"深拷贝":
浅拷贝: 对值类型的成员变量进行值的复制,对引用类型的成员变量只复制引用,不复制引用的对象.
深拷贝: 对值类型的成员变量进行值的复制,对引用类型的成员变量也进行引用对象的复制.
注:使用原型模式复制对象不会调用类的构造方法。因为对象的复制是通过调用Object类的clone方法来完成的,它直接在内存中复制数据,因此不会调用到类的构造方法。不但构造方法中的代码不会执行,甚至连访问权限都对原型模式无效。还记得单例模式吗?单例模式中,只要将构造方法的访问权限设置为private型,就可以实现单例。但是clone方法直接无视构造方法的权限,所以,单例模式与原型模式是冲突的,在使用时要特别注意。
不是基本类型,所以成员变量不会被拷贝,需要我们自己实现深拷贝。
深拷贝与浅拷贝问题中,会发生深拷贝的有java中的8中基本类型以及他们的封装类型,另外还有String类型。其余的都是浅拷贝。
角色:
Client - creates a new object by asking a prototype to clone itself.Prototype - declares an interface for cloning itself.
ConcretePrototype - implements the operation for cloning itself.
模式的应用场景:
使用原型模式创建对象比直接new一个对象在性能上要好的多,因为Object类的clone方法是一个本地方法,它直接操作内存中的二进制流,特别是复制大对象时,性能的差别非常明显。
使用原型模式的另一个好处是简化对象的创建,使得创建对象就像我们在编辑文档时的复制粘贴一样简单。
因为以上优点,所以在需要重复地创建相似对象时可以考虑使用原型模式。比如需要在一个循环体内创建对象,假如对象创建过程比较复杂或者循环次数很多的话,使用原型模式不但可以简化创建过程,而且可以使系统的整体性能提高很多。
结构图:
模式的优缺点:
使用原型模式复制对象不会调用类的构造方法。因为对象的复制是通过调用Object类的clone方法来完成的,它直接在内存中复制数据,因此不会调用到类的构造方法。不但构造方法中的代码不会执行,甚至连访问权限都对原型模式无效。还记得单例模式吗?单例模式中,只要将构造方法的访问权限设置为private型,就可以实现单例。但是clone方法直接无视构造方法的权限,所以,单例模式与原型模式是冲突的,在使用时要特别注意。
深拷贝与浅拷贝。Object类的clone方法只会拷贝对象中的基本的数据类型,对于数组、容器对象、引用对象等都不会拷贝,这就是浅拷贝。如果要实现深拷贝,必须将原型模式中的数组、容器对象、引用对象等另行拷贝。
代码(其实读UML图要比代码还要一目了然):
1、Shape.java
public abstract class Shape implements Cloneable { private String id; protected String type; abstract void draw(); public String getType(){ return type; } public String getId() { return id; } public void setId(String id) { this.id = id; } public Object clone() { Object clone = null; try { clone = super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return clone; }}
2、Rectangle.java
public class Rectangle extends Shape { public Rectangle(){ type = "Rectangle"; } @Override public void draw() { System.out.println("Inside Rectangle::draw() method."); }}
Square.java
public class Square extends Shape { public Square(){ type = "Square"; } @Override public void draw() { System.out.println("Inside Square::draw() method."); }}
Circle.java
public class Circle extends Shape { public Circle(){ type = "Circle"; } @Override public void draw() { System.out.println("Inside Circle::draw() method."); }}
3、ShapeCache.java 【Create a class to get concrete classes from database and store them in a Hashtable.】
import java.util.Hashtable;public class ShapeCache { private static Hashtable<String, Shape> shapeMap = new Hashtable<String, Shape>(); public static Shape getShape(String shapeId) { Shape cachedShape = shapeMap.get(shapeId); //---这句是重点!!,返回的是对象的克隆!---- return (Shape) cachedShape.clone(); } // for each shape run database query and create shape // shapeMap.put(shapeKey, shape); // for example, we are adding three shapes public static void loadCache() { Circle circle = new Circle(); circle.setId("1"); shapeMap.put(circle.getId(),circle); Square square = new Square(); square.setId("2"); shapeMap.put(square.getId(),square); Rectangle rectangle = new Rectangle(); rectangle.setId("3"); shapeMap.put(rectangle.getId(), rectangle); }}
4、PrototypePatternDemo.java 【PrototypePatternDemo uses ShapeCache class to get clones of shapes stored in aHashtable.】
public class PrototypePatternDemo { public static void main(String[] args) { ShapeCache.loadCache(); Shape clonedShape = (Shape) ShapeCache.getShape("1"); System.out.println("Shape : " + clonedShape.getType()); Shape clonedShape2 = (Shape) ShapeCache.getShape("2"); System.out.println("Shape : " + clonedShape2.getType()); Shape clonedShape3 = (Shape) ShapeCache.getShape("3"); System.out.println("Shape : " + clonedShape3.getType()); }}
5、输出:
Shape : CircleShape : SquareShape : Rectangle
--===========================深拷备的分割线===============================--
深拷备是2种方法:
1、利用super.clone(); 后,再给不属于基本变量的类型属性赋值
package com.lee.desingerPattener23.prototype.example3;class Professor implements Cloneable{ String name; int age; Professor(String name,int age){ this.name=name; this.age=age; } public Object clone(){ Object o=null; try{ o=super.clone(); }catch(CloneNotSupportedException e){ System.out.println(e.toString()); } return o; } } public class Student implements Cloneable{ String name; int age; Professor p; Student(String name,int age,Professor p){ this.name=name; this.age=age; this.p=p; } public Object clone(){ Student o=null; try{ o=(Student)super.clone(); }catch(CloneNotSupportedException e){ System.out.println(e.toString()); } // --- 重点!:调用Professor类的clone()方法实现深拷贝 --- o.p=(Professor)this.p.clone(); return o; } public static void main(String[] args){ Professor p=new Professor("wangwu",50); Student s1=new Student("zhangsan",18,p); Student s2=(Student)s1.clone(); s2.p.name="lisi"; s2.p.age=30; //学生1的教授不改变 System.out.println("name="+s1.p.name+","+"age="+s1.p.age); System.out.println("name="+s2.p.name+","+"age="+s2.p.age); } }
2、利用序列化实现深度拷贝
把对象写到流里的过程是串行化(Serilization)过程,又叫对象序列化,而把对象从流中读出来的(Deserialization)过程叫反序列化。应当指出的是,写在流里的是对象的一个拷贝,而原对象仍然存在于JVM里面,因此在Java语言里深复制一个对象,常常可以先使对象实现Serializable接口,然后把对象(实际上只是对象的一个拷贝)写到一个流里,再从流里读出来便可以重建对象。
package com.lee.desingerPattener23.prototype.example3;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.io.OptionalDataException;import java.io.Serializable;class Profess implements Serializable{ String name; int age; Profess(String name,int age){ this.name=name; this.age=age; } } public class StudentDeep implements Serializable{ String name; int age; Profess p; StudentDeep(String name,int age,Profess p){ this.name=name; this.age=age; this.p=p; } public Object deepClone() throws IOException,OptionalDataException,ClassNotFoundException{ Object o = null; try{ //将对象写到流里 ByteArrayOutputStream bo=new ByteArrayOutputStream(); ObjectOutputStream oo=new ObjectOutputStream(bo); oo.writeObject(this);// object of studnet oo.close(); //从流里读出来 ByteArrayInputStream bi=new ByteArrayInputStream(bo.toByteArray()); ObjectInputStream oi=new ObjectInputStream(bi); o = oi.readObject(); oi.close(); }catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e){ e.printStackTrace(); } return o; } public static void main(String[] args) throws OptionalDataException, ClassNotFoundException, IOException{ Profess p=new Profess("wangwu",50); StudentDeep s1=new StudentDeep("zhangsan",18,p); StudentDeep s2=(StudentDeep)s1.deepClone(); s2.p.name="lisi"; s2.p.age=30; //学生1的教授不改变 System.out.println("name="+s1.p.name+","+"age="+s1.p.age); System.out.println("name="+s2.p.name+","+"age="+s2.p.age); } }
输出结果:
name=wangwu,age=50name=lisi,age=30
所有模式:
创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
补充模式:空对象模式
参考/转自:
http://blog.csdn.net/zhengzhb/article/details/7393528
http://www.tutorialspoint.com/design_pattern/prototype_pattern.htm
http://www.oodesign.com/prototype-pattern.html
http://blog.csdn.net/chjttony/article/details/7477346
转载请注明:http://blog.csdn.net/paincupid/article/details/46860283
0 0
- 原型模式 - 创建者模式
- 原型模式与创建者模型
- 原型模式(Prototype Pattern)-创建者模式
- java设计模式(五)创建者模式和原型模式
- 设计模式(五)创建者模式和原型模式
- 创建者模式
- 创建者模式
- 创建者模式
- 创建者模式
- 创建者模式
- 创建者模式
- 创建者模式
- 创建者模式
- 创建者模式
- 创建者模式
- 创建者模式
- 创建者模式
- 创建者模式——原型模式(Prototype)(5)
- system()函数
- Http之Get/Post请求区别
- 关于__block和__weak的详解
- #笔记#圣思园 JavaWeb 第32讲——Servlet多线程同步问题,Cookie
- iOS设计模式-抽象工厂
- 原型模式 - 创建者模式
- 数据结构:树结构笔试题目
- hdu 1548
- Core Data 的使用
- storyboard 和xib的本地化的应用
- svn 和 git的简单使用
- js ==与===区别
- 工作日志2
- 隐马尔科夫学习资料