Swift原型设计模式

时间:2016-08-04 15:06:58

标签: swift design-patterns

有人可以帮我理解这个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而不是Card,那么此模式的重点是什么。您甚至无法访问特定于Card的变量。我试图将此对象转换为Card但我收到错误"Execution was interrupted reason: signal SIGABRT"

1 个答案:

答案 0 :(得分:2)

首先让我们清楚一下Prototype模式:

  

原型模式通过复制现有对象(称为原型)来创建新对象。

首先,有很多方法可以实现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等)中使用值类型时都应用此模式,因为每次将实例的值分配给另一个实例时,都会使用相同的方法创建一个新副本值。问题在于参考值(类),每次将实例分配给新实例时,它们都会共享其值和修改它们。

实现模式的另一种方法是使用NSCopying协议声明一种方法来提供对象的功能副本,在我看来是最常用的。

例如:

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)")

您可以在此问题中了解有关此方式的更多信息:

我希望这对你有所帮助。