91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java中原型模式的示例分析

發布時間:2021-06-12 18:46:06 來源:億速云 閱讀:274 作者:小新 欄目:web開發

這篇文章將為大家詳細講解有關Java中原型模式的示例分析,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

故事

還記得大四那年找工作,無意中我得從網上找到一份相對漂亮的程序員簡歷模板,然后全班同學開啟瘋狂的簡歷拷貝(U盤)。同時也鬧出了一個笑話,有幾位同學,拷貝過去的簡歷,內容完全沒改,名字都沒有改,截止投給面試官(校招面試官)。后來,結果大家也應該能猜出來,大家都去實習了,部分人還在找工作。后面公司面試官和同伴的其他同學反饋:收到一毛一樣的簡歷,好幾份,回來大家一聊就知道問題出哪里了,承認了自己拷貝過去完全沒改就拿出去投了,害,尷尬的一匹。

把簡歷拷貝分為為兩種:

  • 一種是拷貝簡歷,然后把信息修改成自己的

  • 另外一種是,拷貝簡歷,內容什么都不改。

原型模式定義

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

大致意思:用原型實例指定創建對象的種類,并且通過復制這些原型創建新的對象。

原型模式:Prototype Pattern,屬于創建型模式。

調用者不需要知道任何創建細節,也不用調用構造方法來創建對象。

使用場景

原型模式有如下使用場景:

  • 類初始化消耗資源較多

  • new產生的一個對象需要非常繁瑣的過程(數據準備、訪問權限等)

  • 構造函數比較復雜

  • 循環體內生成大量對象時

  • 在Spring中,原型模式應用的非常廣泛,例如:scope='prototype'

我們可以將一些getter和setter之類封裝成一個工廠方法,然后對于使用的人來說,調用方法就可以了,不需要知道里面的getter和setter是怎么處理的。我們也可以使用JDK提供的實現Cloneable接口,實現快速復制。

創建對象的四種方式:

new、反射、克隆、序列化

實際案例

大家是否有遇到過這種常見,就是項目中規定,不能把與數據庫表映射的entity類返回給前端,所以通常返回給前端的有各種O,比如:XxxVO、XxxBO、XxxDTO...

這時候就會出現下面的場景,大家也想已經猜到了。

下面是與數據庫表映射的UserEntity實體類。

public class UserEntity {     private Long id;     private String name;     private Integer age;     //....可能還有很多屬性     //省略getter setter }

返回給前端或者調用方的UserVO實體類。

public class UserVO {     private Long id;     private String name;     private Integer age;     //....可能還有很多屬性     //省略getter setter }

此時,從數據庫里查出來的UserEntity需要轉換成UserVO,然后再返回給前端(或者調用方)。

public class ObjectConvertUtil {      public static UserVo convertUserEntityToUserVO(UserEntity userEntity) {         if (userEntity == null) {             return null;         }         UserVo userVo = new UserVo();          userVo.setId(userEntity.getId());         userVo.setName(userEntity.getName());         userVo.setAge(userEntity.getAge());          //如果還有更多屬性呢?         return userVo;     } }

從這個util類中,我們可以看出,如果一個類的屬性有幾十個,上百個的,這代碼量是不是有點恐怖?

于是,我們通常都會使用一些工具類來處理,比如常見有以下:

BeanUtils.copy(); JSON.parseObject() Guava工具類 .....

這些工具類就用到了原型模式。

通過一個對象,創建一個新的對象。

也把原型模式稱之為對象的拷貝、克隆。

其實對象的克隆分淺克隆和深克隆,下面我們就來聊聊淺克隆和深克隆。

  • 淺克隆:創建一個新對象,新對象的屬性和原來對象完全相同,對于非基本類型屬性,仍指向原來對象的屬性所指向的對象的內存地址。

  • 深克隆:創建一個新對象,屬性中引用的其他對象也會被克隆,不再指向原有對象地址。

我們先來聊聊淺克隆,都喜歡由淺入深。

淺克隆

比如,我現在相對用戶信息User進行克隆,但是User中有用戶地址信息UserAddress屬性。

以下是代碼的實現:

//用戶地址信息 public class UserAddress  implements Serializable{     private String province;     private String cityCode;      public UserAddress(String province, String cityCode) {         this.province = province;         this.cityCode = cityCode;     } } //用戶信息 public class User implements Cloneable {     private int age;     private String name;     //用戶地址信息     private UserAddress userAddress;      //getter setter 省略      @Override     protected Object clone() throws CloneNotSupportedException {          return super.clone();     } } //測試 public class UserTest {     public static void main(String[] args) throws Exception {         User user = new User();         user.setAge(20);         user.setName("田維常");         UserAddress userAddress = new UserAddress("貴州", "梵凈山");         user.setUserAddress(userAddress);          User clone = (User) user.clone();          System.out.println("克隆前后UserAddress比較:" + (user.getUserAddress() == clone.getUserAddress()));     } }

輸出結果

克隆前后 UserAddress 比較:true

兩個對象屬性 UserAddress 指向的是同一個地址。

這就是所謂的淺克隆,只是克隆了對象,對于該對象的非基本類型屬性,仍指向原來對象的屬性所指向的對象的內存地址。

關系如下:

Java中原型模式的示例分析

深克隆

關于深克隆,我們來用一個很經典的案例,西游記里的孫悟空。一個孫悟空能變成n多個孫悟空,手里都會拿著一個金箍棒。

按照前面的淺克隆,結果就是:孫悟空倒是變成很多孫悟空,但是金箍棒用的是同一根。

深克隆的結果是:孫悟空變成了很多個,金箍棒也變成很多個根。

下面我們用代碼來實現:

//猴子,有身高體重和生日 public class Monkey {     public int height;     public int weight;     public Date birthday; }

孫悟空也是猴子,兵器 孫悟空有個金箍棒:

import java.io.Serializable; //孫悟空的金箍棒 public class JinGuBang implements Serializable{     public float  h=100;     public float  d=10;     //金箍棒變大     public void big(){         this.h *=10;         this.d *=10;     }     //金箍棒變小     public void small(){         this.h /=10;         this.d /=10;     } }

齊天大圣孫悟空:

import java.io.*; import java.util.Date;  //孫悟空有七十二變,拔猴毛生成一個金箍棒 //使用JDK的克隆機制, //實現Cloneable并重寫clone方法 public class QiTianDaSheng extends Monkey implements Cloneable, Serializable {      public JinGuBang jinGuBang;      public QiTianDaSheng() {         this.birthday = new Date();         this.jinGuBang = new JinGuBang();     }      @Override     protected Object clone() throws CloneNotSupportedException {         return this.deepClone();     }      //深克隆     public QiTianDaSheng deepClone() {         try {             //內存中操作完成、對象讀寫,是通過字節碼直接操作             //與序列化操作類似             ByteArrayOutputStream bos = new ByteArrayOutputStream();             ObjectOutputStream oos = new ObjectOutputStream(bos);             oos.writeObject(this);              ByteArrayInputStream bais = new ByteArrayInputStream(bos.toByteArray());             ObjectInputStream bis = new ObjectInputStream(bais);              //完成一個新的對象,底層是使用new創建的一個對象             //詳情可以了解readObject方法             QiTianDaSheng qiTianDaSheng = (QiTianDaSheng) bis.readObject();             //每個猴子的生日不一樣,所以每次拷貝的時候,把生日改一下             qiTianDaSheng.birthday = new Date();             return qiTianDaSheng;         } catch (Exception ex) {             ex.printStackTrace();             return null;         }     }      //淺克隆,就是簡單的賦值     public QiTianDaSheng shalllowClone(QiTianDaSheng target) {         QiTianDaSheng qiTianDaSheng = new QiTianDaSheng();         qiTianDaSheng.height = target.height;         qiTianDaSheng.weight = target.weight;          qiTianDaSheng.jinGuBang = target.jinGuBang;         qiTianDaSheng.birthday = new Date();         return qiTianDaSheng;      } }

接著我們就來測試一下:

public class DeepCloneTest {     public static void main(String[] args) {         QiTianDaSheng qiTianDaSheng = new QiTianDaSheng();         try {             QiTianDaSheng newObject = (QiTianDaSheng) qiTianDaSheng.clone();             System.out.print("深克隆后 ");             System.out.println("金箍棒是否一直:" + (qiTianDaSheng.jinGuBang == newObject.jinGuBang));                      } catch (Exception ex) {             ex.printStackTrace();         }                  QiTianDaSheng newObject=qiTianDaSheng.shalllowClone(qiTianDaSheng);         System.out.print("淺克隆后 ");         System.out.println("金箍棒是否一直:" + (qiTianDaSheng.jinGuBang == newObject.jinGuBang));     } }

輸出結果為:

深克隆后 金箍棒是否一直:false  淺克隆后 金箍棒是否一直:true

結論

深克隆后每個孫悟空都有自己的金箍棒,而淺克隆后每個孫悟空用的金箍棒實質上還是同一根。

Java中原型模式的示例分析

總結

切記:深和淺,指的是克隆對象里的屬性(引用類型)是否指向同一個內存地址。

為了更深刻的理解深克隆和淺克隆,我們回答文中的簡歷拷貝的故事。

  • 深拷貝:拷貝一份簡歷,然后對簡歷中的信息進行修改成自己的

  • 淺拷貝:拷貝一份簡歷,簡歷內容完全不變

優點:

  • Java 原型模式基于內存二進制流復制,比直接 new 的性能會更好一些。

  • 可以利用深克隆保存對象狀態,存一份舊的(克隆出來),在對其修改,可以充當一個撤銷功能。

缺點:

  • 需要配置 clone 方法,改造時需要對已有類進行修改,違背 “開閉原則”。

  • 如果對象間存在多重嵌套引用時,每一層都需要實現克隆。

我們從原型模式的定義,使用場景,真實案例、淺克隆、深克隆、優缺點等方面,對原型模式進行了一個全面的講解。

關于“Java中原型模式的示例分析”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

鸡泽县| 大化| 尉犁县| 阳西县| 军事| 大荔县| 巨野县| 广丰县| 寿宁县| 疏附县| 安陆市| 遵化市| 泸州市| 汤原县| 女性| 湛江市| 张掖市| 库伦旗| 大余县| 常宁市| 龙陵县| 甘德县| 贵南县| 密云县| 盘山县| 汽车| 酒泉市| 周至县| 南充市| 常山县| 公安县| 通山县| 四子王旗| 西贡区| 会理县| 茶陵县| 抚顺县| 惠州市| 南京市| 余庆县| 福海县|