原型模式

原型模式

什么是原型模式

原型模式:当创建给定类的实例的过程很昂贵或很复杂时,就使用原型模式。

原型模式是一种创建型模式,允许用户从一个样板实例中复制出一个内部属性一致的对象,俗称克隆。被复制的实例称为原型。原型模式多用在比较复杂或耗时的情况下,因为复制一个已经存在的实例可以时程序运行更高效。

原型类需要具备两个前提条件:

  • 实现Cloneable接口。在Java语言中,Cloneable接口只有一个作用,就是运行时通知虚拟机可以安全的在实现了此接口的类上使用clone方法。在Java虚拟机中,只有实现了这个接口的类才能被拷贝,否则会抛出CloneNotSupportedException异常。
  • 重写Object类中的clone方法。Object类中的clone方法,作用时返回对象的一个拷贝,其作用域是protected,一般类无法调用,因此,需要重写clone方法为public修饰符的。

使用原型模式的注意事项:

  • 使用原型模式复制对象不会调用构造方法。对象的复制是通过调用Object类的clone方法完成的,它直接在内存中复制数据,因此不会调用到类的构造方法。不但构造方法中的代码不会执行,甚至连访问权限都对原型模式无效。单例模式中,只要将构造方法的访问权限设置为private,就可以实现单例。但是clone方法无视构造方法的权限,所以,单例模式和原型模式是冲突的。
  • Object类的clone方法只会拷贝对象中的基本数据类型,对于数组、容器对象、引用对象等都不会拷贝,这就是浅拷贝。如果需要实现深拷贝,必须将原型模式中的数组、容器对象、引用对象等另行拷贝。

UML类图

原型模式

UML成员

Prototype:抽象原型类。声明克隆的能力

ConcretePrototype:具体原型类

Client:客户端

具体场景

科学模拟游戏中一个科学家研究出克隆技术,需要对小狗做实验,现用代码实现小狗的克隆结果。

例子

原型狗类:

public abstract class DogPrototype implements Cloneable {
    public String name;
    public int age;
    public ArrayList<String> call = new ArrayList<> ();

    @Override
    public Object clone() throws CloneNotSupportedException {
        DogPrototype dog = (DogPrototype) super.clone ();
        dog.call = (ArrayList<String>) this.call.clone();
        return dog;
    }

    public abstract void show();
}

具体可被克隆的狗类:

public class Dog extends DogPrototype {
    @Override
    public void show() {
        System.out.println(this.toString ());
        System.out.println("name is " + this.name + "\n" +
                            "age is " + this.age + "\n" +
                            "call is " + this.call);
    }
}

客户端:

public class Client {
    public static void main(String args[]) throws CloneNotSupportedException {
        Dog dog = new Dog ();
        dog.name = "tom";
        dog.age = 1;
        dog.call.add ("wangwang");
        dog.call.add ("wuwu");
        Dog dog1 = (Dog) dog.clone ();
        dog.show ();
        dog1.show ();
        System.out.println(dog == dog1);
    }
}

运行结果:

prototype.Dog@4554617c
name is tom
age is 1
call is [wangwang, wuwu]
prototype.Dog@74a14482
name is tom
age is 1
call is [wangwang, wuwu]
false

优点

  • 向客户隐藏制造新实例的复杂性
  • 提供让客户能够产生未知类型对象的选项
  • 在某些环境下,复制对象比创建对象更有效

缺点

  • 对象的复制有时先当复杂
  • 逃避了构造函数的约束
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值