設計模式之原型模式

  • 注意L缚觥I酌馈!碑韵! 如果你是技術大牛赡茸、技術大咖,請略過這篇文章避免耽擱您的時間祝闻,這篇文章屬于入門級別占卧。??

1、原型模式的概述:用原型實例對象指定創(chuàng)建對象種類联喘,并且通過拷貝這些原型創(chuàng)建新的對象(根據原始對象华蜒,Copy一個對象---Copy:淺拷貝和深度拷貝)
2、原型模式的使用場景:

  • 當我們編寫組件需要創(chuàng)建新的對象豁遭,但又不需要依賴初始化操作(就像swift中的UIView組件)不依賴于構造器-->構造方法
  • 初始化的過程需要消耗非常大的資源(數(shù)據資源:構造方法需要很多數(shù)據參數(shù)叭喜、硬件資源...)
原型模式的一些角色:克隆接口或者說協(xié)議(protocoltype抽象,相當于iOS中的NSCopying)蓖谢、具體的實現(xiàn)類(concreteType)捂蕴、客戶端(client),用一個簡單的實例(淺拷貝)理解一下
//淺拷貝協(xié)議
protocol ShallowCopyProtocal {
    func clone() -> AnyObject?
}
//具體的實現(xiàn)類
class UserCopyModel: ShallowCopyProtocal {
    var name:String?
    var sex:String?
    init(name:String,sex:String) {
        self.name = name
        self.sex = sex
    }
    func clone() -> AnyObject? {
        return UserCopyModel(name:self.name!, sex:self.sex!)
    }
}

 //===========淺度拷貝測試===========
        //原型對象
        let user = UserCopyModel(name: "YSL", sex: "男")
        //克隆對象
        let copyUser:UserCopyModel = user.clone() as! UserCopyModel
        //修改克隆對象的值,看看原型對象會不會改變
        copyUser.name = "Andy"
        copyUser.sex = "man"
        print("原型對象:name = \(user.name!) sex= \(user.sex!)")
        print("克隆對象:name = \(copyUser.name!) sex= \(copyUser.sex!)")

//打印結果如下
原型對象:name = YSL sex= 男
克隆對象:name = Andy sex= man

  • 上面的實例拷貝的是值類型(直接拷貝數(shù)據)蜈抓,并不是引用類型启绰,所以不會改變原型對象值
再來看一下原型設計:數(shù)組的淺拷貝
protocol ShallowCopyProtocal {
    func clone() -> AnyObject?
}
class TeacherModel {
    var name:String?
    init(name:String) {
        self.name = name
    }
}
class StudentCopyModel: ShallowCopyProtocal {
    var name:String?
    var teachers:Array<TeacherModel>?
    init(name:String, teachers:Array<TeacherModel>) {
        self.name = name
        self.teachers = teachers
    }
    func clone() -> AnyObject? {
        return StudentCopyModel(name: self.name!, teachers: self.teachers!)
    }
}

//數(shù)組的淺拷貝測試
let array = [TeacherModel(name:"Jack"),TeacherModel(name:"Rose")]
        let student = StudentCopyModel(name: "Mimi", teachers: array)
        let copyStudent: StudentCopyModel = student.clone() as! StudentCopyModel
        copyStudent.name = "DaChanglian"
        copyStudent.teachers?[0].name = "Lisa"
        print("原型對象:name = \(student.name!) teachers = \(String(describing: student.teachers![0].name))")
        print("克隆對象:name = \(copyStudent.name!) teachers = \(String(describing: copyStudent.teachers![0].name))")
//輸出結果
原型對象:name = Mimi teachers = Optional("Lisa")
克隆對象:name = DaChanglian teachers = Optional("Lisa")

  • 看到以上結果,應該明白沟使,數(shù)組是重新創(chuàng)建了委可,但是數(shù)組中保存的對象沒有重新創(chuàng)建(也就是說數(shù)組保存的是對象的引用類型,那么拷貝的時候拷貝的是數(shù)組的值,數(shù)組的值就是TeacherModel對象的引用)着倾。
  • 這樣對數(shù)組中的對象重新賦值拾酝,其實是改變了對象的值。如何證明數(shù)組保存的是對象的引用卡者,直接打印數(shù)組就可以證明了蒿囤。打印結果如下:
print("原型對象:teachers = \(student.teachers!)\n克隆對象:teachers = \(copyStudent.teachers!)")
原型對象:teachers = [ArchitectGenerics.TeacherModel, ArchitectGenerics.TeacherModel]
克隆對象:teachers = [ArchitectGenerics.TeacherModel, ArchitectGenerics.TeacherModel]

如果遇到以上的問題,我們如何解決這樣的問題呢崇决?答案就是原型模式-->深度拷貝材诽。再看一個例子,解決一下這個問題??
//深度拷貝協(xié)議接口
protocol DeepCopyProtocal {
    func deepClone() -> AnyObject?
}

//深度拷貝測試的具體類 老師類
class TeacherModel2: DeepCopyProtocal {
   var name:String?
    init(name:String) {
        self.name = name
    }
    func deepClone() -> AnyObject? {
        return TeacherModel2(name: self.name!)
    }
}

//深度拷貝的測試類 學生類
class DeepCopyStudentModel: DeepCopyProtocal {
    var name:String?
    var teachers:Array<TeacherModel2>?
    init(name:String, teachers:Array<TeacherModel2>) {
        self.name = name
        self.teachers = teachers
    }

    func deepClone() -> AnyObject? {
        var newArray = Array<TeacherModel2>()
        for teacher in self.teachers! {
            newArray.append(teacher.deepClone() as! TeacherModel2)
        }
        return DeepCopyStudentModel(name: self.name!, teachers: newArray)
    }
}

// ============ 深度拷貝測試===========
let array = [TeacherModel2(name:"Jack"),TeacherModel2(name:"Rose")]
        let student = DeepCopyStudentModel(name: "Mimi", teachers: array)
        let copyStudent: DeepCopyStudentModel = student.deepClone() as! DeepCopyStudentModel
        copyStudent.name = "DaChangLian"
        copyStudent.teachers?[0].name = "Lisa"
        print("原型對象:name = \(student.name!) teachers = \(String(describing: student.teachers![0].name))")
        print("克隆對象:name = \(copyStudent.name!) teachers = \(String(describing: copyStudent.teachers![0].name))")

//=========打印結果================
原型對象:name = Mimi teachers = Optional("Jack")
克隆對象:name = DaChangLian teachers = Optional("Lisa")

  • 深度拷貝是重新拷貝對象(在調用deepCopy()方法的時候重新創(chuàng)建了新的對象),引用對象的值改變恒傻,不影響原型對象
如果有不同的見解 --> 留言區(qū) ---> 請多多指教脸侥。?? ?? ??
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市盈厘,隨后出現(xiàn)的幾起案子睁枕,更是在濱河造成了極大的恐慌,老刑警劉巖沸手,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件外遇,死亡現(xiàn)場離奇詭異,居然都是意外死亡契吉,警方通過查閱死者的電腦和手機跳仿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來捐晶,“玉大人塔嬉,你說我怎么就攤上這事∽馇模” “怎么了?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵恩袱,是天一觀的道長泣棋。 經常有香客問我,道長畔塔,這世上最難降的妖魔是什么潭辈? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮澈吨,結果婚禮上把敢,老公的妹妹穿的比我還像新娘。我一直安慰自己谅辣,他們只是感情好修赞,可當我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般柏副。 火紅的嫁衣襯著肌膚如雪勾邦。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天割择,我揣著相機與錄音眷篇,去河邊找鬼。 笑死荔泳,一個胖子當著我的面吹牛蕉饼,可吹牛的內容都是我干的。 我是一名探鬼主播玛歌,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼昧港,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了沾鳄?” 一聲冷哼從身側響起慨飘,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎译荞,沒想到半個月后瓤的,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡吞歼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年圈膏,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片篙骡。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡稽坤,死狀恐怖,靈堂內的尸體忽然破棺而出糯俗,到底是詐尸還是另有隱情尿褪,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布得湘,位于F島的核電站杖玲,受9級特大地震影響,放射性物質發(fā)生泄漏淘正。R本人自食惡果不足惜摆马,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望鸿吆。 院中可真熱鬧囤采,春花似錦、人聲如沸惩淳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至恕刘,卻和暖如春缤谎,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背褐着。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工坷澡, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人含蓉。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓频敛,卻偏偏與公主長得像,于是被迫代替她去往敵國和親馅扣。 傳聞我的和親對象是個殘疾皇子斟赚,可洞房花燭夜當晚...
    茶點故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內容

  • 原型模式 1.定義: 用原型實例指定創(chuàng)建對象的種類,并通過copy這些原型創(chuàng)建新的對象差油。 2.使用場景: 類初始化...
    TangBuzhi閱讀 260評論 0 0
  • 前言 在 Java 中拗军,我們可以使用 new 關鍵字指定類名來生成類的實例。但是蓄喇,有的時候发侵,我們也會在不指定類名的...
    Kevin_ZGJ閱讀 329評論 0 0
  • 原型模式 有時,我們需要原原本本地為對象創(chuàng)建一個副本妆偏。舉例來說刃鳄,假設你想創(chuàng)建一個應用來存儲、分享钱骂、編輯(比如叔锐,修改...
    英武閱讀 2,400評論 1 53
  • 激情初入句,感物復長歌见秽。 未得昔無奈愉烙,已成今若何。 并非心寂寞解取,總是意婆娑齿梁。 天下遍風色,采來知幾多肮蛹?
    雪窗_武立之閱讀 237評論 2 3
  • 韶光悠悠,比落花有聲创南,比流水無情伦忠,任誰都擋不住它匆忙的腳步,似乎只一夢醒來稿辙,眼前已不是昨日的景色昆码。“未覺池塘春草夢...
    與敏同樂閱讀 312評論 0 0