Radio

一个小小程序员

0%

原型模式

原型模式

原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。例如,一个对象需要在一个高代价的数据库操作之后被创建。我们可以缓存该对象,在下一个请求时返回它的克隆,在需要的时候更新数据库,以此来减少数据库调用。

示例演示:
  1. 创建一个抽象类,实现Cloneable接口,提供一个抽象方法,重写Object的clone方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    package test.prototype;

    import lombok.Data;

    @Data
    public abstract class People implements Cloneable {

    private Integer id;

    protected String type;

    abstract void say();

    public Object clone() {
    Object clone = null;
    try {
    clone = super.clone();
    } catch (CloneNotSupportedException e) {
    e.printStackTrace();
    }
    return clone;
    }
    }
  2. 创建两个people实体类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    package test.prototype;

    public class PeopleOne extends People{
    public PeopleOne(){
    type="peopleone";
    }

    @Override
    public void say() {
    System.out.println("my name is peopleone");
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    package test.prototype;

    public class PeopleTwo extends People{
    public PeopleTwo(){
    type="peopletwo";
    }

    @Override
    public void say() {
    System.out.println("my name is peopletwo");
    }
    }
  3. 创建一个存放原型对象的注册表,提供一个获取新实例的方法,用来复制原型,默认初始化两个实例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    package test.prototype;

    import java.util.Hashtable;

    public class PeopleCache {
    private static Hashtable<Integer, People> peopleMap = new Hashtable<>();

    public static People getPeople(Integer id) {
    People people = peopleMap.get(id);
    //复制一个新的实例,属于浅拷贝
    return (People) people.clone();
    }

    public static void loadCache() {
    PeopleOne peopleOne = new PeopleOne();
    peopleOne.setId(1);
    peopleMap.put(peopleOne.getId(), peopleOne);

    PeopleTwo peopleTwo = new PeopleTwo();
    peopleTwo.setId(2);
    peopleMap.put(peopleTwo.getId(), peopleTwo);
    }
    }
  4. 完成上述步骤,我们就可以开始演示了

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    package test.prototype;

    public class PrototypeDemo {
    public static void main(String[] args) {
    PeopleCache.loadCache();
    People peopleOne = PeopleCache.getPeople(1);
    System.out.println(peopleOne.type);
    peopleOne.say();

    People peopleTwo = PeopleCache.getPeople(2);
    System.out.println(peopleTwo.type);
    peopleTwo.say();
    }
    }

    新生成的两个实例就是通过原型clone出来的

    运行结果:

    1
    2
    3
    4
    peopleone
    my name is peopleone
    peopletwo
    my name is peopletwo
说明:

优点: 1、性能提高。 2、逃避构造函数的约束。

缺点: 1、配备克隆方法需要对类的功能进行通盘考虑,这对于全新的类不是很难,但对于已有的类不一定很容易,特别当一个类引用不支持串行化的间接对象,或者引用含有循环结构的时候。 2、必须实现 Cloneable 接口。

欢迎关注我的其它发布渠道