【设计模式-2】原型模式的原理、代码实现及类图展示

 我们一定对类的实例化比较熟悉,前面我们说的单例、还有3种工厂模式都是通过new关键字来创建对象,下面我们来了解一种新的对象创建的方式。

1. 定义

 原型模式也是一种创建型的设计模式,实现和原理总体比较简单,一句话总结呢,就是可以实现用已有的对象创建新的对象,而不是用类来实例化对象,这样可以起到提升效率的目的。

 众所周知,类的实例化可以创建对象,但其实这是一个比较耗时耗力的工作,尤其是在大量实例化对象的业务场景下,可能会对系统的性能造成很大的影响。这时候,原型模式就可以很好的解决问题,用已有的对象来生成对象的副本,这里已有的对象就是原型对象,副本对象就是拷贝对象。这样对于那些有非常复杂的初始化的操作,或者是需要消耗大量资源的情况,原型模式的优势就体现出来了。

2. 代码实现

 我们来举一个飞机大战的游戏例子,游戏的场是在手机屏幕上方,飞下来很多敌机,而我方战机只有一架,其中敌机的飞行轨迹必须是呈上下直线型的,我方战机可以上下左右移动。因为本篇我们学习原型模式,所以重点关照的是敌机,我方战机其实可以通过前面讲的单例模式实现。

2.1 实例化方式

 假设游戏过程有500架敌机出现,通常情况下,使用实例化创建对象的方式,代码实现可以这样。

public class EnemyPlain {
    // x坐标
    private int x;
    // y坐标
    private int y;
    // 敌机固定x坐标,只能上下移动
    public EnemyPlain(int x) {
        this.x = x;
    }
    public int getX() {
        return x;
    }
    public int getY() {
        return y;
    }
    // 手柄每调用一次setY方法,Y坐标加一
    public void setY() {
        y ++ ;
    }
}

 客户端获取敌机的方法如下:

public class Client {
    public static void main(String[] args) {
        // 500架敌机集合
        List<EnemyPlain> enemyPlains = new ArrayList<>();
        // 实例化500架敌机
        for (int i = 0; i < 500; i++) {
            // 随机出现在0~200的坐标内
            EnemyPlain enemyPlain = new EnemyPlain(RandomUtil.randomInt(200));
            enemyPlains.add(enemyPlain);
        }
    }
}

 这种代码实现的方式是很常见的,但要命的是这500个对象在客户端初始化的时候就会被创建出来,500个对象会占用大量的堆内存空间,这还是定义的对象只有两个属性的前提下。另外,CPU本身就是很宝贵的资源,一次性实例化500个对象,本身也会消耗系统很大的系统资源,极端的情况下会造成游戏界面卡顿,造成不友好的用户体验,下面我们用原型模式来试一下。

2.2 原型模式

 原型模式的代码实现,首先把原型类实现java.lang.Clone接口,接着实现 clone()方法。

// 1.实现java.lang.Clone接口
public class EnemyPlain implements Cloneable {
    // x坐标
    private int x;
    // y坐标
    private int y;
    // 敌机固定x坐标,只能上下移动
    public EnemyPlain(int x) {
        this.x = x;
    }
    public int getX() {
        return x;
    }
    public int getY() {
        return y;
    }
    // 手柄每调用一次setY方法,Y坐标加一
    public void setY() {
        y ++ ;
    }
    public void setX(int x) {
        this.x = x;
    }
    // 重写克隆 clone 方法
    @Override
    public EnemyPlain clone() throws CloneNotSupportedException {
        return (EnemyPlain)super.clone();
    }
}

 客户端获取原型拷贝副本代码实现:

public class ClientAno {
    public static void main(String[] args) throws CloneNotSupportedException {
        // 创建原型对象
        EnemyPlain enemyPlain = new EnemyPlain(100);
        // 存放500架敌机
        List<EnemyPlain> list = new ArrayList<>();
        // 克隆500架敌机
        for (int i = 0; i < 500; i++) {
            EnemyPlain clonePlain = enemyPlain.clone();
            // 设置横坐标
            clonePlain.setX(RandomUtil.randomInt(200));
            list.add(clonePlain);
        }
    }
}

 这里需要特别说明,clone()方法并不是从Cloneable接口实现来的,而是继承自java.lang.Object对象。另外,一般在获取克隆对象的时候,可以借助工厂模式一块实现。

3. UML类图

 下面,就以上面飞机大战这个游戏的这个例子,画一个原型模式的UML类图。

【设计模式-2】原型模式的原理、代码实现及类图展示_第1张图片

你可能感兴趣的:(设计模式,设计模式,原型模式)