Slide 1

Slide 1 text

Learning CQS from mutating keyword by. 2018/3/9 try! Swift After Talks 1

Slide 2

Slide 2 text

takasek iOS Developer @takasek OSS ActionClosurable౳ Xcode Extension PasteTheType 2

Slide 3

Slide 3 text

CQS Command Query Separation ίϚϯυΫΤϦ෼཭ݪଇ 3

Slide 4

Slide 4 text

Commands 1 • Change the state of a system • but do not return a value Queries • Return a result • do not change the observable state of the system • (are free of side effects) 1 https://martinfowler.com/bliki/CommandQuerySeparation.html 4

Slide 5

Slide 5 text

Side effects ෭࡞༻ 5

Slide 6

Slide 6 text

෭࡞༻͸ɺιϑτ΢ΣΞͷਖ਼͠͞ͷ ࠜڌʢʹ਺ֶతଐੑʣΛࣦΘͤΔ Side effects ruin a ground for mathematical validity of the software. 6

Slide 7

Slide 7 text

Referential transparency ࢀরಁաੑ Queries shouldn't change answers. ʮ໰͍Λൃ͢Δ͜ͱʹΑͬͯ ౴͕͑ม͑ΒΕΔ΂͖Ͱ͸ͳ͍ʯ 7

Slide 8

Slide 8 text

Martin Fowler says... 1 It would be nice if the language itself would support this notion. I could imagine a language that would detect state changing methods, or at least allow the programmer to mark them. ʮCQSΛαϙʔτͯ͘͠ΕΔݴޠ͕͋Ε͹͍͍ͷʹʯ 1 https://martinfowler.com/bliki/CommandQuerySeparation.html 8

Slide 9

Slide 9 text

9

Slide 10

Slide 10 text

mutating keyword “if you need to modify the properties of your structure or enumeration within a particular method, you can opt in to mutating behavior for that method” 3 func ͕஋ܕΦϒδΣΫτʹมߋΛՃ͑Δ͜ͱΛ໌ࣔ 3 "The Swift Programming Language (Swift 4.1)" 10

Slide 11

Slide 11 text

4 4 https://swift.org/documentation/api-design-guidelines/ 11

Slide 12

Slide 12 text

Commands 1 • Change the state of a system • but do not return a value Queries • Return a result • do not change the observable state of the system • (are free of side effects) 1 https://martinfowler.com/bliki/CommandQuerySeparation.html 12

Slide 13

Slide 13 text

Commands 1 • Change the state of a system • but do not return a value ! Queries • Return a result • do not change the observable state of the system • (are free of side effects) 1 https://martinfowler.com/bliki/CommandQuerySeparation.html 13

Slide 14

Slide 14 text

find ./stdlib/public/core | grep .swift | xargs cat | grep "public mutating func" public mutating func append(_ newElement: Element) public mutating func insert(_ newElement: Element, at i: Int) public mutating func removeFirst() public mutating func sort() public mutating func subtract(_ other: Self) public mutating func multiply(by other: Self) public mutating func divide(by other: Self) public mutating func negate() public mutating func round(_ rule: FloatingPointRoundingRule) public mutating func write(_ other: String) public mutating func encode(_ value: T, forKey key: Key) throws 14

Slide 15

Slide 15 text

Using Swift value types Swiftͷ஋ܕΛ࢖͏ = Geting along with CQS CQSʹ׳Ε਌͠Ή 15

Slide 16

Slide 16 text

How about reference types (classes)? 16

Slide 17

Slide 17 text

Do queries have side effects? ΫΤϦ͕෭࡞༻Λ͍࣋ͬͯͳ͍͔ʁ Do commands have return value? ίϚϯυ͕໭Γ஋Λ͍࣋ͬͯͳ͍͔ʁ 17

Slide 18

Slide 18 text

Learn from Swift. Swiftʹֶ΅͏ Stand on the shoulders of giants. աڈͷڊਓʹֶ΅͏ 18

Slide 19

Slide 19 text

׬ 19

Slide 20

Slide 20 text

! 20

Slide 21

Slide 21 text

find ./stdlib/public/core | grep .swift | xargs cat | grep "public mutating func" public mutating func popFirst() -> Element? public mutating func popLast() -> Element? public mutating func update(with newMember: Element) -> Element? public mutating func remove(at index: Int) -> Element public mutating func remove(_ member: Element) -> Element? public mutating func removeFirst() -> Element public mutating func removeValue(forKey key: Key) -> Value? public mutating func next() -> Element? public mutating func decode(_ input: inout I) -> UnicodeDecodingResult public mutating func superEncoder() -> Encoder public mutating func nestedContainer(keyedBy keyType: NestedKey.Type) -> KeyedEncodingContainer 21

Slide 22

Slide 22 text

Exceptions. ྫ֎΋͋Δɻ 22

Slide 23

Slide 23 text

Popping a stack is a good example of a query that modifies state. Meyer correctly says that you can avoid having this method, but it is a useful idiom. So I prefer to follow this principle when I can, but I'm prepared to break it to get my pop.1 ʮ෭࡞༻ආ͚ΒΕΔͬͯMeyer͸ݴͬͯΔ͚Ͳɺ popʹ໭Γ஋͕͋ͬͨΒਖ਼௚ศརͳͷͰ ʰCQSݪଇ͸कΕΔͳΒकΔʱʯ 1 https://martinfowler.com/bliki/CommandQuerySeparation.html 23

Slide 24

Slide 24 text

कഁ཭ 24

Slide 25

Slide 25 text

͓͖ͯ͞ɺجຊతʹ͸༗ޮͳͷ͕ ʮݪଇʯ Principles work fine principally. 25

Slide 26

Slide 26 text

ϝϦοτҙࣝͯ͠ ࢖͍͜ͳ͠·͠ΐ͏ Get along with them! 26