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
最初が肝心!技術的負債解消に向けて最初にやるべきこと/first-step-to-pay-of...
Search
Takehiro Kaneko
April 11, 2023
Programming
1.4k
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
最初が肝心!技術的負債解消に向けて最初にやるべきこと/first-step-to-pay-off-technical-debt
Takehiro Kaneko
April 11, 2023
More Decks by Takehiro Kaneko
See All by Takehiro Kaneko
大規模UIKitベースアプリへのTCAの段階的導入/gradual-adoption-of-tca-in-a-large-scale-uikit-based-app
takehilo
2
680
むやみにActionを送信してはいけない/do-not-send-actions-thoughtlessly
takehilo
3
1.7k
SwiftUI+TCAに挑戦!NewsPicks iOSアプリのリアーキテクチャ/re-architecture-newspicks-ios-app-with-swiftui-and-tca
takehilo
1
3.2k
iOSアプリ開発に MVVM+Redux パターンを使い始めた話/ios-mvvm-redux-pattern
takehilo
1
1.5k
RxBlocking Deep Dive
takehilo
1
1.1k
RxTest/RxBlockingテストパターン / RxTest RxBlocking Test Patterns
takehilo
5
1.7k
Other Decks in Programming
See All in Programming
エンジニア向け会社紹介/Findy Company Profile
findyinc
6
360k
才能?センス?知らん、 続けたもん勝ちだ。-- 結婚・出産・癌を越えてなお、私がプロダクトを創り続ける理由
16bitidol
2
800
Mujeres en SEO Summit 2026 - Greatest Disaster Hits en Web Performance
guaca
0
240
Webフレームワークの ベンチマークについて
yusukebe
0
200
Even G2とAWSで推しのエージェントを召喚しよう!
har1101
1
140
エージェンティックRAGにAWSで入門しよう!
har1101
9
1.9k
トークンをケチるな、設計しろ:GitHub Copilotを賢く使うコンテキスト戦略
ochtum
0
300
act1-costs.pdf
sumedhbala
0
180
AIを活用したE2Eテスト実装効率化のあゆみ / ebisu-mobile-14-kotetu
kotetuco
0
160
初めてのKubernetes 本番運用でハマった話
oku053
0
120
【やさしく解説 設計編 #0】DDDのコード、読めるのに分からない人へ
panda728
PRO
2
240
ADKを使って簡単にAIエージェントを作ってみよう
k1mu21
0
290
Featured
See All Featured
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
47
8.2k
AI Search: Implications for SEO and How to Move Forward - #ShenzhenSEOConference
aleyda
1
1.3k
コードの90%をAIが書く世界で何が待っているのか / What awaits us in a world where 90% of the code is written by AI
rkaga
62
44k
Git: the NoSQL Database
bkeepers
PRO
432
67k
Hiding What from Whom? A Critical Review of the History of Programming languages for Music
tomoyanonymous
3
890
The Illustrated Children's Guide to Kubernetes
chrisshort
51
52k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
10
1.2k
B2B Lead Gen: Tactics, Traps & Triumph
marketingsoph
0
170
How to Think Like a Performance Engineer
csswizardry
28
2.7k
職位にかかわらず全員がリーダーシップを発揮するチーム作り / Building a team where everyone can demonstrate leadership regardless of position
madoxten
63
55k
Winning Ecommerce Organic Search in an AI Era - #searchnstuff2025
aleyda
1
2.1k
Marketing Yourself as an Engineer | Alaka | Gurzu
gurzu
0
260
Transcript
最初が肝心! 技術的負債解消に向けて最初にやるべきこと 2023.04.12 モバイルアプリの技術的負債 みんなで学ぶ Lunch LT NewsPicks iOSエンジニア /
金子 雄大
00 自己紹介 ©NewsPicks Inc. All Rights Reserved. 金子 雄大
NewsPicks iOSエンジニア @takehilo_kaneko takehilo takehilo
00 NewsPicksについて ©NewsPicks Inc. All Rights Reserved.
00 前回登壇のイベント ©NewsPicks Inc. All Rights Reserved. • 今日と同じく技術的負債の解消がテーマ
• アーカイブ動画が公開されてるので、今日と合わ せて是非ご参考に https://uzabase-tech.connpass.com/event/253143/
©NewsPicks Inc. All Rights Reserved. 01 リアーキテクチャ実施の背景
01 ビジネス優先で走り続けてきた ©NewsPicks Inc. All Rights Reserved. iOSアプリのコードは限界に来ていた... •
NewsPicksはリリースからまもなく10年を迎える • その間、何度もUIがリニューアルされてきた • 一方で、コードの保守性は置き去りにされたまま ここまで来てしまった
01 技術的負債解消のアプローチ ©NewsPicks Inc. All Rights Reserved. • 既存のアーキテクチャのまま負債を返済していくことはもはや不可能 •
ただし、ゼロから作り直すための時間とリソースは無い 新しいアーキテクチャを作成し、既存の画面・機能を少しずつ新しい アーキテクチャで作り直していくことにした
01 今日伝えたいこと ©NewsPicks Inc. All Rights Reserved. 作り直しに取りかかる前にやっておいたほうが良いことがある • 技術的負債が生まれにくくすること
• たとえ技術的負債が生まれても、返済可能な状態を維持できるようにすること 具体的に何をすべきかをこの後話していく
©NewsPicks Inc. All Rights Reserved. 02 作り直しをする前に 最初にやるべきこと
02 最初にやるべきこと ©NewsPicks Inc. All Rights Reserved. • コードをレイヤー分けしてマルチモジュール化し、依存の方向を強制する •
ユニットテストの実装を強制する環境を作る 強制するというのがポイント!
©NewsPicks Inc. All Rights Reserved. 02 マルチモジュール化して 依存の方向を強制する
02 レイヤー分けと依存の方向の例 ©NewsPicks Inc. All Rights Reserved. • 新しいアーキテクチャのモジュールから古い コード(Legacy)を参照できないようにする
• PresentationとInfrastructureはDomainにの み依存し、直接参照し合わないようにする
02 なぜ依存の方向を強制するのか? ©NewsPicks Inc. All Rights Reserved. • フォルダ分けをしただけでシングルモジュール構成のままだと、新しいコードから古 いコードを利用できてしまう
◦ 負債を返済しているつもりが、新たな負債を生み出すことに... • モジュールを分けて依存の方向を強制してしまえば、これができなくなる 「古いコードは参照しない」というルールを決めても、それを継続し続 けるのは実は難しい ルールを強制してあげることで、新しいコードをキレイな状態に保ちな がら、負債を返済していくことができる
02 依存の方向を強制することによるその他のメリット ©NewsPicks Inc. All Rights Reserved. • 何でも屋クラスが作られづらくなり、各クラスの責務が明確になる。さらに、その状 態を維持しやすい
• ライブラリへの依存がモジュールに閉じるので、ライブラリを使ったコードが散らば らないし、ライブラリの更新、差し替えもしやすくなる 負債が生まれにくく、かつ生まれても返済可能な状態を維持できる!
02 どうしても古いコードを使いたいときは ©NewsPicks Inc. All Rights Reserved. • Adapterパターンを使って古いコードを参照する(後述) ◦
戻り値の型を新しいコードのものに変換するなどして、新しいコードの都合に 合わせるようにする • 利用は最低限にすること
02 Adapterパターンを使った古いコードの利用方法 ©NewsPicks Inc. All Rights Reserved. • 利用したいクラス(例: SelfLogic)がLegacyモジュールにあるとする
• Domainモジュールに利用したい機能のインタフェースを定義したプロトコル(例: SeflLogicAdapter)を作成する • SelfLogicをSelfLogicAdapterに準拠させる • DIコンテナがPresentationモジュールのクラスにSelfLogicをインジェクトする
02 Adapterパターンを使った古いコードの利用方法 ©NewsPicks Inc. All Rights Reserved. // MARK: -
Domainモジュール protocol SelfLogicAdapter { func someLogic() } // MARK: - Legacyモジュール class SelfLogic { func someLogic() {...} } // SelfLogicAdapterに準拠させる extension SelfLogic: SelfLogicAdapter {} // MARK: - Presentationモジュール class NewsFeedresenter { private let selfLogic: SelfLogicAdapter init(selfLogic: SelfLogicAdapter) { // 実体はSelfLogicインスタンス self.selfLogic = selfLogic } } • インジェクションをどうやるかはプロ ジェクトによって異なる
02 The Composable ArchitectureでのDIの例 ©NewsPicks Inc. All Rights Reserved. //
MARK: - Domainモジュール public enum SelfLogicAdapterKey: TestDependencyKey { public static let testValue: SelfLogicAdapter = MockSelfLogic() public static let previewValue: SelfLogicAdapter = MockSelfLogic() } public extension DependencyValues { var selfLogic: SelfLogicAdapter { get { self[SelfLogicAdapterKey.self] } set { self[SelfLogicAdapterKey.self] = newValue } } } // MARK: - Legacyモジュール extension SelfLogicAdapterKey: DependencyKey { public static let liveValue: SelfLogicAdapter = SelfLogic.shared } // MARK: - Presentationモジュール struct NewsFeedReducer: ReducerProtocol { @Dependency(\.selfLogic) var selfLogic func reduce(into state: inout State, action: Action) -> EffectTask<Action> { ... selfLogic.someLogic() } } • DependencyValuesを使ってReducerに SelfLogicをインジェクトしている
©NewsPicks Inc. All Rights Reserved. 02 ユニットテストの 実装を強制する
02 ユニットテストの実装を強制している例 ©NewsPicks Inc. All Rights Reserved. • 例えば、変更したファイルのカバレッジが ◦%以下ならPRをマージできないようにして
しまう
02 なぜユニットテストの実装を強制するのか? ©NewsPicks Inc. All Rights Reserved. • ユニットテストを実装するためには、テスタブルな設計にしなければならない。その結 果、ロジックがシンプルで、可読性が高くなりやすい
◦ 何でも屋クラスや、複雑過ぎるメソッドが作られづらくなる(負債化しにくくな る) • ユニットテストの実装がしづらいと感じたら、プロダクションコードを見直すことにな り、より良い設計にしようという意識が働く ◦ どうすれば良い設計になるかをチームで議論する機会が明らかに増えた • ユニットテストがあると、リファクタしやすくなる ◦ 負債を継続的に返済していくための環境ができる 負債が生まれにくく、かつ生まれても返済可能な状態を維持できる!
02 ユニットテストはバランスが大事 ©NewsPicks Inc. All Rights Reserved. • マルチモジュール化して依存の方向を強制したり、テスタブルにした結果、テストする までもないシンプルなコードが多くなった
◦ ロジックがほとんどないシンプルなコード、変わることがほとんどないコードにつ いては、テストを書いてもコスパが悪い • 比較的変更の多いプレゼンテーションロジックを中心にテストを書くのが良い
©NewsPicks Inc. All Rights Reserved. 03 さいごに
03 新しく作ったコードもすぐに負債になり得る ©NewsPicks Inc. All Rights Reserved. • 新しく作ったコードが完璧なものとは限らない •
設計に不備があったり、納期を優先しなければならない状況は常に発生する 技術的負債を返済可能な状態を維持していることが重要! 技術的負債解消プロジェクトを何度もやることにならないように 最初にしっかり準備をしよう!
03 偉人の金言 ©NewsPicks Inc. All Rights Reserved. 自信過剰による再設計は、元のプロジェクトと同じように崩壊する 速く進む唯一の方法は、うまく進むことである Clean
Architecture 達人に学ぶソフトウェアの構造と設計 より
©NewsPicks Inc. All Rights Reserved. Thank you!!