日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java描述设计模式(05):原型模式

發布時間:2025/3/17 java 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java描述设计模式(05):原型模式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、原型模式簡介

1、基礎概念

原型模式屬于對象的創建模式。通過給出一個原型對象來指明所有創建的對象的類型,然后用復制這個原型對象的辦法創建出更多同類型的對象。

2、模式結構

原型模式要求對象實現一個可以“克隆”自身的接口,這樣就可以通過復制一個實例對象本身來創建一個新的實例。這樣一來,通過原型實例創建新的對象,就不再需要關心這個實例本身的類型,只要實現了克隆自身的方法,就可以通過這個方法來獲取新的對象,而無須再去通過new來創建。

3、代碼實現

1)、UML關系圖

Java描述設計模式(05):原型模式
2)、核心角色

這種形式涉及到三個角色:

1)、客戶(Client)角色:客戶類提出創建對象的請求。

2)、抽象原型(Prototype)角色:這是一個抽象角色,通常由一個Java接口或Java抽象類實現。此角色給出所有的具體原型類所需的接口。

3)、具體原型(Concrete Prototype)角色:被復制的對象。此角色需要實現抽象的原型角色所要求的接口。

3)、基于JDK源碼實現

/*** 基于JDK源碼方式實現原型模式*/ public class C01_Property {public static void main(String[] args) {Product product = new Product("機械鍵盤","白色",100.00) ;Product product1 = (Product) product.clone();Product product2 = (Product) product.clone();System.out.println(product1);System.out.println(product2);System.out.println(product1==product2); // false} } class Product implements Cloneable {private String name ;private String color ;private Double price ;public Product(String name, String color, Double price) {this.name = name;this.color = color;this.price = price;}@Overridepublic String toString() {return "Product{" +"name='" + name + '\'' +", color='" + color + '\'' +", price=" + price +'}';}@Overrideprotected Object clone() {Product product = null ;try{product = (Product)super.clone() ;} catch (Exception e){e.printStackTrace();}return product ;}// 省略GET和SET方法 }

二、Spring框架應用

1、配置文件

<!-- 多例Bean --> <bean id="sheep01" class="com.model.design.spring.node05.property.Sheep" scope="prototype" /> <!-- 單例Bean 默認: scope="singleton" --> <bean id="sheep02" class="com.model.design.spring.node05.property.Sheep"/>

2、測試代碼塊

@Test public void test01 (){ApplicationContext context01 = new ClassPathXmlApplicationContext("/spring/spring-property.xml");// 原型模式Sheep sheep1 = (Sheep)context01.getBean("sheep01") ;Sheep sheep2 = (Sheep)context01.getBean("sheep01") ;System.out.println(sheep1==sheep2); // false// 單例模式Sheep sheep3 = (Sheep)context01.getBean("sheep02") ;Sheep sheep4 = (Sheep)context01.getBean("sheep02") ;System.out.println(sheep3==sheep4); // true }

3、核心源碼

  • 所在類:org.springframework.beans.factory.support.AbstractBeanFactory
  • 所在方法:doGetBean

1)、執行流程

if (mbd.isSingleton()) {sharedInstance = this.getSingleton(beanName, new ObjectFactory<Object>() {public Object getObject() throws BeansException {try {return AbstractBeanFactory.this.createBean(beanName, mbd, args);} catch (BeansException var2) {AbstractBeanFactory.this.destroySingleton(beanName);throw var2;}}});bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } else if (mbd.isPrototype()) {var11 = null;Object prototypeInstance;try {this.beforePrototypeCreation(beanName);prototypeInstance = this.createBean(beanName, mbd, args);} finally {this.afterPrototypeCreation(beanName);}bean = this.getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); }

2)、單例多例判斷

所以默認就是單例模式,指定[scope=“prototype”]就是原型模式。

public boolean isSingleton() {return "singleton".equals(this.scope) || "".equals(this.scope); } public boolean isPrototype() {return "prototype".equals(this.scope); }

三、深淺拷貝

1、淺拷貝

  • 數據類型是基本數據類型、String類型的成員變量,淺拷貝直接進行值傳遞,也就是將該屬性值復制一份給新的對象。
  • 數據類型是引用數據類型的成員變量,比如說成員變量是數組、類的對象等,淺拷貝會進行引用傳遞,也就是只是將該成員變量的引用值(內存地址)復制一份給新的對象。實際上兩個對象的成員變量都指向同一個實例。修改其中一個對象屬性會影響到另一個對象的屬性。
  • 淺拷貝是使用默認的 clone()方法來實現。
  • 2、深拷貝

    1)、概念描述

    除了淺拷貝要拷貝的值外,還負責拷貝引用類型的數據。那些引用其他對象的變量將指向被復制過的新對象,而不再是原有的那些被引用的對象,這種對被引用到的對象的復制叫做間接復制。

    2)、源代碼實現

    序列化實現深度克隆

    對象寫到流里的過程是序列化(Serialization)過程;而把對象從流中讀出來的過程則叫反序列化(Deserialization)過程。應當指出的是,寫到流里的是對象的一個拷貝,而原對象仍然存在于JVM里面。

    在Java語言里深度克隆一個對象,常常可以先使對象實現Serializable接口,然后把對象(實際上只是對象的拷貝)寫到一個流里(序列化),再從流里讀回來(反序列化),便可以重建對象。

    /*** 深拷貝和淺拷貝對比案例*/ public class C02_DeepClone {public static void main(String[] args) throws Exception {Dog dog = new Dog("Tom") ;Dog dog1 = (Dog)dog.clone() ;Dog dog2 = (Dog)dog.clone() ;// dog1:1639622804;dog2:1639622804System.out.println("dog1:"+dog1.cat.hashCode()+";dog2:"+dog2.cat.hashCode());Dog dog3 = (Dog)dog.deepClone() ;Dog dog4 = (Dog)dog.deepClone() ;// dog3:1937348256;dog4:1641808846System.out.println("dog3:"+dog3.cat.hashCode()+";dog4:"+dog4.cat.hashCode());} }class Cat implements Serializable {public String name ;public Cat (String name){this.name = name ;} } class Dog implements Cloneable,Serializable {public String name ;public Cat cat ;public Dog (String name){this.name = name ;this.cat = new Cat("Kit") ;}@Overrideprotected Object clone() {Dog dog = null ;try{dog = (Dog)super.clone() ;} catch (Exception e){e.printStackTrace();}return dog ;}public Object deepClone() throws IOException, ClassNotFoundException{//將對象寫到流里面:序列化ByteArrayOutputStream bos = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(bos);oos.writeObject(this);//從流里面讀出對象:反序列化ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());ObjectInputStream ois = new ObjectInputStream(bis);return ois.readObject();} }

    四、優缺點總結

    1、優點總結

    原型模式允許在運行時動態改變具體的實現類型。原型模式可以在運行期間,由客戶來注冊符合原型接口的實現類型,也可以動態地改變具體的實現類型,看起來接口沒有任何變化,但其實運行的已經是另外一個類實例了。因為克隆一個原型就類似于實例化一個類。

    2、缺點總結

    原型模式最主要的缺點是每一個類都必須配備一個克隆方法。配備克隆方法需要對類的功能進行通盤考慮,這對于全新的類來說不是很難,而對于已經有的類不一定很容易,特別是當一個類引用不支持序列化的間接對象,或者引用含有循環結構的時候。

    五、源代碼地址

    GitHub地址:知了一笑 https://github.com/cicadasmile/model-arithmetic-parent 碼云地址:知了一笑 https://gitee.com/cicadasmile/model-arithmetic-parent


    總結

    以上是生活随笔為你收集整理的Java描述设计模式(05):原型模式的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。