专栏首页LieBrother创建型模式:原型模式

创建型模式:原型模式

五大创建型模式之五:原型模式

简介

姓名:原型模式

英文名:Prototype Pattern

价值观:效率第一

个人介绍

Specify the kinds of objects to create using a prototypical instance,and create new objects by copying this prototype.

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

(来自《设计模式之禅》)

又到了一个系列的最后一篇文章了,今天是创建型模式的最后一篇。什么是创建型模式呢?创建型模式是对类的实例化过程进行抽象,使对象的创建和使用分离,从而使代码更加灵活。

我们平时使用最多的一种创建对象方式就是 new ABC(),直接通过构造方法来创建一个对象。通过原型模式来创建对象则不用调用构造方法,就可以创建一个对象。下面来揭开它的面纱。

你要的故事

前几天有出版社的老师邀请写书,鉴于深知自己水平还不足以出书,所以没有合作,还在努力学习,以后有能力有机会再考虑这方面的事情。

今天的故事就从出书讲起。我们知道一本新书发版的时候,会复印很多册,如果销售得好,会有很多个印刷版本。我们来了解复印一批书籍这个过程是怎么实现的。小明写下了下面这段代码。

public class NoPrototypeTest {

    public static void main(String[] args) {
        for (int i = 1; i <= 10; i ++) {
            Book book = new Book("娱乐至死", "尼尔波兹曼", "社会科学", "XXXX");
            System.out.println("复印书籍:" + book.getName() + ",第 " + i + " 本");
        }
    }

}

class Book {
    private String name;
    private String author;
    private String type;
    private String content;
    public Book(String name, String author, String type, String content) {
        this.name = name;
        this.author = author;
        this.type = type;
        this.content = content;
        System.out.println("实例化书籍:" + this.name);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getContent() {
        return content;
    }

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

// 打印结果:
实例化书籍:娱乐至死
复印书籍:娱乐至死,第 1 本
实例化书籍:娱乐至死
复印书籍:娱乐至死,第 2 本
实例化书籍:娱乐至死
复印书籍:娱乐至死,第 3 本
实例化书籍:娱乐至死
复印书籍:娱乐至死,第 4 本
实例化书籍:娱乐至死
复印书籍:娱乐至死,第 5 本
实例化书籍:娱乐至死
复印书籍:娱乐至死,第 6 本
实例化书籍:娱乐至死
复印书籍:娱乐至死,第 7 本
实例化书籍:娱乐至死
复印书籍:娱乐至死,第 8 本
实例化书籍:娱乐至死
复印书籍:娱乐至死,第 9 本
实例化书籍:娱乐至死
复印书籍:娱乐至死,第 10 本

上面小明的代码复印了 10 本《娱乐至死》,代码逻辑没有问题,有个问题就是复印一本就实例化一次书籍,这个实例化可以减少么?使用原型模式可以实现。小明根据这些提示,重新修改了代码。

public class PrototypeTest {

    public static void main(String[] args) {
        Book2 book1 = new ConcreteBook("娱乐至死", "尼尔波兹曼", "社会科学", "XXXX");
        System.out.println("复印书籍:" + book1.getName() + ",第 " + 1 + " 本");
        for (int i = 2; i <= 10; i ++) {
            Book2 book2 = (Book2) book1.clone();
            System.out.println("复印书籍:" + book2.getName() + ",第 " + i + " 本");
        }


    }

}

/**
 * 抽象类
 */
abstract class Book2 implements Cloneable {

    private String name;
    private String author;
    private String type;
    private String content;
    public Book2(String name, String author, String type, String content) {
        this.name = name;
        this.author = author;
        this.type = type;
        this.content = content;
        System.out.println("实例化书籍:" + this.name);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getContent() {
        return content;
    }

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

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

/**
 * 具体类
 */
class ConcreteBook extends Book2 {

    public ConcreteBook(String name, String author, String type, String content) {
        super(name, author, type, content);
    }
}

打印结果:
实例化书籍:娱乐至死
复印书籍:娱乐至死,第 1 本
复印书籍:娱乐至死,第 2 本
复印书籍:娱乐至死,第 3 本
复印书籍:娱乐至死,第 4 本
复印书籍:娱乐至死,第 5 本
复印书籍:娱乐至死,第 6 本
复印书籍:娱乐至死,第 7 本
复印书籍:娱乐至死,第 8 本
复印书籍:娱乐至死,第 9 本
复印书籍:娱乐至死,第 10 本

看,打印结果和第一次实现的结果完全不一样,这一次只实例化了一次,后面复印的书籍都没有实例化。我们看看代码的变化,代码中最最主要的就是 Book2 实现了 Cloneable 接口,这个接口有个 clone() 方法,通过实现这个方法,可以实现对象的拷贝,就是不用调用构造方法,直接通过对内存的拷贝来创建一个新的对象。这就是原型模式的实现方式,通过原型模式可以提高创建对象的效率

代码:

https://github.com/1CSH1/DesignPatterns/blob/master/src/com/liebrother/designpatterns/prototype/

总结

通过原型模式,绕过构造方法创建对象,利用内存直接拷贝对象,提高对象的创建性效率。在有大量的对象创建或者类初始化消耗多资源的场景下可以利用原型模式来优化。当然在实现的过程中,要注意浅拷贝与深拷贝的问题,防止写出 bug,文章主要介绍原型模式,就不详细说这个问题了,留给大家去扩展了解。

参考资料:《大话设计模式》、《Java设计模式》、《设计模式之禅》、《研磨设计模式》、《Head First 设计模式》

本文分享自微信公众号 - LieBrother(gh_b6002a4cbc1f),作者:LieBrother

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-01-27

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 迪米特法则

    1. Each unit should have only limited knowledge about other units: only units "c...

    LieBrother
  • 开闭原则

    Software entities (classes, modules, functions, etc.) should be open for extensi...

    LieBrother
  • 行为型模式:状态模式

    姓名 :状态模式 英文名 :State Pattern 价值观 :有啥事让状态我来维护 个人介绍 : Allow an object to alter its ...

    LieBrother
  • 看一遍就懂,详解java多线程——volatile

    多线程一直以来都是面试必考点,而volatile、synchronized也是必问点,这里我试图用容易理解的方式来解释一下volatile。

    天涯泪小武
  • springboot2 启动后执行代码

    DencyCheng
  • 说说FactoryBean

    常用的使用场景为:根据不同的配置类型返回不同类型的处理Bean,整体上简化了XML配置等。

    春哥大魔王
  • Dora.Interception: 一个为.NET Core度身定制的AOP框架

    多年从事框架设计开发使我有了一种强迫症,那就是见不得一个应用里频繁地出现重复的代码。之前经常Review别人的代码,一看到这样的程序,我就会想如何将这些重复的代...

    蒋金楠
  • HandlerMethodArgumentResolver(四):自定参数解析器处理特定应用场景,介绍PropertyNamingStrategy的使用【享学Spring MVC】

    前面通过三篇文章介绍了HandlerMethodArgumentResolver这个参数解析器以及它的所有内置实现,相信看过的小伙伴对它的加载、初始化、处理原理...

    YourBatman
  • fastjson:javabean按字段(field)序列化存储为Map并反序列化

    大部分json工具对java对象整体序列化都提供了简单的调用方式,以fastjson为例: Model model = new Model(); String ...

    用户1148648
  • 最新2018年6月份Wordpress通杀全版本漏洞 详情及利用方法

    2018年6月29日,wordpress爆出最新漏洞,该网站漏洞通杀所有wordpress版本,包括目

    网站安全专家

扫码关注云+社区

领取腾讯云代金券