【设计模式】原型模式 ( 概念简介 | 使用场景 | 优缺点 | 基本用法 )
文章目錄
- I . 原型模式 概念簡(jiǎn)介
- II . 原型模式 使用場(chǎng)景
- III . 原型模式 優(yōu)缺點(diǎn)
- IV . 原型模式 實(shí)現(xiàn)及 簡(jiǎn)單示例
I . 原型模式 概念簡(jiǎn)介
原型模式 : 用原型實(shí)例指定創(chuàng)建對(duì)象的種類,并且通過(guò)拷貝這些原型創(chuàng)建新的對(duì)象
① 設(shè)計(jì)模式類型 : 創(chuàng)建型設(shè)計(jì)模式 ;
② 原型實(shí)例對(duì)象 : 給出原型實(shí)例對(duì)象 , 根據(jù)該對(duì)象創(chuàng)建新對(duì)象 ;
③ 創(chuàng)建對(duì)象類型 : 創(chuàng)建對(duì)象的種類由原型的實(shí)例對(duì)象類型確定 ;
④ 創(chuàng)建方式 : 不調(diào)用構(gòu)造函數(shù) , 而是通過(guò)克隆原型的實(shí)例對(duì)象 , 使用現(xiàn)有對(duì)象創(chuàng)建另一個(gè)相同類型的對(duì)象 , 隱藏創(chuàng)建細(xì)節(jié) ;
II . 原型模式 使用場(chǎng)景
原型模式使用場(chǎng)景 : 原型模式的目的是 降低實(shí)例對(duì)象個(gè)數(shù) , 減少構(gòu)造函數(shù)的調(diào)用次數(shù) ;
① 類初始化消耗資源過(guò)多 : 如果類初始化時(shí)消耗過(guò)多的資源 , 如這個(gè)類中某個(gè)成員占用大量?jī)?nèi)存 , 為了節(jié)省開銷 ;
② 初始化繁瑣耗時(shí) : 類對(duì)象創(chuàng)建時(shí)經(jīng)過(guò)大量的計(jì)算 , 或與本地資源 ( 數(shù)據(jù)庫(kù) , 文件 ) 頻繁交互 , 每次創(chuàng)建消耗大量的 CPU 與 時(shí)間資源 ;
③ 構(gòu)造函數(shù)復(fù)雜 : 類中定義的構(gòu)造函數(shù)復(fù)雜 ;
④ 實(shí)例對(duì)象數(shù)量龐大 : 如果在內(nèi)存中循環(huán)創(chuàng)建了很多該實(shí)例對(duì)象 , 就可以使用原型模式復(fù)用不用的對(duì)象 , 用于創(chuàng)建新對(duì)象 ;
III . 原型模式 優(yōu)缺點(diǎn)
1 . 原型模式優(yōu)點(diǎn) : 性能高 , 簡(jiǎn)單 ;
① 性能高 : 使用原型模式復(fù)用的方式創(chuàng)建實(shí)例對(duì)象 , 比使用構(gòu)造函數(shù)重新創(chuàng)建對(duì)象性能要高 ; ( 針對(duì)類實(shí)例對(duì)象開銷大的情況 )
② 流程簡(jiǎn)單 : 原型模式可以簡(jiǎn)化創(chuàng)建的過(guò)程 , 可以直接修改現(xiàn)有的對(duì)象實(shí)例的值 , 達(dá)到復(fù)用的目的 ; ( 針對(duì)構(gòu)造函數(shù)繁瑣的情況 )
2 . 原型模式缺點(diǎn) : 實(shí)現(xiàn)復(fù)雜 , 坑多 ;
① 覆蓋 clone 方法 ( 必須 ) : 必須重寫對(duì)象的 clone 方法 , Java 中提供了 cloneable 標(biāo)識(shí)該對(duì)象可以被拷貝 , 但是必須覆蓋 Object 的 clone 方法才能被拷貝 ;
② 深拷貝 與 淺拷貝 風(fēng)險(xiǎn) : 克隆對(duì)象時(shí)進(jìn)行的一些修改 , 容易出錯(cuò) ; 需要靈活運(yùn)用深拷貝與淺拷貝操作 ;
IV . 原型模式 實(shí)現(xiàn)及 簡(jiǎn)單示例
1 . 原型模式實(shí)現(xiàn) :
① 對(duì)象創(chuàng)建原理 : 創(chuàng)建實(shí)例對(duì)象時(shí)使用原型模式 , 就是調(diào)用類的 clone 方法 , 直接克隆拷貝現(xiàn)有的實(shí)例對(duì)象 , 生成新的對(duì)象 ;
② 實(shí)現(xiàn) Cloneable 接口 : 原型模式類需要實(shí)現(xiàn) Cloneable 接口 , 如下面的 Student 類 ( class Student implements Cloneable ) 就實(shí)現(xiàn)了該接口 ;
③ 重寫 clone() 方法 : 通常情況下直接調(diào)用父類的 clone 方法即可 , 這種方式是淺拷貝 ,
protected Object clone() throws CloneNotSupportedException{}2 . 原型模式類代碼示例 :
① 代碼實(shí)現(xiàn) : Student 類實(shí)現(xiàn) Cloneable 接口 , 重寫了 clone() 方法 , 直接調(diào)用父類的 clone() 方法 ;
② 地址打印 : 注意 toString 中調(diào)用到了父類的打印方法 , super.toString() , 該方法打印 類名@地址 信息 , 可以幫助我們通過(guò)內(nèi)存地址信息 , 看到是否真正的創(chuàng)建了一個(gè)新的實(shí)例對(duì)象 ;
package kim.hsl.design.prototype;/*** 原型模式實(shí)現(xiàn)流程 : 使用 clone 方法實(shí)現(xiàn)原型模式* 1 . 類繼承 Cloneable 接口* 2 . 實(shí)現(xiàn) protected Object clone() 方法*/ public class Student implements Cloneable {private String name;private int age;public Student() {System.out.println("調(diào)用 Student 默認(rèn)構(gòu)造函數(shù)");}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overrideprotected Object clone() throws CloneNotSupportedException {System.out.println("調(diào)用 Student clone 方法");return super.clone();}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", " + super.toString() +'}';} }3 . 使用原型模式創(chuàng)建實(shí)例測(cè)試代碼 :
① 創(chuàng)建一個(gè)原型對(duì)象 : 首先使用構(gòu)造函數(shù) , 創(chuàng)建一個(gè)原型對(duì)象 newStudent , 之后的對(duì)象都是根據(jù)該原型對(duì)象 clone 創(chuàng)建的 ;
② 使用原型模式創(chuàng)建對(duì)象 : 循環(huán)中 , 通過(guò)調(diào)用原型對(duì)象 newStudent 的 clone() 方法 , 創(chuàng)建一個(gè)新的對(duì)象 ;
③ 性能分析 : 使用 clone 方法創(chuàng)建對(duì)象 , 比直接使用 new 構(gòu)造函數(shù)方法開銷更小 , 性能更高 , 如果要?jiǎng)?chuàng)建大量該對(duì)象示例 , 建議使用原型模式 , 使用 clone() 方法大量創(chuàng)建該對(duì)象 ;
package kim.hsl.design.prototype;public class Main {public static void main(String[] args) {try {//測(cè)試使用 clone 方法實(shí)現(xiàn)的原型模式 , 使用原型模式創(chuàng)建 10 個(gè)對(duì)象Student newStudent = new Student();/*需求聲明 : 此時(shí)要?jiǎng)?chuàng)建 10 個(gè) Student 對(duì)象依次調(diào)用一個(gè)創(chuàng)建好的 Student 對(duì)象的 clone 方法 10 次即可創(chuàng)建 10 個(gè)不同的對(duì)象適用場(chǎng)景 : 這是頻繁創(chuàng)建大量的對(duì)象 , 該場(chǎng)景下適合使用原型模式*/for (int i = 0; i < 10; i++) {// 1 . 使用 clone 方法創(chuàng)建對(duì)象Student student = (Student) newStudent.clone();// 2 . 設(shè)置克隆出的對(duì)象參數(shù)student.setName("Tom" + i);student.setAge(10 + i);System.out.println(student);}} catch (CloneNotSupportedException e) {//捕獲 clone 方法可能產(chǎn)生的異常e.printStackTrace();}} }4 . 執(zhí)行結(jié)果 : 通過(guò)打印出的字符串序列分析 , 注意每個(gè)對(duì)象的地址 Student@1b6d3586 , Student@4554617c … , 10 個(gè)對(duì)象的地址都不相同 , 說(shuō)明每個(gè)對(duì)象都是一個(gè)新的實(shí)例對(duì)象 ;
調(diào)用 Student 默認(rèn)構(gòu)造函數(shù) Student clone 方法 注冊(cè)學(xué)生信息 : Student{name='Tom0', age=10, kim.hsl.design.prototype.Student@1b6d3586} Student clone 方法 注冊(cè)學(xué)生信息 : Student{name='Tom1', age=11, kim.hsl.design.prototype.Student@4554617c} Student clone 方法 注冊(cè)學(xué)生信息 : Student{name='Tom2', age=12, kim.hsl.design.prototype.Student@74a14482} Student clone 方法 注冊(cè)學(xué)生信息 : Student{name='Tom3', age=13, kim.hsl.design.prototype.Student@1540e19d} Student clone 方法 注冊(cè)學(xué)生信息 : Student{name='Tom4', age=14, kim.hsl.design.prototype.Student@677327b6} Student clone 方法 注冊(cè)學(xué)生信息 : Student{name='Tom5', age=15, kim.hsl.design.prototype.Student@14ae5a5} Student clone 方法 注冊(cè)學(xué)生信息 : Student{name='Tom6', age=16, kim.hsl.design.prototype.Student@7f31245a} Student clone 方法 注冊(cè)學(xué)生信息 : Student{name='Tom7', age=17, kim.hsl.design.prototype.Student@6d6f6e28} Student clone 方法 注冊(cè)學(xué)生信息 : Student{name='Tom8', age=18, kim.hsl.design.prototype.Student@135fbaa4} Student clone 方法 注冊(cè)學(xué)生信息 : Student{name='Tom9', age=19, kim.hsl.design.prototype.Student@45ee12a7}總結(jié)
以上是生活随笔為你收集整理的【设计模式】原型模式 ( 概念简介 | 使用场景 | 优缺点 | 基本用法 )的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【Kotlin】扩展接收者 与 分发接收
- 下一篇: 【设计模式】原型模式 ( 浅拷贝 | 深