最近我遇到了面向协议的编程(WWDC 2015),它确实很吸引人,但它却是一个非常难以驯服并将其付诸实践的概念。所以我在互联网上做了一些研究,并发现了这个代码。它的模型玩家和敌人在一个典型的游戏场景,玩家可以装备的武器和射击的敌人,那么敌人随后受到伤害:面向协议编程与面向对象编程的区别与范例
protocol Targetable {
var life: Int { get set }
func takeDamage(damage: Int)
}
protocol Shootable {
func shoot(target: Targetable)
}
class Pistol: Shootable {
func shoot(target: Targetable) {
target.takeDamage(1)
}
}
class Shotgun: Shootable {
func shoot(target: Targetable) {
target.takeDamage(5)
}
}
class Enemy: Targetable {
var life: Int = 10
func takeDamage(damage: Int) {
life -= damage
println("enemy lost \(damage) hit points")
if life <= 0 {
println("enemy is dead now")
}
}
}
class Player {
var weapon: Shootable!
init(weapon: Shootable) {
self.weapon = weapon
}
func shoot(target: Targetable) {
weapon.shoot(target)
}
}
var terminator = Player(weapon: Pistol())
var enemy = Enemy()
terminator.shoot(enemy)
//> enemy lost 1 hit points
对我来说,这使得有很大的意义。但是,在我的内心深处,我对自己说“是啊,这个道理,但如果我要实现这样的事情,这将是完全不同的”,我也这样做:
class Gun {
var damage: Int {
return 0
}
}
class Pistol: Gun {
override var damage: Int {
return 5
}
}
class Shotgun: Gun {
override var damage: Int {
return 10
}
}
class Enemy {
var health = 100
func takeDamage(damage: Int) {
health = health - damage
print("Current health is: \(health)")
}
init(health: Int) {
self.health = health
}
}
class Player {
var gun: Gun
func shoot(enemy: Enemy) {
enemy.takeDamage(damage: gun.damage)
}
init(gun: Gun) {
self.gun = gun
}
}
let player = Player(gun: Pistol())
let enemy = Enemy(health: 100)
player.shoot(enemy: enemy)
//Current health is: 95
他们俩模型共享相同的损害承担机制,你有一种方法是协议和对象的混合,另一方面你有纯粹的对象。有很多人能告诉我哪种方法最好,为什么?
谢谢!
嘿,Crusty,再看那个视频。他们并不是说你不能在OOP中提出表示(特别是对于你在这里所拥有的简单的东西),但他们正在展示POP方法的优点。有很多原因可能会导致POP。也许价值语义。或者想象你有“猎人”(有“武器”)和另一个“猎杀”(有“健康”)。那么如果你介绍一个既是“猎人”又是“追捕”的新课程呢?你打算如何表现? POP中的平凡和自然,但在面向对象中卷积。 – Rob
POP是OOP的一部分。使用Swift的事情是协议(接口)不仅可以通过类来实现,还可以通过结构和枚举来实现。您将使用哪种方法还取决于特定情况。 –
我强烈建议你观看[this](https://www.youtube.com/watch?v=AySlYrel7fc)视频。对我来说,WWDC很难实现,用例可能不是那么多...... – Honey