設(shè)計(jì)模式之原型模式

  • 注意!!!! 如果你是技術(shù)大牛、技術(shù)大咖,請(qǐng)略過這篇文章避免耽擱您的時(shí)間,這篇文章屬于入門級(jí)別。??

1、原型模式的概述:用原型實(shí)例對(duì)象指定創(chuàng)建對(duì)象種類,并且通過拷貝這些原型創(chuàng)建新的對(duì)象(根據(jù)原始對(duì)象,Copy一個(gè)對(duì)象---Copy:淺拷貝和深度拷貝)
2、原型模式的使用場(chǎng)景:

  • 當(dāng)我們編寫組件需要?jiǎng)?chuàng)建新的對(duì)象,但又不需要依賴初始化操作(就像swift中的UIView組件)不依賴于構(gòu)造器-->構(gòu)造方法
  • 初始化的過程需要消耗非常大的資源(數(shù)據(jù)資源:構(gòu)造方法需要很多數(shù)據(jù)參數(shù)、硬件資源...)
原型模式的一些角色:克隆接口或者說協(xié)議(protocoltype抽象,相當(dāng)于iOS中的NSCopying)、具體的實(shí)現(xiàn)類(concreteType)、客戶端(client),用一個(gè)簡(jiǎn)單的實(shí)例(淺拷貝)理解一下
//淺拷貝協(xié)議
protocol ShallowCopyProtocal {
    func clone() -> AnyObject?
}
//具體的實(shí)現(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!)
    }
}

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

//打印結(jié)果如下
原型對(duì)象:name = YSL sex= 男
克隆對(duì)象:name = Andy sex= man

  • 上面的實(shí)例拷貝的是值類型(直接拷貝數(shù)據(jù)),并不是引用類型,所以不會(huì)改變?cè)蛯?duì)象值
再來看一下原型設(shè)計(jì):數(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ù)組的淺拷貝測(cè)試
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("原型對(duì)象:name = \(student.name!) teachers = \(String(describing: student.teachers![0].name))")
        print("克隆對(duì)象:name = \(copyStudent.name!) teachers = \(String(describing: copyStudent.teachers![0].name))")
//輸出結(jié)果
原型對(duì)象:name = Mimi teachers = Optional("Lisa")
克隆對(duì)象:name = DaChanglian teachers = Optional("Lisa")

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

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

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

//深度拷貝的測(cè)試類 學(xué)生類
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)
    }
}

// ============ 深度拷貝測(cè)試===========
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("原型對(duì)象:name = \(student.name!) teachers = \(String(describing: student.teachers![0].name))")
        print("克隆對(duì)象:name = \(copyStudent.name!) teachers = \(String(describing: copyStudent.teachers![0].name))")

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

  • 深度拷貝是重新拷貝對(duì)象(在調(diào)用deepCopy()方法的時(shí)候重新創(chuàng)建了新的對(duì)象),引用對(duì)象的值改變,不影響原型對(duì)象
如果有不同的見解 --> 留言區(qū) ---> 請(qǐng)多多指教。?? ?? ??
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 原型模式 1.定義: 用原型實(shí)例指定創(chuàng)建對(duì)象的種類,并通過copy這些原型創(chuàng)建新的對(duì)象。 2.使用場(chǎng)景: 類初始化...
    TangBuzhi閱讀 287評(píng)論 0 0
  • 前言 在 Java 中,我們可以使用 new 關(guān)鍵字指定類名來生成類的實(shí)例。但是,有的時(shí)候,我們也會(huì)在不指定類名的...
    Kevin_ZGJ閱讀 343評(píng)論 0 0
  • 原型模式 有時(shí),我們需要原原本本地為對(duì)象創(chuàng)建一個(gè)副本。舉例來說,假設(shè)你想創(chuàng)建一個(gè)應(yīng)用來存儲(chǔ)、分享、編輯(比如,修改...
    英武閱讀 2,441評(píng)論 1 53
  • 激情初入句,感物復(fù)長(zhǎng)歌。 未得昔無奈,已成今若何。 并非心寂寞,總是意婆娑。 天下遍風(fēng)色,采來知幾多?
    雪窗_武立之閱讀 263評(píng)論 2 3
  • 韶光悠悠,比落花有聲,比流水無情,任誰都擋不住它匆忙的腳步,似乎只一夢(mèng)醒來,眼前已不是昨日的景色。“未覺池塘春草夢(mèng)...
    與敏同樂閱讀 337評(píng)論 0 0