Created
November 7, 2017 12:07
-
-
Save norio-nomura/65db97c4786851bc368a8d68834fb31b to your computer and use it in GitHub Desktop.
https://qiita.com/hikaruna/items/7d2e919be0bc93bf3f45 を `RawRepresentable` で実装
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Mario { | |
enum State: RawState { | |
case normal = "normal" | |
case big = "big" | |
case fire = "fire" | |
case dead = "dead" | |
} | |
var state: State = .normal | |
var name: String { return "\(state.rawValue.name)マリオ" } | |
func hitEnemy() { state.rawValue.hitEnemy(self) } | |
} | |
private protocol MarioStateBehavior { | |
var name: String { get } | |
func hitEnemy(_ mario: Mario) | |
} | |
protocol Factory { | |
init(factory: Self) | |
} | |
extension Factory { | |
init(factory: Self) { | |
self = factory | |
} | |
} | |
class RawState: MarioStateBehavior, RawRepresentable, Equatable, ExpressibleByStringLiteral, Factory { | |
// MarioStateBehavior | |
var name: String { fatalError("unreachable") } | |
func hitEnemy(_ mario: Mario) { fatalError("unreachable") } | |
// RawRepresentable | |
var rawValue: String | |
required init(rawValue: String) { self.rawValue = rawValue } | |
// Equatable | |
static func == (lhs: RawState, rhs: RawState) -> Bool { return lhs.rawValue == rhs.rawValue } | |
// ExpressibleByStringLiteral | |
required convenience init(stringLiteral value: String) { | |
switch value { | |
case "normal": self.init(factory: Normal(rawValue: value)) | |
case "big": self.init(factory: Big(rawValue: value)) | |
case "fire": self.init(factory: Fire(rawValue: value)) | |
case "dead": self.init(factory: Dead(rawValue: value)) | |
default: fatalError("unreachable") | |
} | |
} | |
} | |
class Normal: RawState { | |
override var name: String { return "チビ" } | |
override func hitEnemy(_ mario: Mario) { | |
print("死ぬ") | |
mario.state = .dead | |
} | |
} | |
class Big: RawState { | |
override var name: String { return "スーパー" } | |
override func hitEnemy(_ mario: Mario) { | |
print("チビマリオになる") | |
mario.state = .normal | |
} | |
} | |
class Fire: RawState { | |
override var name: String { return "ファイアー" } | |
override func hitEnemy(_ mario: Mario) { | |
print("チビマリオになる") | |
mario.state = .normal | |
} | |
} | |
class Dead: RawState { | |
override var name: String { return "死んだ" } | |
override func hitEnemy(_ mario: Mario) { | |
print("死ぬ") | |
} | |
} | |
// 以下使用例 | |
let mario = Mario() | |
mario.name //=> "チビマリオ" | |
mario.hitEnemy() //=> print 死ぬ | |
mario.state // dead | |
mario.state = .big | |
mario.name //=> "スーパーマリオ" | |
mario.hitEnemy() //=> print チビマリオになる | |
mario.state // normal |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment