2016-08-04 77 views
1

有人可以幫我理解這個Swift代碼嗎?此代碼是根據預定我最近在讀的原型設計模式的實現:Swift原型設計模式

class AbstractCard { 
    var name: String? 
    var mana: Int? 
    var attack: Int? 
    var defense: Int? 
    init(name:String?, mana:Int?, attack:Int?, defense:Int?) { 
     self.name = name 
     self.attack = attack 
     self.defense = defense 
     self.mana = mana 
    } 
    func clone() -> AbstractCard { 
     return AbstractCard(name: self.name, mana: self.mana, attack: 
      self.attack, defense: self.defense) 
    } 
} 
class Card: AbstractCard { 
    var someNumber: Int 
    override init(name:String?, mana:Int?, attack:Int?, defense:Int?){ 
     someNumber = 2 
     super.init(name: name,mana: mana,attack: attack,defense: 
      defense) 
    } 
} 
// Simulate our client 
// This is the card that we will copy 
let raidLeader = Card(name: "Raid Leader", mana: 3, attack: 2, defense: 2) 
// Now we use our faceless Manipulator card to clone the 

let facelessManipulator = raidLeader.clone() 
print("\(facelessManipulator.name, facelessManipulator.mana, facelessManipulator.attack, facelessManipulator.defense)") 
print(facelessManipulator.dynamicType) // prints "AbstractCard" 

這是什麼模式的點,如果克隆的對象的dynamicType仍然AbstractCard,而不是卡。你甚至不能訪問特定於卡的變量。我試圖施放此對象卡,但我得到的錯誤"Execution was interrupted reason: signal SIGABRT"

+1

我想你需要重寫'卡'中的克隆。 – tktsubota

+0

'AbstractCard'中'clone'的實現有點毫無意義,那不是嗎?因爲這只是一個抽象類。 – ttrs

回答

2

讓我們明確了原型模式第一:

原型模式通過複製現有的對象,被稱爲原型創建新的對象。

首先有很多方法來實現Prototype模式,我認爲本書的作者試圖以最合適的方式解釋你模式的用戶案例。

因此,作爲擺在評論別人的clone方法應該是覆蓋在子類,允許對象的克隆正確,如以下方式:

class Card: AbstractCard { 

    var someNumber: Int 

    override init(name:String?, mana:Int?, attack:Int?, defense:Int?){ 
     someNumber = 2 
     super.init(name: name,mana: mana,attack: attack,defense: 
     defense) 
    } 

    override func clone() -> AbstractCard { 
     return Card(name: self.name, mana: self.mana, attack: 
     self.attack, defense: self.defense) 
    } 
} 

我必須說,我曾作爲本書的技術評論員,我認爲作者用更好的方式表達了他可以使用這種模式。

如果您認真思考,每次在Swift(Arrays,Int,Bool等)中使用值類型時都會應用此模式,因爲每次將實例的值分配給另一個實例時,都會創建一個新副本相同的值。問題在於引用值(類),每次將實例分配給新實例時,它們都會共享其值和修改。

實施該模式的另一種方式是使用協議,該協議聲明瞭提供對象的功能副本的方法,並且在我看來是最常用的方法。

例如:

class Card: NSObject, NSCopying { 

    var name: String? 
    var mana: Int? 
    var attack: Int? 
    var defense: Int? 

    init(name:String?, mana:Int?, attack:Int?, defense:Int?) { 
     self.name = name 
     self.attack = attack 
     self.defense = defense 
     self.mana = mana 
    } 

    func copyWithZone(zone: NSZone) -> AnyObject { 
     return Card(name: self.name, mana: self.mana, attack: self.attack, defense: self.defense) 
    } 
} 

// Simulate our client 
// This is the card that we will copy 
let raidLeader = Card(name: "Raid Leader", mana: 3, attack: 2, defense: 2) 
// Now we use our faceless Manipulator card to clone the 

let facelessManipulator = raidLeader.copy() as Card 
raidLeader.attack = 5 

print("\(facelessManipulator.name, facelessManipulator.mana, facelessManipulator.attack, facelessManipulator.defense)") 
print("\(raidLeader.name, raidLeader.mana, raidLeader.attack, raidLeader.defense)") 

您可以瞭解這個問題,更多是這樣的:

我希望這可以幫助您。

+0

謝謝你的回答。爲什麼作者沒有在書中重寫'clone'?是因爲'AbstractCard'和'Card'幾乎是一回事嗎? – ttrs

+0

是的,我認爲作者的主要目標是隱藏在我看來使用它們的組件創建對象的代碼。 –