真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Java原型設(shè)計(jì)模式是什么

本篇內(nèi)容介紹了“Java原型設(shè)計(jì)模式是什么”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

成都創(chuàng)新互聯(lián)公司-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價(jià)比文登網(wǎng)站開(kāi)發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫(kù),直接使用。一站式文登網(wǎng)站制作公司更省心,省錢(qián),快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋文登地區(qū)。費(fèi)用合理售后完善,十多年實(shí)體公司更值得信賴。

原型模式

原型模式

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

2、原型模式是一種創(chuàng)建型設(shè)計(jì)模式,允許一個(gè)對(duì)象再創(chuàng)建另外一個(gè)可定制的對(duì)象,無(wú)需知道如何創(chuàng)建的細(xì)節(jié)

3、工作原理是:通過(guò)將一個(gè)原型對(duì)象傳給那個(gè)要發(fā)動(dòng)創(chuàng)建的對(duì)象,這個(gè)要發(fā)動(dòng)創(chuàng)建的對(duì)象通過(guò)請(qǐng)求原型對(duì)象拷貝它們自己來(lái)實(shí)施創(chuàng)建,即 對(duì)象.clone()

這個(gè)原型模式我是想了一天,都沒(méi)有想到實(shí)際開(kāi)發(fā)怎么能用到它,看了很多博客說(shuō)是Spring創(chuàng)建bean的時(shí)候能用到它,在看源碼的時(shí)候,好多注解式框架就可以看到

 

怎么實(shí)現(xiàn)原型模式呢?

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

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

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

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

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

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

舉個(gè)例子

諸葛上學(xué)的時(shí)候絕對(duì)是個(gè)學(xué)渣:每天都不寫(xiě)作業(yè),每天早讀下來(lái)老師都要檢查作業(yè),所以諸葛從來(lái)早讀不讀書(shū),和班花班長(zhǎng)學(xué)習(xí)委員關(guān)系搞好,每天都來(lái)抄他們的作業(yè),完成一個(gè)復(fù)制的過(guò)程,那么問(wèn)題來(lái)了,每個(gè)班不止有一個(gè)學(xué)渣,學(xué)渣有那種憨憨學(xué)渣和聰明學(xué)渣,而諸葛就是那種聰明點(diǎn)的學(xué)渣

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

聰明一點(diǎn)的學(xué)渣:抄作業(yè)要有竅門(mén),不能讓老師發(fā)現(xiàn),就做點(diǎn)手腳,答案是一樣的都是同一個(gè)對(duì)象,過(guò)程稍微改點(diǎn),一種題的解法是有很多種方法的(深拷貝)

使用淺拷貝完成創(chuàng)建對(duì)象(實(shí)際開(kāi)發(fā)肯定不要用)

  • 創(chuàng)建一個(gè)對(duì)象

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

  • 測(cè)試淺拷貝

    public class Client {
    
    	public static void main(String[] args) {
    		System.out.println("原型模式完成對(duì)象的創(chuàng)建");
    		// TODO Auto-generated method stub
    		Sheep sheep = new Sheep("tom", 1, "白色");
    		
    		sheep.friend = new Sheep("jack", 2, "黑色");
    		// 更新一個(gè)屬性,發(fā)現(xiàn)復(fù)制克隆的對(duì)象屬性都變了
    		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());
    	}
    
    }

  • 輸出

    原型模式完成對(duì)象的創(chuàng)建
    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
    
    這種方式隨意一個(gè)對(duì)象更改屬性,其他克隆的對(duì)象的屬性都將改變

使用深拷貝完成創(chuàng)建對(duì)象

1、復(fù)制對(duì)象的所有基本數(shù)據(jù)類型的成員變量值

2、為所有引用數(shù)據(jù)類型的成員變量申請(qǐng)存儲(chǔ)空間,并復(fù)制每個(gè)引用數(shù)據(jù)類型成員變量所引用的對(duì)象,直到該對(duì)象可達(dá)的所有對(duì)象。也就是說(shuō),對(duì)象進(jìn)行深拷貝要對(duì)整個(gè)對(duì)象進(jìn)行拷貝

3、深拷貝實(shí)現(xiàn)方式

1:重寫(xiě)clone方法來(lái)實(shí)現(xiàn)深拷貝

2:通過(guò)對(duì)象序列化實(shí)現(xiàn)深拷貝(推薦)

  • 創(chuàng)建一個(gè)對(duì)象

    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;
    		//這里完成對(duì)基本數(shù)據(jù)類型(屬性)和String的克隆
    		deep = super.clone(); 
    		//對(duì)引用類型的屬性,進(jìn)行單獨(dú)處理
    		DeepProtoType deepProtoType = (DeepProtoType)deep;
    		deepProtoType.deepCloneableTarget  = (DeepCloneableTarget)deepCloneableTarget.clone();
    		
    		// TODO Auto-generated method stub
    		return deepProtoType;
    	}
    	
    	//深拷貝 - 方式2 通過(guò)對(duì)象的序列化實(shí)現(xiàn) (推薦)
    	
    	public Object deepClone() {
    		
    		//創(chuàng)建流對(duì)象
    		ByteArrayOutputStream bos = null;
    		ObjectOutputStream oos = null;
    		ByteArrayInputStream bis = null;
    		ObjectInputStream ois = null;
    		
    		try {
    			
    			//序列化
    			bos = new ByteArrayOutputStream();
    			oos = new ObjectOutputStream(bos);
    			oos.writeObject(this); //當(dāng)前這個(gè)對(duì)象以對(duì)象流的方式輸出
    			
    			//反序列化
    			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 {
    			//關(guān)閉流
    			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;
    
    	//構(gòu)造器
    	public DeepCloneableTarget(String cloneName, String cloneClass) {
    		this.cloneName = cloneName;
    		this.cloneClass = cloneClass;
    	}
    
    	//因?yàn)樵擃惖膶傩?,都是String , 因此我們這里使用默認(rèn)的clone完成即可
    	@Override
    	protected Object clone() throws CloneNotSupportedException {
    		return super.clone();
    	}
    }

  • 測(cè)試

    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
        
     從而達(dá)到我們的復(fù)制對(duì)象并改變對(duì)象屬性的需求

總結(jié)原型模式的注意事項(xiàng)和細(xì)節(jié)

  • 1、創(chuàng)建新的對(duì)象比較復(fù)雜時(shí),可以利用原型模式簡(jiǎn)化對(duì)象的創(chuàng)建過(guò)程,同時(shí)也能夠提高效率

  • 2、不用重新初始化對(duì)象,而是動(dòng)態(tài)地獲得對(duì)象運(yùn)行時(shí)的狀態(tài)3) 如果原始對(duì)象發(fā)生變化(增加或者減少屬性),其它克隆對(duì)象的也會(huì)發(fā)生相應(yīng)的變化,無(wú)需修改代碼

  • 4、在實(shí)現(xiàn)深克隆的時(shí)候可能需要比較復(fù)雜的代碼

  • 5、缺點(diǎn):需要為每一個(gè)類配備一個(gè)克隆方法,這對(duì)全新的類來(lái)說(shuō)不是很難,但對(duì)已有的類進(jìn)行改造時(shí),需要修改其源代碼,違背了ocp原則,這點(diǎn)請(qǐng)同學(xué)們注意.

“Java原型設(shè)計(jì)模式是什么”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!


分享標(biāo)題:Java原型設(shè)計(jì)模式是什么
標(biāo)題路徑:http://weahome.cn/article/pdeddh.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部