建立型模式:原型模式
個人公眾號原文:
建立型模式:原型模式
五大建立型模式之五:原型模式。
簡介
姓名:原型模式
英文名: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,文章主要介紹原型模式,就不詳細說這個問題了,留給大家去擴充套件瞭解。
參考資料:《大話設計模式》、《Java設計模式》、《設計模式之禪》、《研磨設計模式》、《Head First 設計模式》
希望文章對您有所幫助,設計模式系列會持續更新,感興趣的同學可以關注公眾號: LieBrother ,第一時間獲取文章推送閱讀,也可以一起交流,交個朋友。