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

溫馨提示×

溫馨提示×

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

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

Java原型設計模式是什么

發布時間:2021-06-24 14:08:31 來源:億速云 閱讀:140 作者:chen 欄目:編程語言

本篇內容介紹了“Java原型設計模式是什么”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

原型模式

原型模式

1、原型模式(Prototype模式)是指:用原型實例指定創建對象的種類,并且通過拷貝這些原型,創建新的對象(復制,粘貼,克隆的意思,盡量避免new的方式)

2、原型模式是一種創建型設計模式,允許一個對象再創建另外一個可定制的對象,無需知道如何創建的細節

3、工作原理是:通過將一個原型對象傳給那個要發動創建的對象,這個要發動創建的對象通過請求原型對象拷貝它們自己來實施創建,即 對象.clone()

這個原型模式我是想了一天,都沒有想到實際開發怎么能用到它,看了很多博客說是Spring創建bean的時候能用到它,在看源碼的時候,好多注解式框架就可以看到

 <bean id="" class="" scope="prototype"/>

怎么實現原型模式呢?

  • 1、Prototype : 原型類,聲明一個克隆自己的接口

  • 2、ConcretePrototype: 具體的原型類, 實現 Cloneable 接口,實現克隆操作,在 JAVA 繼承 Cloneable,重寫 clone(),實現一個克隆自己的操作

  • 3、Client: 讓一個原型對象克隆自己,從而創建一個新的對象(屬性一樣)

原型模式:淺拷貝和深拷貝

1、對于數據類型是基本數據類型的成員變量,淺拷貝會直接進行值傳遞,也就是將該屬性值復制一份給新的對象。

2、對于數據類型是引用數據類型的成員變量,比如說成員變量是某個數組、某個類的對象等,那么淺拷貝會進行引用傳遞,也就是只是將該成員變量的引用值(內存地址)復制一份給新的對象。因為實際上兩個對象的該成員變量都指向同一個實例。在這種情況下,在一個對象中修改該成員變量會影響到另一個對象的該成員變量值,從而達不到我們的需求

舉個例子

諸葛上學的時候絕對是個學渣:每天都不寫作業,每天早讀下來老師都要檢查作業,所以諸葛從來早讀不讀書,和班花班長學習委員關系搞好,每天都來抄他們的作業,完成一個復制的過程,那么問題來了,每個班不止有一個學渣,學渣有那種憨憨學渣和聰明學渣,而諸葛就是那種聰明點的學渣

憨憨學渣:抄作業不管三七二十一,拿著就抄,等老師檢查的時候,老師就會發現這叼毛玩意的作業怎么和班花的作業一樣,不用想了,在老師眼里,肯定是憨憨學渣抄別人的(淺拷貝)

聰明一點的學渣:抄作業要有竅門,不能讓老師發現,就做點手腳,答案是一樣的都是同一個對象,過程稍微改點,一種題的解法是有很多種方法的(深拷貝)

使用淺拷貝完成創建對象(實際開發肯定不要用)

  • 創建一個對象

    public class Sheep implements Cloneable {
    	private String name;
    	private int age;
    	private String color;
    	private String address = "蒙古羊";
    	public Sheep friend; //是對象, 克隆是會如何處理
    	public Sheep(String name, int age, String color) {
    		super();
    		this.name = name;
    		this.age = age;
    		this.color = color;
    	}
    	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;
    	}
    	public String getColor() {
    		return color;
    	}
    	public void setColor(String color) {
    		this.color = color;
    	}
    	@Override
    	public String toString() {
    		return "Sheep [name=" + name + ", age=" + age + ", color=" + color + ", address=" + address + "]";
    	}
    	//克隆該實例,使用默認的clone方法來完成
    	@Override
    	protected Object clone()  {
    		Sheep sheep = null;
    		try {
    			sheep = (Sheep)super.clone();
    		} catch (Exception e) {
    			System.out.println(e.getMessage());
    		}
    		return sheep;
    	}
    }


  • 測試淺拷貝

    public class Client {
    
    	public static void main(String[] args) {
    		System.out.println("原型模式完成對象的創建");
    		// TODO Auto-generated method stub
    		Sheep sheep = new Sheep("tom", 1, "白色");
    		
    		sheep.friend = new Sheep("jack", 2, "黑色");
    		// 更新一個屬性,發現復制克隆的對象屬性都變了
    		sheep.setAge(2);
    		
    		Sheep sheep2 = (Sheep)sheep.clone(); //克隆
    		Sheep sheep3 = (Sheep)sheep.clone(); //克隆
    		Sheep sheep4 = (Sheep)sheep.clone(); //克隆
    		Sheep sheep5 = (Sheep)sheep.clone(); //克隆
    		
    		System.out.println("sheep2 =" + sheep2 + "sheep2.friend=" + sheep2.friend.hashCode());
    		System.out.println("sheep3 =" + sheep3 + "sheep3.friend=" + sheep3.friend.hashCode());
    		System.out.println("sheep4 =" + sheep4 + "sheep4.friend=" + sheep4.friend.hashCode());
    		System.out.println("sheep5 =" + sheep5 + "sheep5.friend=" + sheep5.friend.hashCode());
    	}
    
    }


  • 輸出

    原型模式完成對象的創建
    sheep2 =Sheep [name=tom, age=2, color=白色, address=蒙古羊]sheep2.friend=312714112  
    sheep3 =Sheep [name=tom, age=2, color=白色, address=蒙古羊]sheep3.friend=312714112
    sheep4 =Sheep [name=tom, age=2, color=白色, address=蒙古羊]sheep4.friend=312714112
    sheep5 =Sheep [name=tom, age=2, color=白色, address=蒙古羊]sheep5.friend=312714112
    
    這種方式隨意一個對象更改屬性,其他克隆的對象的屬性都將改變


使用深拷貝完成創建對象

1、復制對象的所有基本數據類型的成員變量值

2、為所有引用數據類型的成員變量申請存儲空間,并復制每個引用數據類型成員變量所引用的對象,直到該對象可達的所有對象。也就是說,對象進行深拷貝要對整個對象進行拷貝

3、深拷貝實現方式

1:重寫clone方法來實現深拷貝

2:通過對象序列化實現深拷貝(推薦)

  • 創建一個對象

    public class DeepProtoType implements Serializable, Cloneable{
    	
    	/**  
    	 * @Fields serialVersionUID : TODO(描述)
    	 * @author wangmeng
    	 * @date 2021年5月13日 
    	 */ 
    	private static final long serialVersionUID = 1L;
    	
    	public String name; //String 屬性
    	
    	public DeepCloneableTarget deepCloneableTarget;// 引用類型
    	
    	public DeepProtoType() {
    		super();
    	}
    	//深拷貝 - 方式 1 使用clone 方法
    	@Override
    	protected Object clone() throws CloneNotSupportedException {
    		
    		Object deep = null;
    		//這里完成對基本數據類型(屬性)和String的克隆
    		deep = super.clone(); 
    		//對引用類型的屬性,進行單獨處理
    		DeepProtoType deepProtoType = (DeepProtoType)deep;
    		deepProtoType.deepCloneableTarget  = (DeepCloneableTarget)deepCloneableTarget.clone();
    		
    		// TODO Auto-generated method stub
    		return deepProtoType;
    	}
    	
    	//深拷貝 - 方式2 通過對象的序列化實現 (推薦)
    	
    	public Object deepClone() {
    		
    		//創建流對象
    		ByteArrayOutputStream bos = null;
    		ObjectOutputStream oos = null;
    		ByteArrayInputStream bis = null;
    		ObjectInputStream ois = null;
    		
    		try {
    			
    			//序列化
    			bos = new ByteArrayOutputStream();
    			oos = new ObjectOutputStream(bos);
    			oos.writeObject(this); //當前這個對象以對象流的方式輸出
    			
    			//反序列化
    			bis = new ByteArrayInputStream(bos.toByteArray());
    			ois = new ObjectInputStream(bis);
    			DeepProtoType copyObj = (DeepProtoType)ois.readObject();
    			
    			return copyObj;
    			
    		} catch (Exception e) {
    			// TODO: handle exception
    			e.printStackTrace();
    			return null;
    		} finally {
    			//關閉流
    			try {
    				bos.close();
    				oos.close();
    				bis.close();
    				ois.close();
    			} catch (Exception e2) {
    				// TODO: handle exception
    				System.out.println(e2.getMessage());
    			}
    		}
    		
    	}	
    }
    
    public class DeepCloneableTarget implements Serializable, Cloneable {
    	
    	/**
    	 * 
    	 */
    	private static final long serialVersionUID = 1L;
    
    	private String cloneName;
    
    	private String cloneClass;
    
    	//構造器
    	public DeepCloneableTarget(String cloneName, String cloneClass) {
    		this.cloneName = cloneName;
    		this.cloneClass = cloneClass;
    	}
    
    	//因為該類的屬性,都是String , 因此我們這里使用默認的clone完成即可
    	@Override
    	protected Object clone() throws CloneNotSupportedException {
    		return super.clone();
    	}
    }


  • 測試

    public class Client {
    
    	public static void main(String[] args) throws Exception {
    		
    		DeepProtoType p = new DeepProtoType();
    		p.name = "諸葛孔暗";
    		p.deepCloneableTarget = new DeepCloneableTarget("大牛", "小牛");
    		
    		//方式1 完成深拷貝
    		
    		DeepProtoType p2 = (DeepProtoType) p.clone();
    		p2.name="wangmeng";
    		System.out.println("p.name=" + p.name + "   p.deepCloneableTarget=" + p.deepCloneableTarget.hashCode());
    		System.out.println("p2.name=" + p2.name + "  p2.deepCloneableTarget=" + p2.deepCloneableTarget.hashCode());
    	
    		//方式2 完成深拷貝
    		DeepProtoType p3 = (DeepProtoType) p.deepClone();
    		p3.name="zhugekongan";
    		
    		System.out.println("p3.name=" + p3.name + "   p3.deepCloneableTarget=" + p3.deepCloneableTarget.hashCode());
    	
    	}
    }


  • 輸出:

    p.name=諸葛孔暗   p.deepCloneableTarget=705927765
    p2.name=wangmeng  p2.deepCloneableTarget=366712642
    p3.name=zhugekongan   p3.deepCloneableTarget=356573597
        
     從而達到我們的復制對象并改變對象屬性的需求


總結原型模式的注意事項和細節

  • 1、創建新的對象比較復雜時,可以利用原型模式簡化對象的創建過程,同時也能夠提高效率

  • 2、不用重新初始化對象,而是動態地獲得對象運行時的狀態3) 如果原始對象發生變化(增加或者減少屬性),其它克隆對象的也會發生相應的變化,無需修改代碼

  • 4、在實現深克隆的時候可能需要比較復雜的代碼

  • 5、缺點:需要為每一個類配備一個克隆方法,這對全新的類來說不是很難,但對已有的類進行改造時,需要修改其源代碼,違背了ocp原則,這點請同學們注意.

“Java原型設計模式是什么”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

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

AI

阜平县| 永泰县| 谷城县| 资阳市| 宿州市| 沂南县| 嘉荫县| 临猗县| 红原县| 六安市| 扶绥县| 虹口区| 衢州市| 清涧县| 齐齐哈尔市| 景泰县| 黄石市| 班玛县| 家居| 金门县| 西乡县| 星座| 鸡西市| 瑞昌市| 嘉祥县| 上杭县| 滨海县| 宁城县| 禄劝| 岚皋县| 吴川市| 资溪县| 历史| 佛山市| 五大连池市| 多伦县| 安岳县| 宝清县| 华坪县| 余江县| 灌阳县|