多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國(guó)內(nèi)最全I(xiàn)T社區(qū)平臺(tái) 聯(lián)系我們 | 收藏本站
阿里云優(yōu)惠2
您當(dāng)前位置:首頁(yè) > php開(kāi)源 > 綜合技術(shù) > Android開(kāi)發(fā)中無(wú)處不在的設(shè)計(jì)模式――原型模式

Android開(kāi)發(fā)中無(wú)處不在的設(shè)計(jì)模式――原型模式

來(lái)源:程序員人生   發(fā)布時(shí)間:2016-03-22 08:58:12 閱讀次數(shù):2722次

不知不覺(jué)這個(gè)系列已寫(xiě)了3篇了,其實(shí)很早之前就想寫(xiě)設(shè)計(jì)模式了,只不過(guò)怕自己誤人子弟沒(méi)有提筆去寫(xiě)。后來(lái)在實(shí)際開(kāi)發(fā)中,發(fā)現(xiàn)設(shè)計(jì)模式可讓1個(gè)開(kāi)發(fā)人員融會(huì)貫通所學(xué)的知識(shí),為了進(jìn)1步鞏固自己,就寫(xiě)下了這1些列文章。前面介紹了3個(gè)模式。

  • Android開(kāi)發(fā)中無(wú)處不在的設(shè)計(jì)模式――單例模式
  • Android開(kāi)發(fā)中無(wú)處不在的設(shè)計(jì)模式――Builder模式
  • Android開(kāi)發(fā)中無(wú)處不在的設(shè)計(jì)模式――視察者模式

本篇文章介紹的模式其實(shí)很簡(jiǎn)單,即原型模式,依照慣例,先看定義。

用原型實(shí)例指定創(chuàng)建對(duì)象的種類,并通過(guò)拷貝這些原型創(chuàng)建新的對(duì)象。

這是甚么鬼哦,本寶寶看不懂!沒(méi)必要過(guò)度在乎這些定義,自己心里明白就ok了。沒(méi)代碼你說(shuō)個(gè)jb。

首先我們定義1個(gè)Person類

public class Person{ private String name; private int age; private double height; private double weight; public Person(){ } 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 double getHeight() { return height; } public void setHeight(double height) { this.height = height; } public double getWeight() { return weight; } public void setWeight(double weight) { this.weight = weight; } @Override public String toString() { return "Person{" + "name=" + name + + ", age=" + age + ", height=" + height + ", weight=" + weight + }; } }

要實(shí)現(xiàn)原型模式,只需要依照下面的幾個(gè)步驟去實(shí)現(xiàn)便可。

  • 實(shí)現(xiàn)Cloneable接口
public class Person implements Cloneable{ }
  • 重寫(xiě)Object的clone方法
@Override public Object clone(){ return null; }
  • 實(shí)現(xiàn)clone方法中的拷貝邏輯
@Override public Object clone(){ Person person=null; try { person=(Person)super.clone(); person.name=this.name; person.weight=this.weight; person.height=this.height; person.age=this.age; } catch (CloneNotSupportedException e) { e.printStackTrace(); } return person; }

測(cè)試1下

public class Main { public static void main(String [] args){ Person p=new Person(); p.setAge(18); p.setName("張3"); p.setHeight(178); p.setWeight(65); System.out.println(p); Person p1= (Person) p.clone(); System.out.println(p1); p1.setName("李4"); System.out.println(p); System.out.println(p1); } }

輸出結(jié)果以下

Person{name=’張3’, age=18, height=178.0, weight=65.0}
Person{name=’張3’, age=18, height=178.0, weight=65.0}
Person{name=’張3’, age=18, height=178.0, weight=65.0}
Person{name=’李4’, age=18, height=178.0, weight=65.0}

試想1下,兩個(gè)不同的人,除姓名不1樣,其他3個(gè)屬性都1樣,用原型模式進(jìn)行拷貝就會(huì)顯得異常簡(jiǎn)單,這也是原型模式的利用場(chǎng)景之1。

1個(gè)對(duì)象需要提供給其他對(duì)象訪問(wèn),而且各個(gè)調(diào)用者可能都需要修改其值時(shí),可以斟酌使用原型模式拷貝多個(gè)對(duì)象供調(diào)用者使用,即保護(hù)性拷貝。

但是假定Person類里還有1個(gè)屬性叫興趣愛(ài)好,是1個(gè)List集合,就像這模樣

private ArrayListhobbies=new ArrayList(); public ArrayListgetHobbies() { return hobbies; } public void setHobbies(ArrayListhobbies) { this.hobbies = hobbies; }

在進(jìn)行拷貝的時(shí)候要格外注意,如果你直接按之前的代碼那樣拷貝

@Override public Object clone(){ Person person=null; try { person=(Person)super.clone(); person.name=this.name; person.weight=this.weight; person.height=this.height; person.age=this.age; person.hobbies=this.hobbies; } catch (CloneNotSupportedException e) { e.printStackTrace(); } return person; }

會(huì)帶來(lái)1個(gè)問(wèn)題

使用測(cè)試代碼進(jìn)行測(cè)試

public class Main { public static void main(String [] args){ Person p=new Person(); p.setAge(18); p.setName("張3"); p.setHeight(178); p.setWeight(65); ArrayListhobbies=new ArrayList(); hobbies.add("籃球"); hobbies.add("編程"); hobbies.add("長(zhǎng)跑"); p.setHobbies(hobbies); System.out.println(p); Person p1= (Person) p.clone(); System.out.println(p1); p1.setName("李4"); p1.getHobbies().add("游泳"); System.out.println(p); System.out.println(p1); } }

我們拷貝了1個(gè)對(duì)象,并添加了1個(gè)興趣愛(ài)好進(jìn)去,看下打印結(jié)果

Person{name=’張3’, age=18, height=178.0, weight=65.0, hobbies=[籃球, 編程, 長(zhǎng)跑]}
Person{name=’張3’, age=18, height=178.0, weight=65.0, hobbies=[籃球, 編程, 長(zhǎng)跑]}
Person{name=’張3’, age=18, height=178.0, weight=65.0, hobbies=[籃球, 編程, 長(zhǎng)跑, 游泳]}
Person{name=’李4’, age=18, height=178.0, weight=65.0, hobbies=[籃球, 編程, 長(zhǎng)跑, 游泳]}

你會(huì)發(fā)現(xiàn)原來(lái)的對(duì)象的hobby也產(chǎn)生了變換。

其實(shí)致使這個(gè)問(wèn)題的本質(zhì)緣由是我們只進(jìn)行了淺拷貝,也就是只拷貝了援用,終究?jī)蓚€(gè)對(duì)象指向的援用是同1個(gè),1個(gè)產(chǎn)生變化另外一個(gè)也會(huì)產(chǎn)生變換,明顯解決方法就是使用深拷貝。

@Override public Object clone(){ Person person=null; try { person=(Person)super.clone(); person.name=this.name; person.weight=this.weight; person.height=this.height; person.age=this.age; person.hobbies=(ArrayList)this.hobbies.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return person; }

注意person.hobbies=(ArrayList)this.hobbies.clone();,不再是直接援用而是進(jìn)行了1份拷貝。再運(yùn)行1下,就會(huì)發(fā)現(xiàn)原來(lái)的對(duì)象不會(huì)再產(chǎn)生變化了。

Person{name=’張3’, age=18, height=178.0, weight=65.0, hobbies=[籃球, 編程, 長(zhǎng)跑]}
Person{name=’張3’, age=18, height=178.0, weight=65.0, hobbies=[籃球, 編程, 長(zhǎng)跑]}
Person{name=’張3’, age=18, height=178.0, weight=65.0, hobbies=[籃球, 編程, 長(zhǎng)跑]}
Person{name=’李4’, age=18, height=178.0, weight=65.0, hobbies=[籃球, 編程, 長(zhǎng)跑, 游泳]}

其實(shí)有時(shí)候我們會(huì)更多的看到原型模式的另外一種寫(xiě)法。

  • 在clone函數(shù)里調(diào)用構(gòu)造函數(shù),構(gòu)造函數(shù)的入?yún)⑹窃擃悓?duì)象。
@Override public Object clone(){ return new Person(this); }
  • 在構(gòu)造函數(shù)中完成拷貝邏輯
public Person(Person person){ this.name=person.name; this.weight=person.weight; this.height=person.height; this.age=person.age; this.hobbies= new ArrayList(hobbies); }

其實(shí)都差不多,只是寫(xiě)法不1樣。

現(xiàn)在來(lái)挖挖android中的原型模式。

先看Bundle類,該類實(shí)現(xiàn)了Cloneable接口

public Object clone() { return new Bundle(this); } public Bundle(Bundle b) { super(b); mHasFds = b.mHasFds; mFdsKnown = b.mFdsKnown; }

然后是Intent類,該類也實(shí)現(xiàn)了Cloneable接口

@Override public Object clone() { return new Intent(this); } public Intent(Intent o) { this.mAction = o.mAction; this.mData = o.mData; this.mType = o.mType; this.mPackage = o.mPackage; this.mComponent = o.mComponent; this.mFlags = o.mFlags; this.mContentUserHint = o.mContentUserHint; if (o.mCategories != null) { this.mCategories = new ArraySet(o.mCategories); } if (o.mExtras != null) { this.mExtras = new Bundle(o.mExtras); } if (o.mSourceBounds != null) { this.mSourceBounds = new Rect(o.mSourceBounds); } if (o.mSelector != null) { this.mSelector = new Intent(o.mSelector); } if (o.mClipData != null) { this.mClipData = new ClipData(o.mClipData); } }

用法也顯得10分簡(jiǎn)單,1旦我們要用的Intent與現(xiàn)有的1個(gè)Intent很多東西都是1樣的,那我們就能夠直接拷貝現(xiàn)有的Intent,再修改不同的地方,即可以直接使用。

Uri uri = Uri.parse("smsto:10086"); Intent shareIntent = new Intent(Intent.ACTION_SENDTO, uri); shareIntent.putExtra("sms_body", "hello"); Intent intent = (Intent)shareIntent.clone() ; startActivity(intent);

網(wǎng)絡(luò)要求中1個(gè)最多見(jiàn)的開(kāi)源庫(kù)OkHttp中,也利用了原型模式。它就在OkHttpClient這個(gè)類中,它實(shí)現(xiàn)了Cloneable接口

/** Returns a shallow copy of this OkHttpClient. */ @Override public OkHttpClient clone() { return new OkHttpClient(this); } private OkHttpClient(OkHttpClient okHttpClient) { this.routeDatabase = okHttpClient.routeDatabase; this.dispatcher = okHttpClient.dispatcher; this.proxy = okHttpClient.proxy; this.protocols = okHttpClient.protocols; this.connectionSpecs = okHttpClient.connectionSpecs; this.interceptors.addAll(okHttpClient.interceptors); this.networkInterceptors.addAll(okHttpClient.networkInterceptors); this.proxySelector = okHttpClient.proxySelector; this.cookieHandler = okHttpClient.cookieHandler; this.cache = okHttpClient.cache; this.internalCache = cache != null ? cache.internalCache : okHttpClient.internalCache; this.socketFactory = okHttpClient.socketFactory; this.sslSocketFactory = okHttpClient.sslSocketFactory; this.hostnameVerifier = okHttpClient.hostnameVerifier; this.certificatePinner = okHttpClient.certificatePinner; this.authenticator = okHttpClient.authenticator; this.connectionPool = okHttpClient.connectionPool; this.network = okHttpClient.network; this.followSslRedirects = okHttpClient.followSslRedirects; this.followRedirects = okHttpClient.followRedirects; this.retryOnConnectionFailure = okHttpClient.retryOnConnectionFailure; this.connectTimeout = okHttpClient.connectTimeout; this.readTimeout = okHttpClient.readTimeout; this.writeTimeout = okHttpClient.writeTimeout; }

正如開(kāi)頭的注釋Returns a shallow copy of this OkHttpClient,該clone方法返回了1個(gè)當(dāng)前對(duì)象的深拷貝對(duì)象。



生活不易,碼農(nóng)辛苦
如果您覺(jué)得本網(wǎng)站對(duì)您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈(zèng)
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關(guān)閉
程序員人生
主站蜘蛛池模板: 亚洲国产成a人v在线观看 | 欧美vido| 国产欧美精品国产国产专区 | 亚洲伊人成综合网 | 曰本在线网 | 另类小说图片 | 亚洲精品一区二 | 夜夜嗨影院 | 福利片午夜 | 欧美一级毛片欧美一级无片 | 日本三区视频 | 一区一区三区产品乱码 | 欧美成人性色xxxx视频 | 免费永久国产在线视频 | 国产精品成人扳一级aa毛片 | 国产高清在线播放免费观看 | 欧美日韩亚洲精品一区 | 国产成人久久精品麻豆二区 | 欧美孕妇乱大交xxxx | 2019在线亚洲成年视频网站 | 国产成人精品一区二区三区 | 欧美13一18成年性 | 中文字幕中文字幕在线 | 欧美一级毛片免费大片 | 国产亚洲精品久久精品6 | 亚洲高清中文字幕一区二区三区 | 日韩理论在线播放 | 免费 欧美 自拍 在线观看 | 亚洲理论a中文字幕在线 | 爱爱毛片| 一二三四免费手机在线观看视频 | 精品国产一区二区三区久 | 最近免费字幕中文大全在线观看 | 欧美性受xxxx | 国产免费不卡v片在线观看 国产免费叼嘿视频 | a天堂视频| 亚洲欧美视频在线播放 | 最近中文国语字幕 | 人人澡人人爱 | 九色自拍| 4虎1515hh永久免费 |