标准 专业
多元 极客

设计模式实验室(6)——原型模式

什么是原型模式?

原型模式是一种对象创建型模式。

原型模式使用原型实例指定创建对象的类,并且通过拷贝这些原型创建新的对象。

Java中的克隆就是采用的原型模式。

工作或生活中,我们写的周报,记得手帐,其实每一周都是同一套实现,只是内容不一样而已,这种例子也可以用原型模式来实现。

在消息推送中,用户接收到的消息体的格式,是基本不会变化的,所以也可以使用原型模式。

核心结构

  • Prototype。抽象原型类,既可以是抽象类,也可以是接口,甚至可以是某些具体实现类,主要声明了克隆方法。
  • ConcretePrototype。具体原型类,实现了抽象原型类中声明的克隆方法,在克隆方法中返回一个自己的克隆对象。
  • Client。客户端,原型对象的外部调用,可以根据原型对象的克隆方法获取多个克隆对象。

类图展示

原型模式

代码分析

在模式介绍中,我们举了消息推送格式的例子,接下来我们就对其进行一下实现。

我们使用的是Java中已经存在的Cloneable作为抽象原型类,我们看一下这个类:

public interface Cloneable {

}

什么都没有,你让我继承什么?

别急,忘记了Object类是万物之父了?在我们背过的面试题中,肯定有这么一道题,请说出Object类中的方法,并简述其作用,方法中就有一个clone()方法,Object#clone()方法是一个本地方法。

接下来,我们实现具体原型类:

/**
 * Created by <sunshine> mysunshinedreams@163.com on 2017/1/13 0013.
 * 原型模式——具体原型类
 */
public class Message implements Cloneable {

    private String title;

    private String content;

    private String date;

    public Message clone() {
        Object obj;
        try {
            obj = super.clone();
            return (Message) obj;
        } catch (CloneNotSupportedException e) {
            System.out.println("消息暂时不支持复制");
            return null;
        }
    }

    public void message() {
        System.out.println("title: " + title + "content: " + content + "date: " + date);
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getDate() {
        return date;
    }

    public void setData(String date) {
        this.date = date;
    }
}

原型模式部分已经OK。

其实外部调用就相当于客户端,客户端其实也就是我们惯例的测试代码:

/**
 * Created by <sunshine> mysunshinedreams@163.com on 2017/1/13 0013.
 * 原型模式测试
 */
public class CloneTest {
    public static void main(String[] args) {
        cloneTest();
    }

    private static void cloneTest() {
        Message evening = null;
        try {
            Message model = new Message();
            model.setTitle("早间新闻");
            model.setContent("XXX");
            model.setData("2017-01-13");
            Message noon = model.clone();
            noon.setTitle("午间新闻");
            evening = model.clone();
            evening.setTitle("晚间新闻");
            model.message();
            noon.message();
            evening.message();
            System.out.println(model == noon);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

模式总结

优点

  • 客户根据需求直接调用克隆方法,无需了解内部实现细节,便于代码的维护和扩展。
  • 使用原型模式创建的对象比重新在内存中分配对象性能更好,尤其是在使用大对象的时候。
  • 原型模式和工厂模式类似,但是没有复杂的层级关系,代码结构简单清晰。

缺点

  • 克隆方法位于类的内部,如果需要修改克隆方法,则破坏了开闭原则
  • 如果需要实现深克隆,则需要进行认真的编码,加大了开发者的挑战难度。

适用场景

  • 大对象往复创建。
  • 系统设计时,如果发现某一模型中,对象的变化很小,可以采用原型模式构造不同的实例。
赞(2) 投币

评论 抢沙发

慕勋的实验室慕勋的研究院

码字不容易,路过请投币

支付宝扫一扫

微信扫一扫