设计模式之原型设计模式

原创 2017年09月13日 17:29:37

1.定义
用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。
说白了就是创建一个结构复杂的对象的创建工作与之前创建的对象几乎相同,只是个别变量不同的对象。
2.适用的场景
它主要面对的问题是:“某些结构复杂的对象”的创建工作;由于需求的变化,这些对象经常面临着剧烈的变化,但是他们却拥有比较稳定一致的接口。
3.UML图
这里写图片描述
4.实例
- 4.1写法1

public class Person implements Cloneable{

    private String name;
    private String age;
    private String weight;
    private String height;
    private ArrayList<String> hobbies = new ArrayList<String>();

    public Person(){

    }
    //深复制  浅复制
    @SuppressWarnings("unchecked")
    @Override
    protected Object clone() throws CloneNotSupportedException {

//      Person person =(Person) super.clone();
//      return person;//浅复制 只能复制值 引用的地址未改变

        Person person = (Person) super.clone();
        person.hobbies = (ArrayList<String>) this.hobbies.clone();//深复制
        return person;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }

    public String getWeight() {
        return weight;
    }

    public void setWeight(String weight) {
        this.weight = weight;
    }

    public String getHeight() {
        return height;
    }

    public void setHeight(String height) {
        this.height = height;
    }

    public ArrayList<String> getHobbies() {
        return hobbies;
    }

    public void setHobbies(ArrayList<String> hobbies) {
        this.hobbies = hobbies;
    }
    @Override
    public String toString() {
        return "{\"name\":\"" + name + "\",\"age\":\"" + age
                + "\",\"weight\":\"" + weight + "\",\"height\":\"" + height
                + "\",\"hobbies\":\"" + hobbies + "\"}";
    }
}
  • 4.2写法2
public class Person2 implements Cloneable{

    private String name;
    private String age;
    private String weight;
    private String height;
    private ArrayList<String> hobbies = new ArrayList<String>();

    public Person2(){

    }

    public Person2(Person2 person){
        this.name = person.name;
        this.age = person.age;
        this.height = person.height;
        this.weight = person.weight;
        if (person.hobbies != null) {
            this.hobbies = new ArrayList<String>(person.hobbies);
        }
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return new Person2(this);
    }


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }

    public String getWeight() {
        return weight;
    }

    public void setWeight(String weight) {
        this.weight = weight;
    }

    public String getHeight() {
        return height;
    }

    public void setHeight(String height) {
        this.height = height;
    }

    public ArrayList<String> getHobbies() {
        return hobbies;
    }

    public void setHobbies(ArrayList<String> hobbies) {
        this.hobbies = hobbies;
    }

    @Override
    public String toString() {
        return "{\"name\":\"" + name + "\",\"age\":\"" + age
                + "\",\"weight\":\"" + weight + "\",\"height\":\"" + height
                + "\",\"hobbies\":\"" + hobbies + "\"}";
    }

}
  • 4.3调用
public class Test {

    public static void main(String[] args) throws CloneNotSupportedException {
        Person person = new Person();
        person.setAge("11");
        person.setHeight("172");
        person.setName("xiaoghong");
        ArrayList<String> hobbies = new ArrayList<String>();
        hobbies.add("游泳");
        person.setHobbies(hobbies);


        Person person2 = (Person) person.clone();
        person2.setAge("15");
        person2.getHobbies().add("篮球");
        System.out.println("person "+person.toString());
        System.out.println("person "+ person2.toString());

        Person2 person3 = new Person2();
        person3.setAge("11");
        person3.setHeight("172");
        person3.setName("xiaoghong");
        ArrayList<String> hobbies3 = new ArrayList<String>();
        hobbies3.add("游泳");
        person3.setHobbies(hobbies);

        Person2 person4 = new Person2(person3);
        person4.getHobbies().add("羽毛球");
        System.out.println("person "+person3.toString());
        System.out.println("person "+ person4.toString());
    }
}
  • 4.3运行结果
person {"name":"xiaoghong","age":"11","weight":"null","height":"172","hobbies":"[游泳]"}
person {"name":"xiaoghong","age":"15","weight":"null","height":"172","hobbies":"[游泳, 篮球]"}
person {"name":"xiaoghong","age":"11","weight":"null","height":"172","hobbies":"[游泳]"}
person {"name":"xiaoghong","age":"11","weight":"null","height":"172","hobbies":"[游泳, 羽毛球]"}

5.Android中应用场景
Bundle类实现了Cloneable接口

public Object clone() {
    return new Bundle(this);
} 
public Bundle(Bundle b) {
    super(b);

    mHasFds = b.mHasFds;
    mFdsKnown = b.mFdsKnown;
}

Intent也实现了Cloneable接口

@Override
public Object clone() {
    return new Intent(this);
}
public Intent(Intent o) {
    this.mAction = o.mAction;
    this.mData = o.mData;
    this.mType = o.mType;
    this.mPackage = o.mPackage;
    this.mComponent = o.mComponent;
    this.mFlags = o.mFlags;
    this.mContentUserHint = o.mContentUserHint;
    if (o.mCategories != null) {
        this.mCategories = new ArraySet<String>(o.mCategories);
    }
    if (o.mExtras != null) {
        this.mExtras = new Bundle(o.mExtras);
    }
    if (o.mSourceBounds != null) {
        this.mSourceBounds = new Rect(o.mSourceBounds);
    }
    if (o.mSelector != null) {
        this.mSelector = new Intent(o.mSelector);
    }
    if (o.mClipData != null) {
        this.mClipData = new ClipData(o.mClipData);
    }
}

6.总结
优点
(1)原型模式是在内存中二进制流的拷贝,要比直接new一个对象性能好很多,特别是要在一个循环体内产生大量对象时,原型模式可能更好的体现其优点。
(2)还有一个重要的用途就是保护性拷贝,也就是对某个对象对外可能是只读的,为了防止外部对这个只读对象的修改,通常可以通过返回一个对象拷贝的形式实现只读的限制。

缺点:
(1)这既是它的优点也是缺点,直接在内存中拷贝,构造函数是不会执行的,在实际开发中应该注意这个潜在问题。优点是减少了约束,缺点也是减少了约束,需要大家在实际应用时考虑。
(2)通过实现Cloneable接口的原型模式在调用clone函数构造实例时并不一定比通过new操作速度快,只有当通过new构造对象较为耗时或者说成本较高时,通过clone方法才能够获得效率上的提升。

把自己学习设计模式的过程记成笔记,方便自己随时查看,如有错误,欢迎指出,谢谢!

版权声明:本文为博主原创文章,未经博主允许不得转载。

JAVA设计模式之原型模式

定义:用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。 类型:创建类模式 类图: 原型模式主要用于对象的复制,它的核心是就是类图中的原型类Prototype。Prototype...
  • jason0539
  • jason0539
  • 2014年04月08日 08:22
  • 14725

iOS设计模式之原型模式

What is the 原型模式?原型设计模式是通过一个原型拷贝的方式快速创建一个新的对象。拷贝分为两种: 浅拷贝(同一个地址,不同的指针) 深拷贝(不同的地址,完全的独立) 二者区别在于是否生成新的...
  • IT_DS
  • IT_DS
  • 2016年04月24日 20:27
  • 2261

Java设计模式(五) 原型模式详解

在开发过程中,有时会遇到为一个类创建多个实例的情况,这些实例内部成员往往完全相同或有细微的差异,而且实例的创建开销比较大或者需要输入较多参数,如果能通过复制一个已创建的对象实例来重复创建多个相同的对象...
  • u013916933
  • u013916933
  • 2016年06月04日 16:22
  • 2452

iOS与java原型设计模式对比

iOS原型模式与Java原型模式 2014-10-17 牛其洪 iOS编程与大数据 什么是原型模式 什么时候用到原型模式 原型模式有那些优缺点 ...
  • baiyepdca
  • baiyepdca
  • 2014年10月17日 13:49
  • 300

三、原型设计模式

1. 原型设计模式介绍用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。原型设计模式多用于创建复杂的或者构造耗时的实例。因为这种情况下,复制一个已经存在的实例可使程序运行更高效。2. 原型...
  • u010649376
  • u010649376
  • 2016年04月25日 21:14
  • 389

原型设计模式

c#设计模式-原型模式 意图   用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。   场景   游戏场景中的有很多相似的敌人,它们的技能都一样,但是随着敌人出现的...
  • vs920079469vs
  • vs920079469vs
  • 2013年06月24日 16:06
  • 411

Java原型设计模式(Prototype)

1、定义       原型模式(Prototype)就是通过复制一个已经存在的实例来返回新的实例,而不是新建实例,被复制的实例就是我们所称的原型对象,这个原型是可定制的。 2、原理      有两部分...
  • YJian2008
  • YJian2008
  • 2013年12月03日 21:43
  • 566

Android 原型设计模式

简介原型模式是一个创建型的模式.原型就是应该有一个样板实例,我们可以从这个样板对象中复制出一个内部属性一致的对象,其实就是一个”克隆”,被复制的实例就是我们所称”原型”,这个原型是可定制的.主要是原型...
  • u010316858
  • u010316858
  • 2016年03月14日 20:32
  • 1916

设计模式---原型设计模式

原型模式属于创建模式,GOF对他的定义是:用原型实例指定创建对象的种类,并且通过拷贝原型创建新对象。 说白了就是对象拷贝,java中有clone方法实现起来非常的容易。 原型设计模式有几个要素: ...
  • gxy3509394
  • gxy3509394
  • 2012年07月19日 13:53
  • 417

设计模式:简单工厂、方法工厂、抽象工厂、单例、原型、委派、模板、代理、策略

  • 2017年10月04日 20:51
  • 41KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:设计模式之原型设计模式
举报原因:
原因补充:

(最多只允许输入30个字)