设计模式之原型模式

什么是原型模式

什么是原型模式,就是根据一个已经存在的对象实例,复制创建出多个对象实例的设计方法。已经存在的对象实例就是原型对象。原型模式属于创建型的设计模式。

当创建对象的代价交高时,可是使用原型模式复制拷贝对象,这样更做效率更高。

原型模式复制对象一般会用到Object类的clone方法。在Java中实现对象拷贝或克隆,使用clone()方法。

能够实现克隆的Java类必须实现一个标识接口Cloneable,表示这个Java类支持复制。如果一个类没有实现这个接口但是调用了clone()方法,Java编译器将抛出一个CloneNotSupportedException异常。

原型模式的几种使用场景

1、通过 new 产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式,创建原型对象后缓存,再使用该种对象时,返回它的拷贝。

2、一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用。

3、如果想要让生成实例的框架不再依赖于具体的类,这时,不能指定类名来生成实例,而要事先“注册”一个“原型”实例,然后通过复制该实例来生成新的实例。

原型模式代码实现

将创建一个抽象类 Animal和扩展了 Animal类的实体类Cat、Dog。下一步是定义类 AnimalCache,该类把 Animal 对象存储在一个 Hashtable 中,并在请求的时候返回它们的克隆。

1、先定义一个原型抽象类,可以是接口,实现Cloneable接口。

public abstract class Animal implements Cloneable{

    // 名字
    protected String name;

    // 重量
    protected float weight;

    // 叫声,定义为抽象的
    abstract void bark();

    // 克隆,此处直接使用object的clone来进行对象拷贝
    public Object clone(){
        Object clone = null;
        try {
            clone = super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return clone;
    }
}

2、创建两个具体的实体类,继承或实现上面的原型抽象类或接口。

public class Cat extends Animal{

    public Cat(String name, float weight){
        this.name = name;
        this.weight = weight;
    }
    @Override
    void bark() {
        System.out.println("猫叫。。。。。");
    }
}

public class Dog extends Animal{

    public Dog(String name, float weight){
        this.name = name;
        this.weight = weight;
    }
    @Override
    void bark() {
        System.out.println("狗叫。。。。。");
    }
}

3、创建一个类,从数据库获取实体类,并把它们存储在一个 Hashtable 中。

public class AnimalCache {
    private static Hashtable<String, Animal> animalMap
            = new Hashtable<String, Animal>();

    public static Animal getAnimal(String name) {
        Animal cachedAnimal = animalMap.get(name);
        return (Animal) cachedAnimal.clone();
    }

    public static void loadCache() {
        Cat cat = new Cat("tom",50);
        animalMap.put("cat",cat);

        Dog dog = new Dog("小六",100);
        animalMap.put("dog",dog);

    }
}

4、创建一个PrototypePatternTest 使用 AnimalCache 类来获取存储在 Hashtable 中的形状的克隆。

public class PrototypePatternTest {
    public static void main(String[] args) {
        AnimalCache.loadCache();
        Animal dog1 = AnimalCache.getAnimal("dog");
        Animal dog2 = AnimalCache.getAnimal("dog");
        System.out.println(dog1);
        System.out.println(dog2);
        dog2.bark();
        Animal cat2 = AnimalCache.getAnimal("cat");
        cat2.bark();
    }
}

执行程序,输出结果如下:

com.herp.pattern.prototype.Dog@4554617c
com.herp.pattern.prototype.Dog@74a14482
狗叫。。。。。
猫叫。。。。。

可以看到两个,获取了两次dog对象,每次获取到的都是不同的对象。同时也是原型对象的拷贝。

原型模式类图分析

在这里插入图片描述
对应原型模式中具体角色:
Animal:抽象的原型类,可以为抽象类或接口,负责定义用于复制现有实例来生成新实例的方法,也就是克隆或拷贝对象的方法。

Cat和Dog类:具体的原型类。实现复制现有实例并生成新实例的方法。也可以不实现,直接使用抽象原型中实现的拷贝方法。

AnimalCache类:客户类,使用者,负责通过调用原型类的克隆方法生成新对象。

PrototypePatternTest 属于测试类main入口。
(完)

往期设计模式文章回顾。
工厂模式超详解(代码示例)
Java面试必备:手写单例模式

微信公众号
在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值