Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up for free
Self-Documenting のススメ
Elvis Shi
September 20, 2018
Programming
5
620
Self-Documenting のススメ
Elvis Shi
September 20, 2018
Tweet
Share
More Decks by Elvis Shi
See All by Elvis Shi
偏見と妄想で語るスクリプト言語としての Swift / Swift as a Scripting Language
lovee
2
370
danger-swift-kantoku
lovee
1
160
Decimal、正しく使ってる? / Are you using Decimal correctly?
lovee
4
310
A story about me trying to make a router that manages when, how and which view to transit in a SwiftUI app
lovee
1
190
M1チップの脆弱性M1raclesを読み解く / About the vulnerability on M1 chip called M1racles
lovee
1
890
Demystify SwiftUI 要約 / Summary of Demystify SwiftUI
lovee
3
390
いいから `!` を使え! / Shut up and use `!` !
lovee
11
3.4k
SwiftUIにおける依存性逆転原則の戦略 / A strategy to import Dependency-Inversion-Principle in SwiftUI apps
lovee
3
480
CGAffineTransform はどう動いてるのか?〜Swift エンジニアのための線形代数〜 / How does CGAffineTransform work? ~A linearity lesson for Swift engineers~
lovee
0
230
Other Decks in Programming
See All in Programming
僕が便利だと感じる Snow Monkey の特徴/20220723_Gifu_WordPress_Meetup
oleindesign
0
110
FullStack eXchange, July 2022
brucel
0
200
Untangling Coroutine Testing (Droidcon Berlin 2022)
zsmb
2
490
How to Test Your Compose UI (Droidcon Berlin 2022)
stewemetal
1
130
夕食断食にTRY!/for-lt-12th
pachikuriii
0
250
Google I/O 2022 Android関連概要 / Google I/O 2022 Android summary
phicdy
1
410
MLOps勉強会_リアルタイムトラフィックのサーバレスMLOps基盤_20220810
strsaito
1
460
Rust、何もわからない...#3
estie
0
170
Computer Vision Seminar 1/コンピュータビジョンセミナーvol.1 OpenCV活用
fixstars
0
170
Agile Tech EXPO_2022/カケハシ
kakehashi
0
110
回帰分析ではlm()ではなくestimatr::lm_robust()を使おう / TokyoR100
dropout009
0
4.6k
Go1.19で採用された Pattern-defeating Quicksort の紹介
po3rin
7
1.6k
Featured
See All Featured
Git: the NoSQL Database
bkeepers
PRO
415
59k
Why You Should Never Use an ORM
jnunemaker
PRO
47
7.7k
Fashionably flexible responsive web design (full day workshop)
malarkey
396
62k
Creatively Recalculating Your Daily Design Routine
revolveconf
207
10k
The Invisible Side of Design
smashingmag
290
48k
Product Roadmaps are Hard
iamctodd
35
6.9k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
498
130k
Code Reviewing Like a Champion
maltzj
506
37k
Learning to Love Humans: Emotional Interface Design
aarron
261
37k
A Philosophy of Restraint
colly
192
15k
How To Stay Up To Date on Web Technology
chriscoyier
780
250k
WebSockets: Embracing the real-time Web
robhawkes
57
5.6k
Transcript
4FMG%PDVNFOUJOH$PEF ͷεεϝ forJ04%$3FKFDU$POGFSFODFEBZT
rܙྤ lզʑΤϯδχΞେͬݏ͍ͳ͜ͱ͕Cͭ͋Δ CͭυΩϡϝϯτΛॻ͘͜ͱɻ CͭυΩϡϝϯτͷͳ͍ଞਓ͕ॻ͍ͨ ίʔυΛอक͢Δ͜ͱͩɻz
rܙྤ lզʑΤϯδχΞେͬݏ͍ͳ͜ͱ͕Cͭ͋Δ CͭυΩϡϝϯτΛॻ͘͜ͱɻ CͭυΩϡϝϯτͷͳ͍ଞਓ͕ॻ͍ͨ ίʔυΛอक͢Δ͜ͱͩɻz
rܙྤ lզʑΤϯδχΞେͬݏ͍ͳ͜ͱ͕Cͭ͋Δ CͭυΩϡϝϯτΛॻ͘͜ͱɻ CͭυΩϡϝϯτͷͳ͍ଞਓ͕ॻ͍ͨ ίʔυΛอक͢Δ͜ͱͩɻz ʊਓਓਓਓਓਓਓਓਓਓਓਓਓਓਓਓਓਓਓਓਓʊ ʼɹͩͬͨΒ࠷ॳ͔ΒυΩϡϝϯτͱͯ͠ɹʻ ʼɹ͑ΔίʔυΛॻ͚ສࣄղܾͳͷͰ
ɹʻ ʉ:?:?:?:?:?:?:?:?::?:?:?:?:?:?:?:?:ʉ
} 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 {
໔આ໌ w "͜ͷτʔΫίʔσΟϯάνοϓεతͳͰ͋Δ w #͜ͷτʔΫυΩϡϝϯτࣗಈੜͷͰͳ͍
rӳࣙ l4FMGEPDVNFOUJOHDPEFɿࣗݾจॻԽίʔυz
let s = (0 ..< 50) .map({ _ in Int.random(in:
0 ... 100) }) .filter({ $0 >= 60 }) .reduce(0, +)
let s = (0 ..< 50) .map({ _ in Int.random(in:
0 ... 100) }) .filter({ $0 >= 60 }) .reduce(0, +)
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, +) ͳΔ΄Ͳɺςετʹ߹֨ͨ͠ੜెͷ ͷ߹ܭͶʂ
rܙྤ l4FMGEPDVNFOUJOHDPEFɿࣗࣗͷҙຯΛ ͖ͪΜͱઆ໌Ͱ͖͍ͯΔίʔυz
ͳͥ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
4FMG%PDVNFOUJOH$PEFͷΞϓϩʔν w ՄಡੑʹؾΛ͚ͭΔ w Λࡉ͔͘நԽ w ҉ͳલఏΛͳ͘͢
ՄಡੑʹؾΛ͚ͭΔ
ՄಡੑʹؾΛ͚ͭΔʢʣ ͳΜͷ 63-ͩΖʁ let url = URL(string: "https://iosdc.jp/2018/")!
ՄಡੑʹؾΛ͚ͭΔʢʣ let apiBaseURL = URL(string: "https://iosdc.jp/2018/")! "1*ͷ ϕʔε63-ͩͶʂ
r୭͔ l؆ܿ͞ΑΓɺΘ͔Γ͢͞z
ՄಡੑʹؾΛ͚ͭΔʢʣ class Player { // ... var allowsMagic: Bool {
return // ຐ๏͕͑Δ͔Ͳ͏͔ͷఆ } } ຐ๏Λ ڐՄʜʁ
ՄಡੑʹؾΛ͚ͭΔʢʣ class Player { // ... var canUseMagic: Bool {
return // ຐ๏͕͑Δ͔Ͳ͏͔ͷఆ } } ຐ๏͕ ͑Δ͔Ͳ͏͔͔ʂ
r୭͔ lޡղͷͳ͍දݱʹؾΛ͚ͭΑ͏z
ՄಡੑʹؾΛ͚ͭΔʢʣ func addSubview(_ subview: UIView, _ baseView: UIView) { baseView.addSubview(subview)
} addSubview(avatarView, contentView) Ͳ͕ͬͪͲͬͪʹ Ճ͞ΕΔͷʜʁ
ՄಡੑʹؾΛ͚ͭΔʢʣ func addSubview(subview: UIView, baseView: UIView) { baseView.addSubview(subview) } addSubview(subview:
avatarView, baseView: contentView) ଟavatarView͕ࢠϏϡʔͰ contentView͕Ϗϡʔʁ
ՄಡੑʹؾΛ͚ͭΔʢʣ avatarViewΛ contentViewͷ্ʹՃͩͶʂ func addSubview(_ subview: UIView, onto baseView: UIView)
{ baseView.addSubview(subview) } addSubview(avatarView, onto: contentView)
r୭͔ lҾϥϕϧΛ͏·͘׆༻͠Α͏z
ՄಡੑʹؾΛ͚ͭΔʢʣ func addSubview(_ subview: UIView, onto baseView: UIView) { baseView.addSubview(subview)
} addSubview(avatarView, onto: contentView)
ՄಡੑʹؾΛ͚ͭΔʢʣ func addSubview(_ subview: UIView, onto baseView: UIView, ifNeeded) {
if !baseView.subviews.contains(where: { $0 === subview }) { baseView.addSubview(subview) } } addSubview(avatarView, onto: contentView, ifNeeded) ಡΈ͍͕͢ จ๏ΤϥʔͰ͋Δ
rܙྤ l4XJGUͷจ๏ʹ།Ұʹͯ͠࠷େͷෆຬ ޙஔϥϕϧ͕ͳ͍͜ͱz
ՄಡੑʹؾΛ͚ͭΔʢʣ func addSubview(_ subview: UIView, onto baseView: UIView, ifNeeded) {
if !baseView.subviews.contains(where: { $0 === subview }) { baseView.addSubview(subview) } } addSubview(avatarView, onto: contentView, ifNeeded)
ՄಡੑʹؾΛ͚ͭΔʢʣ 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ΛΘ͟Θ͟ఆٛ͠ͳ͍ͱ͍͚ͳ͍ɺ໘ष͍ɺ໊લিಥ͍͢͠
ՄಡੑʹؾΛ͚ͭΔʢʣ func addSubview(_ subview: UIView, onto baseView: UIView, ifNeeded: ())
{ if !baseView.subviews.contains(where: { $0 === subview }) { baseView.addSubview(subview) } } addSubview(avatarView, onto: contentView, ifNeeded: ()) ߈ུ#ɿޙஔϥϕϧ༻ͷμϛʔҾΛ࡞Δ ɿԿՃͰఆٛ͢Δඞཁ͕ͳ͍ɺָ ɿར༻෦ΛಡΉ࣌ඍົʹͳͥ͜ͷҾͯ͠Δͷ͔Λߟ͑ͯ͠·͍ͦ͏
ՄಡੑʹؾΛ͚ͭΔʢʣ ߈ུ$ɿ࠷ॳ͔ΒޙஔϥϕϧΛ࡞Βͳ͍ ɿճΓ͘Ͳ͍ϫʔΫΞϥϯυ͕ཁΒͳ͍ ɿӳจ๏ͱͯͪ͠ΐͬͱඍົͳͷͰ͏ͪΐͬͱ໊લͷ͕ඞཁ͔ func addSubviewIfNeeded(_ subview: UIView, onto baseView:
UIView) { if !baseView.subviews.contains(where: { $0 === subview }) { baseView.addSubview(subview) } } addSubviewIfNeeded(avatarView, onto: contentView)
rܙྤ l݁ɿޙஔϥϕϧཉ͍͠ɻz
ՄಡੑʹؾΛ͚ͭΔʢʣ 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ͷঢ়ଶ͕มΘͬͨ
ՄಡੑʹؾΛ͚ͭΔʢʣ 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() ͜ͷϝιουΓ͕͋Δ͕ ෭࡞༻͋Δϝιουͩʂ
r୭͔ l෭࡞༻͕͋Δ͔Ͳ͏͔Λ໌ࣔ͠Α͏z
IUUQTTXJGUPSHEPDVNFOUBUJPOBQJEFTJHOHVJEFMJOFTTUSJWFGPSqVFOUVTBHF
ՄಡੑʹؾΛ͚ͭΔ w ؆ܿ͞ΑΓɺΘ͔Γ͢͞ w ޡղͷͳ͍දݱʹؾΛ͚ͭΑ͏ w ҾϥϕϧΛ͏·͘׆༻͠Α͏ w ෭࡞༻͕͋Δ͔Ͳ͏͔Λ໌ࣔ͠Α͏
クイズ:象さんを冷蔵庫に入れる手順は? 1.冷蔵庫のドアを開ける 2.象さんを冷蔵庫の中に入れる 3.冷蔵庫のドアを閉める
ࡉ͔͘நԽ
ࡉ͔͘நԽ class SomeScreen { func presentWebPage() { // ΞυϨεόʔΛ... //
ΔϘλϯΛ... // ... // จࣈྻΛ URL ʹ... // URL ͔ΒϦΫΤετΛ... // ... // จࣈίʔυΛ... // ༰ͷϨΠΞτΛ... // ... // } }
ࡉ͔͘நԽ class SomeScreen { func presentWebPage() { // ॳظ WebPage
ը໘Λ࡞Δ // ࡞ͬͨ WebPage ը໘ʹભҠ͢Δ // ભҠ͕ऴΘͬͨΒ WebPage ը໘ͰಡΈࠐΉ } }
ࡉ͔͘நԽ class SomeScreen { func presentWebPage() { let screen =
WebPageScreen() self.present(screen, completion: { screen.loadAddress("user_defined") }) } }
ࡉ͔͘நԽ class SomeScreen { // presentWebPage private func present(_ screen:
WebPageScreen, completion: () -> Void) { // ભҠॲཧʹઐ೦ } } class WebPageScreen { // ը໘ߏʹઐ೦ func loadAddress(_ address: String) { // ಡΈࠐΈॲཧʹઐ೦ } }
Λࡉ͔͘நԽ͢Δ w ͍͖ͳΓ۩ମతͳ࣮Λߟ͑ͳ͍ w ෳࡶͳͦͦߟ͑Δͷ͍͠ w ؆୯ͳͰ͋Δఔͬ͘͟ΓͳΠϝʔδ͕͍͍ w ෳࡶͳػೳ΄Ͳɺͪΐͬͱׂͣͭ͢Δ w
Ұʹߟ͑ΔΛߜΕΔ w 5%%ʹ௨͡Δߟ͑ํ w ςετॻ͖͘͢ͳΔͱ͍͏خ͍͠෭࡞༻ w ෦ͷʹઐ೦͢Δ w ඞཁʹԠͯ͡%FMFHBUF$MPTVSFʹؙ͛
҉ͳલఏΛͳ͘͢
҉ͳલఏΛͳ͘͢ class SomeContainerView: UIScrollView { var childViews: [UIView] = []
// ... func scrollToView(at index: Int) { self.contentOffset.x = self.bounds.width * CGFloat(index) } } தಡΜͰΈͨΒ ͜Ε֤childViewͷ෯͕ࣗͷ෯ͱಉ͡ ͱ͍͏લఏͰಈ͍ͯΔॲཧͩ
҉ͳલఏΛͳ͘͢ class SomeContainerView: UIScrollView { var childViews: [UIView] = []
// ... func scrollToView(at index: Int) { self.contentOffset = self.childViews[index].frame.origin } } ͍ͭͲ͜Ͱ୭ʹݺΕΑ͏ͱඞͣ ֘childView͕දࣔ͞ΕΔॲཧͰ͋Δ ʢchildViewͷϨΠΞτͱ͍͏҉ͳલఏʹ ґଘ͠ͳ͍ʣ
҉ͳલఏΛͳ͘͢ 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 } } Ͳ͏ͯ͠֎ͤͳ͍લఏ ඞͣ໌ࣔ͢Δ
҉ͳલఏΛͳ͘͢ w ͍ͭͲ͜Ͱ୭ʹݺΕͯಉ݁͡ՌʹͳΔΑ͏ʹ࡞Δ w Ͳ͏ͯ͠ඞཁͳલఏΛ໌ࣔ͢Δ w લఏΛҾʹͰ͖ΕҾʹ͢Δ w લఏΛҾʹͰ͖ͳ͚Ε໊લʹΈࠐΉ w
໊લʹΈࠐΉʹ͍͠߹࣮ͰΞαʔτ
4FMG%PDVNFOUJOH$PEFͷΞϓϩʔν w ՄಡੑʹؾΛ͚ͭΔ w Λࡉ͔͘நԽ w ҉ͳલఏΛͳ͘͢
͡Ό͋4FMG%PDVNFOUJOH$PEFͰॻ͍ͨϓϩάϥϜ ίϝϯτυΩϡϝϯτ͕શ͘ཁΒͳ͘ͳΔͷʁ
4FMG%PDVNFOUJOH$PEF͚ͩͰΓͳ͍ w $PEFʮ8IBUʯͱʮ)PXʯ͚͔ͩ͠આ໌Ͱ͖ͳ͍ w ϓϩάϥϜϓϩδΣΫτΛཧղ͢ΔͨΊʹ ʮ8IZʯඞཁʢΠϨΪϡϥʔͳ༷આ໌ͳͲʣ w υΩϡϝϯτίϝϯτͰ8IBUͱ)PXΛઆ໌͠ͳ ͯ͘ࡁΉΘΓʹɺ8IZͷઆ໌ʹઐ೦Ͱ͖Δ w
݁Ռͱͯ͠ඞཁՕॴϘϦϡʔϜ͕ݮΔʂ
4FMG%PDVNFOUJOH$PEFͰ ফͷগͳ͍։ൃϥΠϑΛ