Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
新規チームで新規開発を始める時にやること
Search
Shinnosuke Kugimiya
March 27, 2019
Programming
40
9.4k
新規チームで新規開発を始める時にやること
DMM Android勉強会で発表した内容です
Shinnosuke Kugimiya
March 27, 2019
Tweet
Share
More Decks by Shinnosuke Kugimiya
See All by Shinnosuke Kugimiya
Claude Code x Androidアプリ 開発
kgmyshin
1
2k
AndroidアプリエンジニアもMCPを触ろう
kgmyshin
2
1.3k
15分で分かった気になる dumpsys
kgmyshin
1
310
UIテストはもうMaestroでいいのかもしれない話
kgmyshin
28
13k
新規開発を始めるときにやるべきこと
kgmyshin
19
9.1k
android app error handling
kgmyshin
1
1.5k
solid+cqs+dry
kgmyshin
35
10k
Paging Library ~ アイテムの更新 ~
kgmyshin
2
3.5k
KotlinでReact Native(expo) を使いたい
kgmyshin
2
1.2k
Other Decks in Programming
See All in Programming
今、アーキテクトとして 品質保証にどう関わるか
nealle
0
190
AI巻き込み型コードレビューのススメ
nealle
2
2.4k
Head of Engineeringが現場で回した生産性向上施策 2025→2026
gessy0129
0
200
クライアントワークでSREをするということ。あるいは事業会社におけるSREと同じこと・違うこと
nnaka2992
1
210
Amazon Bedrockを活用したRAGの品質管理パイプライン構築
tosuri13
5
900
izumin5210のプロポーザルのネタ探し #tskaigi_msup
izumin5210
1
490
RAGでハマりがちな"Excelの罠"を、データの構造化で突破する
harumiweb
8
2k
朝日新聞のデジタル版を支えるGoバックエンド ー価値ある情報をいち早く確実にお届けするために
junkiishida
1
280
文字コードの話
qnighy
43
16k
DSPy入門 Pythonで実現する自動プロンプト最適化 〜人手によるプロンプト調整からの卒業〜
seaturt1e
1
380
Claude Code、ちょっとした工夫で開発体験が変わる
tigertora7571
0
190
オブザーバビリティ駆動開発って実際どうなの?
yohfee
2
620
Featured
See All Featured
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
100
Abbi's Birthday
coloredviolet
2
5k
How Software Deployment tools have changed in the past 20 years
geshan
0
32k
Making Projects Easy
brettharned
120
6.6k
Designing for Timeless Needs
cassininazir
0
150
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
1
1.3k
Context Engineering - Making Every Token Count
addyosmani
9
720
What does AI have to do with Human Rights?
axbom
PRO
0
2k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3.3k
Mozcon NYC 2025: Stop Losing SEO Traffic
samtorres
0
160
Art, The Web, and Tiny UX
lynnandtonic
304
21k
More Than Pixels: Becoming A User Experience Designer
marktimemedia
3
340
Transcript
!LHNZTIJO %.."OESPJEษڧձ ৽نνʔϜͰ৽ن։ൃΛ࢝ΊΔ࣌ʹΔ͜ͱ
X © DMM.com ࣗݾհ
X © DMM.com ࣗݾհ w LHNZTIJOఝٶʢ͗͘Έʣ w "OESPJEΤϯδχΞ w $50ࣨॴଐ
X © DMM.com ಥવͰ͕͢ɺ ৽نҊ݅ͷ։ൃΛਐΊ͍ͯ͘தͰ ͜Μͳܦݧ͋Γ·ͤΜ͔ʁ
X © DMM.com $*Λಋೖ͍ͯ͠ͳ͍ w ͦͦ#VJME௨ͬͯͳ͍ w NBTUFS#VJME͕௨ͬͯͳ͍ w ͍͔ͭΒ௨ͬͯͳ͍ͷ͔Θ͔Βͳ͍
w νʔϜ͕ΪεΪε͢Δ
X © DMM.com -JOUΛಋೖ͍ͯ͠ͳ͍ w Πϯσϯτ͕ w ϨϏϡʔ༰ͷ΄ͱΜͲ͕ʮϑΥʔϚοτ͔͚ͯʯͰࡁΉ w νʔϜ͕ΪεΪε͢Δ
X © DMM.com $%Λಋೖ͍ͯ͠ͳ͍ w ඇ։ൃऀҎ֎ͷਓ͕ɺ։ൃதͷΞϓϦΛ͞ΘΕͳͯ͘ෆ҆ w ඇ։ൃऀͷਓ͚ͨͪʹɺQSPEʹ͍ۙͭΛ৮Ζ͏ͱͯ͠Βͬͯ QSPHVSBEʹ·Δ w
QSPHVBSE௨͚ͬͨͲɺHTPO͋ͨΓͷLFFQOBNFTͷઃఆΛΕͯɺ "1*ίʔϧ͕શ໓͢Δ w νʔϜ͕ΪεΪε͢Δ
X © DMM.com ςετΛॻ͍ͯͳ͍ w ϦϑΝΫλͰ͖ͳ͍ w มߋޙͷίʔυͱมߋલͷίʔυ͕ಉ͡ಈ͖Λ͢Δͱ͍͏อূ͕ Ͱ͖ͳ͍ w
Ͳ͏͍͏ಈ࡞Λਖ਼ͱͨ͠ϩδοΫͳͷ͔Θ͔Βͳ͍ͷͰɺϨϏϡʔͳ Μͱͳ͘େৎΖͰBQQSPWF w ͦͦ΄΅΄΅ಈ͍ͯͳ͍ʢಈ࡞֬ೝ͞Εͯͳ͍ʣ w νʔϜ͕ΪεΪε͢Δ
X © DMM.com ઃܭํΛܾΊͯͳ͍ w ਓʹΑͬͯॻ͖ํ͕શ͘ҧ͏ w ʮͷॻ͍ͯΔ7JFX.PEFM999͍ͬͯ͏͚ͩͲɺ͋ͳͨͷ ॻ͍ͯΔ7JFX.PEFMͳΜ͔ҧ͍·ͤΜ͔ʁʯ w
νʔϜ͕ΪεΪε͢Δ w ʮΈΜͳ.71͚ͩͲɺ.77.Ͱॻ͖·͢Ͷʯ
X © DMM.com ৽ن։ൃ࣌ʹɺ·ͣ։ൃपΓͷඋΛ͢Δ͜ͱ͕ॏཁ w ʹΑͬͯɺ్த͔Βͷಋೖ͕͍͠ͷɺίετ͕େ͖͍ͷ͕͋ Δ w ઃܭํ w
ಛʹ৽نνʔϜͰॏཁ w ςετํ w Βͳ͍ਓɺͬͯΔ͚Ͳಇ͍ͨ͜ͱͳ͍ਓͱɺԿͳ͘ େ͖ͳͷΛ࡞Γ্͛ΔͷࠔɻԿ͔͠Βͷτϥϒϧ͋Γ͑ ΔͷͰɺ͋Β͔͡ΊఆͰ͖ΔͷΛରॲ͓ͯ͜͠͏ɻ
X © DMM.com ৽ن։ൃΛ࢝ΊΔͱ͖༻ νΣοΫϦετ
X © DMM.com νΣοΫϦετ <>ϑΥʔϚολ <>$* <>$%
<>-JOU BOESPJEMJOU LUMJOUPSEFUFLU <>HSBEMFपΓͷཧ <>%BOHFS <>ϝοηʔδςϯϓϨʔτʢHJUIVC HJUʣ <>ઃܭํ <>ςετํ <>։ൃϑϩʔ PQU $SBTIMZUJDT PQU σόοάϝχϡʔ
X © DMM.com ࣮ࡍʹ͖ͬͯ·͠ΐ͏
X © DMM.com IUUQTHJUIVCDPNLHNZTIJOOFXQSPKFDUBOESPJEQVMM ελΠϧɾϑΥʔϚοτͷઃఆ Δ͜ͱ "4ͷઃఆ͔ΒɺͦΕͧΕͷελΠϧΛઃఆ͢Δ FEJUPSDPOpHΛઃఆ͢Δ
ϑΥʔϚολҎ֎ͷίʔσΟϯάنEPDVNFOUͳͲʹ·ͱΊ͓ͯ͘ TIBQFTFMFDUPSͳͲͷϑΝΠϧ໊ͷ໋໊نଇͳͲ
X © DMM.com <ࣗͷ߹>ελΠϧɾϑΥʔϚοτͷઃఆ 1SFGFSFODFT&EJUPS$PEF4UZMF͔Β+BWB,PUMJO9.-ͦΕͧΕΛ ઃఆͯ͠ɺԼهϑΝΠϧΛίϛοτ
X © DMM.com <ࣗͷ߹>ελΠϧɾϑΥʔϚοτͷઃఆ FEJUPSDPOpHઃఆ͠Α͏ root = true [*] insert_final_newline=true
indent_size = 2 continuation_indent_size = 2 IUUQTHJUIVCDPNLHNZTIJOOFXQSPKFDUBOESPJEQVMM
X © DMM.com νΣοΫϦετ <Y>ϑΥʔϚολ <>$* <>$%
<>-JOU BOESPJEMJOU LUMJOUPSEFUFLU <>HSBEMFपΓͷཧ <>%BOHFS <>ϝοηʔδςϯϓϨʔτʢHJUIVC HJUʣ <>ઃܭํ <>ςετํ <>։ൃϑϩʔ PQU $SBTIMZUJDT PQU σόοάϝχϡʔ
X © DMM.com HJUIVCͰϓϩδΣΫτΛ࡞ͬͨΒɺ·ͣਅͬઌʹಋೖ͢͠ w DJSDMFDJ w 5SBWJT$* w #JUSJTF
w +FOLJOT $*ͷಋೖ
X © DMM.com IUUQTHJUIVCDPNLHNZTIJOOFXQSPKFDUBOESPJEQVMM <ࣗͷ߹>$*ͷಋೖ DJSDMFDJΛ༻ ͻͱ·ͣMJOUͱUFTU͚ͩΒ͓ͤͯ͘ ./gradlew
lint test DJSDMFDJCBEHFઃఆ͓ͯ͘͠
X © DMM.com <ࣗͷ߹>$*ͷಋೖ HJUIVCͷઃఆΕͣʹ
X © DMM.com νΣοΫϦετ <Y>ϑΥʔϚολ <Y>$* <>$%
<>-JOU BOESPJEMJOU LUMJOUPSEFUFLU <>HSBEMFपΓͷཧ <>%BOHFS <>ϝοηʔδςϯϓϨʔτʢHJUIVC HJUʣ <>ઃܭํ <>ςετํ <>։ൃϑϩʔ PQU $SBTIMZUJDT PQU σόοάϝχϡʔ
X © DMM.com ඇ։ൃऀͷํʹ͚ͯɺಛʹσβΠφʔ͞Μ͕৮ΕΔΑ͏ʹॳΊ͔Β༻ҙ ͓ͯ͘͠ͷ͕٢ɻ πʔϧ༧ࢉ͍উखͰબΜͰ͍ͩ͘͞ɻ EFQMPZHBUF 'BCSJDCFUB
ʢࣗ࡞ʣ $%ͷಋೖ
X © DMM.com <ࣗͷ߹>$%ͷಋೖ
X © DMM.com <ࣗͷ߹>$%ͷಋೖ - run: | GIT_HASH=$(git rev-parse --short
HEAD) GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD) curl \ -F "token=$DEPLOY_GATE_API_KEY" \ -F "file=@app/build/outputs/apk/debug/app-debug.apk" \ -F "message=git:$GIT_HASH" \ -F "distribution_name=$GIT_BRANCH" \ https://deploygate.com/api/users/kgmyshin/apps IUUQTHJUIVCDPNLHNZTIJOOFXQSPKFDUBOESPJEDPNNJUGGEGFBEGCDEBED $*ʹઃఆ
X © DMM.com νΣοΫϦετ <Y>ϑΥʔϚολ <Y>$* <Y>$%
<>-JOU BOESPJEMJOU LUMJOUPSEFUFLU <>HSBEMFपΓͷཧ <>%BOHFS <>ϝοηʔδςϯϓϨʔτʢHJUIVC HJUʣ <>ઃܭํ <>ςετํ <>։ൃϑϩʔ PQU $SBTIMZUJDT PQU σόοάϝχϡʔ
X © DMM.com -JOU Δ͜ͱ BOESPJEMJOUͷϧʔϧͷݟ͠ LUMJOUPSEFUFLUͷಋೖ
X © DMM.com <ࣗͷ߹>-JOUͷઃఆBOESPJEMJOU <?xml version="1.0" encoding="UTF-8"?> <lint> <issue id="all">
<ignore path="build" /> </issue> <issue id="GoogleAppIndexingWarning" severity="ignore" /> </lint> ઃఆϑΝΠϧΛͭ͘Δ
X © DMM.com android { ... lintOptions { ... lintConfig
file("${rootDir.absolutePath}/lint/lint.xml") } } HSBMEFʹઃఆ͢Δɻ <ࣗͷ߹>-JOUͷઃఆBOESPJEMJOU
X © DMM.com <ࣗͷ߹>-JOUͷઃఆLUMJOU buildscript { repositories { … maven
{ url "https://plugins.gradle.org/m2/" } } dependencies { classpath "org.jmailen.gradle:kotlinter-gradle:1.22.0" … } } 5PQMFWFMͷCVJMEHSBMEFʹઃఆ͢Δɻ ˞LPUMJOUFSHSBEMFΛͬͯ·͕͢ɺଞͷͰ͍͍Ͱ͢ɻ·ͨLUMJOU͡Όͳͯ͘EFUFLUͰ0,Ͱ͢
X © DMM.com <ࣗͷ߹>-JOUͷઃఆLUMJOU NPEVMFͷCVJMEHSBMEFʹઃఆ͢Δɻ apply plugin: "org.jmailen.kotlinter" kotlinter {
ignoreFailures = true reporters = ['checkstyle', 'plain'] indentSize = 2 continuationIndentSize = 2 }
X © DMM.com <ࣗͷ߹>-JOUͷઃఆ ./gradlew lint lintKotlin $*Ͱ࣍ͷίϚϯυΛୟ͘Α͏ʹͯ͠ɺઃఆྃ IUUQTHJUIVCDPNLHNZTIJOOFXQSPKFDUBOESPJEQVMM
X © DMM.com νΣοΫϦετ <Y>ϑΥʔϚολ <Y>$* <Y>$%
<Y>-JOU BOESPJEMJOU LUMJOUPSEFUFLU <>HSBEMFपΓͷཧ <>%BOHFS <>ϝοηʔδςϯϓϨʔτʢHJUIVC HJUʣ <>ઃܭํ <>ςετํ <>։ൃϑϩʔ PQU $SBTIMZUJDT PQU σόοάϝχϡʔ
X © DMM.com HSBEMFपΓͷཧ ϚϧνϞδϡʔϧͳϓϩδΣΫτͰΔ߹͍Δ͚ͲɺγϯάϧϞδϡʔ ϧͳϓϩδΣΫτͰෆཁ͔ɻ Δ͜ͱ όʔδϣϯͳͲΛҰݩཧ
X © DMM.com <ࣗͷ߹>HSBEMFपΓͷཧ ext.kotlin_version = '1.3.21' ext.versions = [
compileSdk: 28, minSdk : 21, targetSdk : 28, code : 1, name : "0.9.0" ] ext.deps = [ kotlin : [ core : "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version", reflect: "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" ], 7FSTJPOܥΛ·ͱΊͯ͠·͏
X © DMM.com <ࣗͷ߹>HSBEMFपΓͷཧ android { compileSdkVersion versions.compileSdk defaultConfig {
minSdkVersion versions.minSdk targetSdkVersion versions.targetSdk versionCode versions.code versionName versions.name ... } ... } dependencies { implementation deps.kotlin.core implementation deps.androidx.appcompat implementation deps.androidx.constraintlayout implementation deps.androidx.lifecycle implementation deps.androidx.recyclerview ... ͜Μͳײ͡Ͱ͔͚Δ
X © DMM.com <ࣗͷ߹>HSBEMFपΓͷཧ apply plugin: 'com.android.library' apply from: "${rootDir.absolutePath}/modules/android_partial.gradle"
dependencies { … } apply from: "${rootDir.absolutePath}/modules/ktlint_partial.gradle" BOESPJEͰͷઃఆɺLUMJOUपΓ·ͱΊͯ͠·͑ɺ ֤ϞδϡʔϧͷCVJMEHSBEMFΛ͜Μͳײ͡ʹ͢Δ͜ͱͰ͖Δ IUUQTHJUIVCDPNLHNZTIJOOFXQSPKFDUBOESPJEQVMM
X © DMM.com νΣοΫϦετ <Y>ϑΥʔϚολ <Y>$* <Y>$%
<Y>-JOU BOESPJEMJOU LUMJOUPSEFUFLU <Y>HSBEMFपΓͷཧ <>%BOHFS <>ϝοηʔδςϯϓϨʔτʢHJUIVC HJUʣ <>ઃܭํ <>ςετํ <>։ൃϑϩʔ PQU $SBTIMZUJDT PQU σόοάϝχϡʔ
X © DMM.com %BOHFSͷઃఆ $PQZSJHIU D 0SUB5IFSPY 3FMFBTFEVOEFSUIF.*5MJDFOTF IUUQTHJUIVCDPNEBOHFSEFTJHOCMPCNBTUFS-*$&/4& IUUQTEBOHFSTZTUFNTHVJEFTHFUUJOH@TUBSUFEIUNM
Δ͜ͱɺHFUUJOH@TUBSUFEϖʔδΛݟͳ͕ΒηοτΞοϓ͢Δ͚ͩ
X © DMM.com %BOHFSͷઃఆ # Warn when there is a
big PR warn("a large PR") if git.lines_of_code > 1000 ### lint ### Dir.glob("**/lint-results.xml").each { |report| android_lint.filtering = true android_lint.report_file = report.to_s android_lint.lint(inline_mode: true) } զ͕Ոͷ%BOHFSpMFʢͷҰ෦ʣɻ ϚϧνϞδϡʔϧʹΑΔରԠ͕ೖΓ·͢ɻ IUUQTHJUIVCDPNLHNZTIJOOFXQSPKFDUBOESPJEQVMM
X © DMM.com νΣοΫϦετ <Y>ϑΥʔϚολ <Y>$* <Y>$%
<Y>-JOU BOESPJEMJOU LUMJOUPSEFUFLU <Y>HSBEMFपΓͷཧ <Y>%BOHFS <>ϝοηʔδςϯϓϨʔτʢHJUIVC HJUʣ <>ઃܭํ <>ςετํ <>։ൃϑϩʔ PQU $SBTIMZUJDT PQU σόοάϝχϡʔ
X © DMM.com ϝοηʔδςϯϓϨʔτ Δ͜ͱ HJUIVCܥͷςϯϓϨʔτΛ༻ҙ͢Δ PQU ίϛοτϝοηʔδͷςϯϓϨʔτΛ༻ҙ͍͍͔ͯ͠
X © DMM.com ϝοηʔδςϯϓϨʔτ IUUQTIFMQHJUIVCDPNFOBSUJDMFTBCPVUJTTVFBOEQVMMSFRVFTUUFNQMBUFT
X © DMM.com ίϛοτϝοηʔδͷ౷Ұ
X © DMM.com νΣοΫϦετ <Y>ϑΥʔϚολ <Y>$* <Y>$%
<Y>-JOU BOESPJEMJOU LUMJOUPSEFUFLU <Y>HSBEMFपΓͷཧ <Y>%BOHFS <Y>ϝοηʔδςϯϓϨʔτʢHJUIVC HJUʣ <>ઃܭํ <>ςετํ <>։ൃϑϩʔ PQU $SBTIMZUJDT PQU σόοάϝχϡʔ
X © DMM.com ઃܭํ Δ͜ͱ ઃܭํΛΈΜͳͰڞ༗Ͱ͖ΔΑ͏EPDVNFOUͳͲʹॻ͖ى͜͢
X © DMM.com ઃܭํ
X © DMM.com ઃܭํ
X © DMM.com ઃܭํ
X © DMM.com νΣοΫϦετ <Y>ϑΥʔϚολ <Y>$* <Y>$%
<Y>-JOU BOESPJEMJOU LUMJOUPSEFUFLU <Y>HSBEMFपΓͷཧ <Y>%BOHFS <Y>ϝοηʔδςϯϓϨʔτʢHJUIVC HJUʣ <Y>ઃܭํ <>ςετํ <>։ൃϑϩʔ PQU $SBTIMZUJDT PQU σόοάϝχϡʔ
X © DMM.com ςετํ Δ͜ͱ ԼهΛEPDVNFOUʹى͜͢ ͲͷϑϨʔϜϫʔΫΛ͏ͷ͔ Ͳ͜ʹͲΜͳςετΛॻ͘ͷ͔
ͦͷςετԿΛอূ͢Δͷ͔ ॻ͖ํ͕Θ͔Δαϯϓϧ
X © DMM.com ςετํ
X © DMM.com νΣοΫϦετ <Y>ϑΥʔϚολ <Y>$* <Y>$%
<Y>-JOU BOESPJEMJOU LUMJOUPSEFUFLU <Y>HSBEMFपΓͷཧ <Y>%BOHFS <Y>ϝοηʔδςϯϓϨʔτʢHJUIVC HJUʣ <Y>ઃܭํ <Y>ςετํ <>։ൃϑϩʔ PQU $SBTIMZUJDT PQU σόοάϝχϡʔ
X © DMM.com ։ൃϑϩʔ Δ͜ͱ HJUqPX HJUIVCqPX
TQSJOUͷྲྀΕΛͲ͏͏ʁ
X © DMM.com ։ൃϑϩʔ TQSJOUͷྲྀΕ ϓϥϯχϯάͷ ϓϥϯχϯά͕ऴΘͬͨΒͦͷ··ू·ͬͯશͯͷλεΫͷΫϥεਤ Λख͚ͯ͠ॻ͘
6TF$BTF͚ͩγʔέϯεਤॻ͘ ͦΕҎ֎ͷΫϥεਤɺγʔέϯεਤΛݩʹΨϦΨϦίʔσΟϯά͢ Δ͚ͩ
X © DMM.com ։ൃϑϩʔ UBTLͷྲྀΕʢઃܭํ͕ೃછΉ·Ͱࡉ͔ͬͯͨ͘ʣ ػೳ࣮ϒϥϯν࡞ ੜͤͯ͞EPNBJO࣮Ͱ13ͭ
JOGSB࣮Ͱ13ͭ 7JFX.PEFM -JWF%BUBΛ࣮ͯ͠13ͭ 'SBHNFOUʢओʹσβΠϯʣΛ࣮ͯ͠13ͭ 6TF$BTFΛ࣮ͯ͠13̍ͭ ࠷ޙʹ%*Ͱܨ͛ͯಈ࡞֬ೝ·Ͱͬͯ13ͭ
X © DMM.com ·ͱΊ
X © DMM.com νΣοΫϦετ <>ϑΥʔϚολ <>$* <>$%
<>-JOU BOESPJEMJOU LUMJOUPSEFUFLU <>HSBEMFपΓͷཧ <>%BOHFS <>ϝοηʔδςϯϓϨʔτʢHJUIVC HJUʣ <>ઃܭํ <>ςετํ <>։ൃϑϩʔ PQU $SBTIMZUJDT PQU σόοάϝχϡʔ
X © DMM.com ͝੩ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠ʂ ଞʹ͜͏͍͏ͷͬͨΒ͍͍ͱࢥ͏ʂͬͯͷ͕͋Εɺͥͻڭ͑ͯ͘ ͍ͩ͞ʂ