文章首发:
创建型模式:原型模式
五大创建型模式之五:原型模式。
姓名 :原型模式
英文名 :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() 方法,通过实现这个方法,可以实现对象的拷贝,就是不用调用构造方法,直接通过对内存的拷贝来创建一个新的对象。这就是原型模式的实现方式,通过原型模式可以提高创建对象的效率。
代码:
Prototype Pattern
通过原型模式,绕过构造方法创建对象,利用内存直接拷贝对象,提高对象的创建性效率。在有大量的对象创建或者类初始化消耗多资源的场景下可以利用原型模式来优化。当然在实现的过程中,要注意浅拷贝与深拷贝的问题,防止写出 bug,文章主要介绍原型模式,就不详细说这个问题了,留给大家去扩展了解。
推荐阅读:
单一职责原则(方法:修改名字还是密码?接口:洗碗、买菜还是倒垃圾?类:注册、登录和注销)
里氏替换原则(我儿来自新东方烹饪)
依赖倒置原则(抠门的饭店老板)
接口隔离原则(小伙子的作坊)
迪米特法则(手机上看电子书)
开闭原则(社保这点事)
创建型模式:单例模式(小明就只有 1 辆车)
创建型模式:工厂方法(小明家的车库)
创建型模式:抽象工厂(宝马车就得用宝马轮胎和宝马方向盘)
创建型模式:建造者模式(汤这么煲)
公众号后台回复『大礼包』获取 Java、Python、IOS 等教程
加个人微信备注『教程』获取架构师、机器学习等教程
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。