设计模式——原型模式

132 阅读2分钟

1. 原型模式概述

原型模式用于创建重复的对象,同时又能保证性能。
原型模式也提供了一种创建对象的最佳方式。

(1) 适用情况

利用一个已有的原型对象,快速生成和原型对象一样的实例,并可以进行修改。特别适用于直接创建对象开销很大的场景。

就像是如果有一个模板,就可以快速复制粘贴,而不用每次都花费很大的代价去创建新的对象。

(2) 优点

可以提高性能。

(3) 缺点

需要实现Cloneable接口,并重写clone方法。

2. 原型模式实例

我们需要用原型模式,来得到不同的球。

(1) 先声明抽象类Ball,实现了Cloneable,重写了clone方法

public abstract class Ball implements Cloneable {
    protected String type;

    protected Ball(String type) {
        this.type = type;
    }

    abstract protected void declare();

    @Override
    public Object clone() {
        Object clone = null;
        try {
            clone = super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return clone;
    }
}

(2) 分别实现不同的球类

public class Basketball extends Ball {
    public Basketball() {
        super("Basketball");
    }

    @Override
    protected void declare() {
        System.out.println("我是篮球。");
    }
}
public class Football extends Ball {
    public Football() {
        super("Football");
    }

    @Override
    protected void declare() {
        System.out.println("我是足球。");
    }
}

(3) 实现用来获取球的克隆对象的Cache类

public class BallCache {
    private static Map<String, Ball> balls = new HashMap<>();

    public BallCache() {
        Basketball basketball = new Basketball();
        balls.put("Basketball", basketball);

        Football Football = new Football();
        balls.put("Football", Football);
    }

    public Ball getBall(String type) {
        return (Ball) balls.get(type).clone();
    }
}

(4) 使用原型模式来获取球的实例

public class BallDemo {
    public static void main(String[] args) {
        BallCache ballCache = new BallCache();
        Ball basketBall = ballCache.getBall("Basketball");
        basketBall.declare();

        Ball Football = ballCache.getBall("Football");
        Football.declare();
    }
}

运行结果:

3. 一些思考

Cloneable其实只是一个标记接口,而clone方法其实是Object里面的native方法。
当实现了Cloneable接口后,需要重写Object中的clone方法,然后通过类调用clone方法才能克隆成功。 如果不实现这个接口,只重写clone方法的话,会抛出CloneNotSupportedException异常。

拷贝可以分为引用拷贝浅拷贝深拷贝
引用拷贝就是常见的对象赋值操作,两个引用指向堆中同一块内存。
浅拷贝会创建一个新对象,这个新对象会拷贝基本类型以及引用类型的内存地址,而不会拷贝引用的对象。
深拷贝则是完全拷贝了一个新对象,和原对象没有任何关系。

原型模式可以考虑和单例模式以及工厂模式一起使用,使用单例模式创建原型对象,使用原型模式clone出拷贝对象,做定制化修改,然后由工厂模式提供给调用者,岂不美哉?