Self-Documenting のススメ

Af64bc38c0ffcfcabdf430759ee491ce?s=47 Elvis Shi
September 20, 2018

Self-Documenting のススメ

Af64bc38c0ffcfcabdf430759ee491ce?s=128

Elvis Shi

September 20, 2018
Tweet

Transcript

  1. 4FMG%PDVNFOUJOH$PEF
 ͷεεϝ forJ04%$3FKFDU$POGFSFODFEBZT

  2. r੕໺ܙྤ lզʑΤϯδχΞ͸େͬݏ͍ͳ͜ͱ͕Cͭ͋Δ  Cͭ໨͸υΩϡϝϯτΛॻ͘͜ͱɻ  Cͭ໨͸υΩϡϝϯτͷͳ͍ଞਓ͕ॻ͍ͨ
 ίʔυΛอक͢Δ͜ͱͩɻz

  3. r੕໺ܙྤ lզʑΤϯδχΞ͸େͬݏ͍ͳ͜ͱ͕Cͭ͋Δ  Cͭ໨͸υΩϡϝϯτΛॻ͘͜ͱɻ  Cͭ໨͸υΩϡϝϯτͷͳ͍ଞਓ͕ॻ͍ͨ
 ίʔυΛอक͢Δ͜ͱͩɻz

  4. r੕໺ܙྤ lզʑΤϯδχΞ͸େͬݏ͍ͳ͜ͱ͕Cͭ͋Δ  Cͭ໨͸υΩϡϝϯτΛॻ͘͜ͱɻ  Cͭ໨͸υΩϡϝϯτͷͳ͍ଞਓ͕ॻ͍ͨ
 ίʔυΛอक͢Δ͜ͱͩɻz ʊਓਓਓਓਓਓਓਓਓਓਓਓਓਓਓਓਓਓਓਓਓʊ ʼɹͩͬͨΒ࠷ॳ͔ΒυΩϡϝϯτͱͯ͠΋ɹʻ ʼɹ࢖͑ΔίʔυΛॻ͚͹ສࣄղܾͳͷͰ͸

    ɹʻ ʉ:?:?:?:?:?:?:?:?::?:?:?:?:?:?:?:?:ʉ
  5. } var employedBy = "YUMEMI Inc." var job = "iOS

    Developer" var favoriteLanguage = "Swift" var twitter = "@lovee" var qiita = "lovee" var github = "el-hoshino" var additionalInfo = """ iOSDC 2018 CfP શ෦མͪͨਏ͍ """ class Me: Developable, Talkable {
  6. ໔੹આ໌ w "͜ͷτʔΫ͸ίʔσΟϯάνοϓεతͳ࿩Ͱ͋Δ w #͜ͷτʔΫ͸υΩϡϝϯτࣗಈੜ੒ͷ࿩Ͱ͸ͳ͍

  7. rӳࣙ࿠ l4FMGEPDVNFOUJOHDPEFɿࣗݾจॻԽίʔυz

  8. let s = (0 ..< 50) .map({ _ in Int.random(in:

    0 ... 100) }) .filter({ $0 >= 60 }) .reduce(0, +)
  9. let s = (0 ..< 50) .map({ _ in Int.random(in:

    0 ... 100) }) .filter({ $0 >= 60 }) .reduce(0, +)
  10. private extension Int { var isPassed: Bool { return self

    >= 60 } } let numberOfStudents = 50 let studentsScoreList = (0 ..< numberOfStudents) .map({ _ -> Int in let score = Int.random(in: 0 ... 100) return score }) let passedStudentsScoreList = studentsScoreList .filter({ $0.isPassed }) let totalScoreOfAllPassedStudents = passedStudentsScoreList .reduce(0, +) ͳΔ΄Ͳɺςετʹ߹֨ͨ͠ੜెͷ
 ఺਺ͷ߹ܭͶʂ
  11. r੕໺ܙྤ l4FMGEPDVNFOUJOHDPEFɿࣗ෼ࣗ਎ͷҙຯΛ
 ͖ͪΜͱઆ໌Ͱ͖͍ͯΔίʔυz

  12. ͳͥ4FMG%PDVNFOUJOH$PEFʁ w ಉ͜͡ͱΛʮίʔυʯͱʮυΩϡϝϯτʯ྆ํͰॻ͘ ͱ͍͏ೋ౓ख͕ؒݮΔɻ w w w w w w

    w w ίʔυϨϏϡʔ͕ΑΓ͠΍͘͢ͳΔɻ w ίϛολʔͷҙਤ͕ಡΈऔΓ΍͘͢ͳΔ w w w w w w w w w w w อक͢Δ࣌ʹ໰୊ՕॴΛಛఆ͠΍͘͢ͳΔ w w w w w w
  13. 4FMG%PDVNFOUJOH$PEF΁ͷΞϓϩʔν w ՄಡੑʹؾΛ͚ͭΔ w ໰୊Λࡉ͔͘ந৅Խ w ҉໧ͳલఏΛͳ͘͢

  14. ՄಡੑʹؾΛ͚ͭΔ

  15. ՄಡੑʹؾΛ͚ͭΔʢʣ ͳΜͷ 63-ͩΖʁ let url = URL(string: "https://iosdc.jp/2018/")!

  16. ՄಡੑʹؾΛ͚ͭΔʢʣ let apiBaseURL = URL(string: "https://iosdc.jp/2018/")! "1*ͷ ϕʔε63-ͩͶʂ

  17. r୭͔ l؆ܿ͞ΑΓɺΘ͔Γ΍͢͞z

  18. ՄಡੑʹؾΛ͚ͭΔʢʣ class Player { // ... var allowsMagic: Bool {

    return // ຐ๏͕࢖͑Δ͔Ͳ͏͔ͷ൑ఆ } } ຐ๏Λ ڐՄʜʁ
  19. ՄಡੑʹؾΛ͚ͭΔʢʣ class Player { // ... var canUseMagic: Bool {

    return // ຐ๏͕࢖͑Δ͔Ͳ͏͔ͷ൑ఆ } } ຐ๏͕ ࢖͑Δ͔Ͳ͏͔͔ʂ
  20. r୭͔ lޡղͷͳ͍දݱʹؾΛ͚ͭΑ͏z

  21. ՄಡੑʹؾΛ͚ͭΔʢʣ func addSubview(_ subview: UIView, _ baseView: UIView) { baseView.addSubview(subview)

    } addSubview(avatarView, contentView) Ͳ͕ͬͪͲͬͪʹ ௥Ճ͞ΕΔͷʜʁ
  22. ՄಡੑʹؾΛ͚ͭΔʢʣ func addSubview(subview: UIView, baseView: UIView) { baseView.addSubview(subview) } addSubview(subview:

    avatarView, baseView: contentView) ଟ෼avatarView͕ࢠϏϡʔͰ contentView͕਌Ϗϡʔʁ
  23. ՄಡੑʹؾΛ͚ͭΔʢʣ avatarViewΛ contentViewͷ্ʹ௥ՃͩͶʂ func addSubview(_ subview: UIView, onto baseView: UIView)

    { baseView.addSubview(subview) } addSubview(avatarView, onto: contentView)
  24. r୭͔ lҾ਺ϥϕϧΛ͏·͘׆༻͠Α͏z

  25. ՄಡੑʹؾΛ͚ͭΔʢʣ func addSubview(_ subview: UIView, onto baseView: UIView) { baseView.addSubview(subview)

    } addSubview(avatarView, onto: contentView)
  26. ՄಡੑʹؾΛ͚ͭΔʢʣ func addSubview(_ subview: UIView, onto baseView: UIView, ifNeeded) {

    if !baseView.subviews.contains(where: { $0 === subview }) { baseView.addSubview(subview) } } addSubview(avatarView, onto: contentView, ifNeeded) ಡΈ΍͍͕͢
 จ๏ΤϥʔͰ͋Δ
  27. r੕໺ܙྤ l4XJGUͷจ๏ʹ།Ұʹͯ͠࠷େͷෆຬ఺͸
 ޙஔϥϕϧ͕ͳ͍͜ͱz

  28. ՄಡੑʹؾΛ͚ͭΔʢʣ func addSubview(_ subview: UIView, onto baseView: UIView, ifNeeded) {

    if !baseView.subviews.contains(where: { $0 === subview }) { baseView.addSubview(subview) } } addSubview(avatarView, onto: contentView, ifNeeded)
  29. ՄಡੑʹؾΛ͚ͭΔʢʣ enum AddSubviewPostLabel { case ifNeeded } func addSubview(_ subview:

    UIView, onto baseView: UIView, _ label: AddSubviewPostLabel) { if !baseView.subviews.contains(where: { $0 === subview }) { baseView.addSubview(subview) } } addSubview(avatarView, onto: contentView, .ifNeeded) ߈ུ"ɿޙஔϥϕϧ༻ͷenumҾ਺Λ׶͑ͯ࡞Δ ɿར༻෦ΛಡΉͱ͔ͳΓಡΈ΍͍͢ ɿenumΛΘ͟Θ͟ఆٛ͠ͳ͍ͱ͍͚ͳ͍ɺ໘౗ष͍ɺ໊લিಥ͠΍͍͢
  30. ՄಡੑʹؾΛ͚ͭΔʢʣ func addSubview(_ subview: UIView, onto baseView: UIView, ifNeeded: ())

    { if !baseView.subviews.contains(where: { $0 === subview }) { baseView.addSubview(subview) } } addSubview(avatarView, onto: contentView, ifNeeded: ()) ߈ུ#ɿޙஔϥϕϧ༻ͷμϛʔҾ਺Λ࡞Δ ɿԿ΋௥ՃͰఆٛ͢Δඞཁ͕ͳ͍ɺָ ɿར༻෦ΛಡΉ࣌ඍົʹͳͥ͜ͷҾ਺౉ͯ͠Δͷ͔Λߟ͑ͯ͠·͍ͦ͏
  31. ՄಡੑʹؾΛ͚ͭΔʢʣ ߈ུ$ɿ࠷ॳ͔ΒޙஔϥϕϧΛ࡞Βͳ͍ ɿճΓ͘Ͳ͍ϫʔΫΞϥ΢ϯυ͕ཁΒͳ͍ ɿӳจ๏ͱͯͪ͠ΐͬͱඍົͳͷͰ΋͏ͪΐͬͱ໊લͷ޻෉͕ඞཁ͔΋ func addSubviewIfNeeded(_ subview: UIView, onto baseView:

    UIView) { if !baseView.subviews.contains(where: { $0 === subview }) { baseView.addSubview(subview) } } addSubviewIfNeeded(avatarView, onto: contentView)
  32. r੕໺ܙྤ l݁࿦ɿޙஔϥϕϧཉ͍͠ɻz

  33. ՄಡੑʹؾΛ͚ͭΔʢʣ class SomeSequence { private var numbers: [Int] = [3,

    2, 1] private var isSorted: Bool = false // ... func getSorted() -> [Int] { self.numbers = self.numbers.sorted(by: <) self.isSorted = true return self.numbers } } let sequence = SomeSequence() // Կ͔ॲཧ... let sorted = sequence.getSorted() ฒͼସ͑ΒΕͨ഑ྻΛऔΖ͏ͱͨ͠
 ͚ͩͳͷʹsequenceͷঢ়ଶ͕มΘͬͨ
  34. ՄಡੑʹؾΛ͚ͭΔʢʣ class SomeSequence { private var numbers: [Int] = [3,

    2, 1] private var isSorted: Bool = false // ... @discardableResult func sort() -> [Int] { self.numbers = self.numbers.sorted(by: <) self.isSorted = true return self.numbers } } let sequence = SomeSequence() // Կ͔ॲཧ... let sorted = sequence.sort() ͜ͷϝιου͸໭Γ஋͕͋Δ͕
 ෭࡞༻΋͋Δϝιουͩʂ
  35. r୭͔ l෭࡞༻͕͋Δ͔Ͳ͏͔Λ໌ࣔ͠Α͏z

  36. IUUQTTXJGUPSHEPDVNFOUBUJPOBQJEFTJHOHVJEFMJOFTTUSJWFGPSqVFOUVTBHF

  37. ՄಡੑʹؾΛ͚ͭΔ w ؆ܿ͞ΑΓɺΘ͔Γ΍͢͞ w ޡղͷͳ͍දݱʹؾΛ͚ͭΑ͏ w Ҿ਺ϥϕϧΛ͏·͘׆༻͠Α͏ w ෭࡞༻͕͋Δ͔Ͳ͏͔Λ໌ࣔ͠Α͏

  38. クイズ:象さんを冷蔵庫に入れる手順は? 1.冷蔵庫のドアを開ける 2.象さんを冷蔵庫の中に入れる 3.冷蔵庫のドアを閉める

  39. ࡉ͔͘ந৅Խ

  40. ࡉ͔͘ந৅Խ class SomeScreen { func presentWebPage() { // ΞυϨεόʔΛ... //

    ໭ΔϘλϯΛ... // ... // จࣈྻΛ URL ʹ... // URL ͔ΒϦΫΤετΛ... // ... // จࣈίʔυΛ... // ಺༰ͷϨΠΞ΢τΛ... // ... // } }
  41. ࡉ͔͘ந৅Խ class SomeScreen { func presentWebPage() { // ॳظ WebPage

    ը໘Λ࡞Δ // ࡞ͬͨ WebPage ը໘ʹભҠ͢Δ // ભҠ͕ऴΘͬͨΒ WebPage ը໘ͰಡΈࠐΉ } }
  42. ࡉ͔͘ந৅Խ class SomeScreen { func presentWebPage() { let screen =

    WebPageScreen() self.present(screen, completion: { screen.loadAddress("user_defined") }) } }
  43. ࡉ͔͘ந৅Խ class SomeScreen { // presentWebPage private func present(_ screen:

    WebPageScreen, completion: () -> Void) { // ભҠॲཧʹઐ೦ } } class WebPageScreen { // ը໘ߏ੒ʹઐ೦ func loadAddress(_ address: String) { // ಡΈࠐΈॲཧʹઐ೦ } }
  44. ໰୊Λࡉ͔͘ந৅Խ͢Δ w ͍͖ͳΓ۩ମతͳ࣮૷Λߟ͑ͳ͍ w ෳࡶͳ໰୊͸ͦ΋ͦ΋ߟ͑Δͷ͸೉͍͠ w ؆୯ͳ໰୊Ͱ΋͋Δఔ౓ͬ͘͟ΓͳΠϝʔδ͕͍͍ w ෳࡶͳػೳ΄Ͳɺͪΐͬͱͣͭ෼ׂ͢Δ w

    Ұ౓ʹߟ͑Δ໰୊ΛߜΕΔ w 5%%ʹ΋௨͡Δߟ͑ํ w ςετ΋ॻ͖΍͘͢ͳΔͱ͍͏خ͍͠෭࡞༻ w ෦඼ͷ੹຿ʹઐ೦͢Δ w ඞཁʹԠͯ͡%FMFHBUF΍$MPTVSFʹؙ౤͛
  45. ҉໧ͳલఏΛͳ͘͢

  46. ҉໧ͳલఏΛͳ͘͢ class SomeContainerView: UIScrollView { var childViews: [UIView] = []

    // ... func scrollToView(at index: Int) { self.contentOffset.x = self.bounds.width * CGFloat(index) } } த਎ಡΜͰΈͨΒ
 ͜Ε͸֤childViewͷ෯͕ࣗ਎ͷ෯ͱಉ͡
 ͱ͍͏લఏͰಈ͍ͯΔॲཧͩ
  47. ҉໧ͳલఏΛͳ͘͢ class SomeContainerView: UIScrollView { var childViews: [UIView] = []

    // ... func scrollToView(at index: Int) { self.contentOffset = self.childViews[index].frame.origin } } ͍ͭͲ͜Ͱ୭ʹݺ͹ΕΑ͏ͱඞͣ ֘౰childView͕දࣔ͞ΕΔॲཧͰ͋Δ 
 ʢchildViewͷϨΠΞ΢τͱ͍͏҉໧ͳલఏʹ ґଘ͠ͳ͍ʣ
  48. ҉໧ͳલఏΛͳ͘͢ class SomeContainerView: UIScrollView { private var childViews: [UIView] =

    [] // ... func scrollToChildView(at index: Int) { let childView = self.childViews[index] assert(childView.superview === self) self.contentOffset = childView.frame.origin } } Ͳ͏ͯ͠΋֎ͤͳ͍લఏ͸ ඞͣ໌ࣔ͢Δ
  49. ҉໧ͳલఏΛͳ͘͢ w ͍ͭͲ͜Ͱ୭ʹݺ͹Εͯ΋ಉ݁͡ՌʹͳΔΑ͏ʹ࡞Δ w Ͳ͏ͯ͠΋ඞཁͳલఏΛ໌ࣔ͢Δ w લఏΛҾ਺ʹͰ͖Ε͹Ҿ਺ʹ͢Δ w લఏΛҾ਺ʹͰ͖ͳ͚Ε͹໊લʹ૊ΈࠐΉ w

    ໊લʹ૊ΈࠐΉʹ΋೉͍͠৔߹͸࣮૷ͰΞαʔτ
  50. 4FMG%PDVNFOUJOH$PEF΁ͷΞϓϩʔν w ՄಡੑʹؾΛ͚ͭΔ w ໰୊Λࡉ͔͘ந৅Խ w ҉໧ͳલఏΛͳ͘͢

  51. ͡Ό͋4FMG%PDVNFOUJOH$PEFͰॻ͍ͨϓϩάϥϜ͸
 ίϝϯτ΍υΩϡϝϯτ͕શ͘ཁΒͳ͘ͳΔͷʁ

  52. 4FMG%PDVNFOUJOH$PEF͚ͩͰ͸଍Γͳ͍ w $PEF͸ʮ8IBUʯͱʮ)PXʯ͚͔ͩ͠આ໌Ͱ͖ͳ͍ w ϓϩάϥϜ΍ϓϩδΣΫτΛཧղ͢ΔͨΊʹ͸ ʮ8IZʯ΋ඞཁʢΠϨΪϡϥʔͳ࢓༷આ໌ͳͲʣ w υΩϡϝϯτ΍ίϝϯτͰ8IBUͱ)PXΛઆ໌͠ͳ ͯ͘ࡁΉ୅ΘΓʹɺ8IZͷઆ໌ʹઐ೦Ͱ͖Δ w

    ݁Ռͱͯ͠ඞཁՕॴ΍ϘϦϡʔϜ͕ݮΔʂ
  53. 4FMG%PDVNFOUJOH$PEFͰ
 ফ໣ͷগͳ͍։ൃϥΠϑΛ