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
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Suyeol Jeon
December 05, 2019
Programming
2.6k
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
레거시 프로젝트에서 의존성 주입하기
왜 개념만 알려주고 적용 방법은 아무도 알려주지 않는가
Suyeol Jeon
December 05, 2019
More Decks by Suyeol Jeon
See All by Suyeol Jeon
성장하는 iOS 개발자 되기
devxoul
2
260
Let's TDD
devxoul
0
110
Hello, ReactorKit 👋
devxoul
0
120
Build Funnels with Google BigQuery
devxoul
0
63
RxSwift 시작하기
devxoul
1
370
ReactorKit으로 단방향 반응형 앱 만들기
devxoul
0
190
Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기
devxoul
10
3.3k
좋은 디자이너, 나쁜 프로젝트매니저, 이상한 개발자
devxoul
0
130
Other Decks in Programming
See All in Programming
信頼性について考えてみる(SRE NEXT 2026 miniLT)
hayama17
0
230
PHPだって関数型したい 〜できること、できないこと〜 / fp-in-php
jsoizo
1
260
今さら聞けない .NET CLI
htkym
0
170
生成AIで帳票OCRが「簡単に」作れる時代になった?
kon_shou
0
210
jsmini JavaScript Engine を作ってみた話
yosuke_furukawa
PRO
0
280
Haskell/Servantを通してWebミドルウェアを捉え直す
pizzacat83
1
630
Go言語とトイモデルで学ぶTransformerの気持ち / fukuokago23-transformer
monochromegane
0
160
JAWS-UG横浜 #102 AWSサ終供養LT会 成仏できない AWS サービスたち 〜本日、三体供養します〜
maroon1st
0
290
全PRの83%がAIレビューだけでマージできるようになった開発組織はその後どうなったか
athug
0
1k
Prismを使った型安全な暗号化_関数型まつり2026
_fhhmm
0
160
アルゴリズムは何を圧縮しているのか ─ Haskell から育った「圧縮代数」というメンタルモデル
naoya
16
3.7k
5分で問診!Composer セキュリティ健康診断
codmoninc
0
770
Featured
See All Featured
The SEO Collaboration Effect
kristinabergwall1
1
510
Accessibility Awareness
sabderemane
1
170
A Tale of Four Properties
chriscoyier
163
24k
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2.3k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
130k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
21
1.6k
YesSQL, Process and Tooling at Scale
rocio
174
15k
The Impact of AI in SEO - AI Overviews June 2024 Edition
aleyda
5
1.1k
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
680
Fashionably flexible responsive web design (full day workshop)
malarkey
408
67k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.8k
How to train your dragon (web standard)
notwaldorf
97
6.7k
Transcript
ۨѢद ۽ંীࢲ ઓࢿ ੑೞӝ ࣻৌ
ۨѢद ۽ંীࢲ ઓࢿ ੑೞӝ ࣻৌ ࠗઁ: ৵ ѐ֛݅ ঌ۰Ҋ ਊ
ߑߨ ইޖب ঌ۰ ঋחо
పझח য۵
పझח য۵ పझೞӝ જѱ ৈ ঋ
పझח য۵ పझೞӝ જѱ ৈ ঋ Coupling ъೞ
func fetchUser() -> Single<User> { }
func fetchUser() -> Single<User> { return Networking.shared.get("/user/1") }
✅ పझ ాҗ func fetchUser() -> Single<User> { return Networking.shared.get("/user/1")
}
✅ పझ ాҗ ⛔ పझ पಁ func fetchUser() -> Single<User>
{ return Networking.shared.get("/user/1") }
func fetchUser() -> Single<User> { return Networking.shared.get("/user/1") } ✅ పझ
ాҗ ⛔ పझ पಁ
func fetchUser() -> Single<User> { return Networking.shared.get("/user/1") } ✅ పझ
ాҗ ⛔ పझ पಁ
func fetchUser() -> Single<User> { return Networking.shared.get("/user/1") } ъೠ ઓ
func fetchUser() -> Single<User> { return Networking.shared.get("/user/1") } ъೠ ઓ
ডೠ ઓ
func fetchUser() -> Single<User> { return Networking.shared.get("/user/1") } ъೠ ઓ
ডೠ ઓ Networking Production
func fetchUser() -> Single<User> { return Networking.shared.get("/user/1") } ъೠ ઓ
ডೠ ઓ Networking NetworkingStub Production Testing
func fetchUser() -> Single<User> { return self.networking.get("/user/1") } ъೠ ઓ
ডೠ ઓ Networking NetworkingStub Production Testing
func fetchUser() -> Single<User> { return self.networking.get("/user/1") } UserService(networking: Networking())
func fetchUser() -> Single<User> { return self.networking.get("/user/1") } UserService(networking: Networking())
UserService(networking: NetworkingStub())
UserService(networking: Networking()) UserService(networking: NetworkingStub())
UserService(networking: Networking()) UserService(networking: NetworkingStub()) ب ফ֎ܳ য٣ࢲ ࢤࢿ೧ਃ?
Composition Root
Composition Root ઓࢿ Ӓېо ٜ݅যח Ҕ
Composition Root ઓࢿ Ӓېо ٜ݅যח Ҕ ۽Ӓ۔ ੑ
Composition Root ઓࢿ Ӓېо ٜ݅যח Ҕ ۽Ӓ۔ ੑ (=AppDelegate)
User Repo List Repo Detail
User Repo List Repo Detail
User Repo List Repo Detail UserService RepoService
User Repo List Repo Detail UserService RepoService Networking Networking
AppDelegate UIWindow ListVC DetailVC UserService RepoService Networking Module Module
AppDelegate UIWindow ListVC DetailVC UserService RepoService Networking Module Module
AppDelegate UIWindow ListVC DetailVC UserService RepoService Networking Module Module Composition
Root ীࢲ ࢤࢿ
AppDelegate UIWindow ListVC DetailVC UserService RepoService Networking Module Module AppDependency
struct AppDependency { let window: UIWindow } CompositionRoot
struct AppDependency { let window: UIWindow } extension AppDependency {
} CompositionRoot
struct AppDependency { let window: UIWindow } extension AppDependency {
static func resolve() -> AppDependency { } } CompositionRoot
struct AppDependency { let window: UIWindow } extension AppDependency {
static func resolve() -> AppDependency { return AppDependency( ) } } CompositionRoot
struct AppDependency { let window: UIWindow } extension AppDependency {
static func resolve() -> AppDependency { return AppDependency( window: ... ) } } CompositionRoot
struct AppDependency { let window: UIWindow } extension AppDependency {
} CompositionRoot static func resolve() -> AppDependency { return AppDependency( window: ... ) }
let window = UIWindow() return AppDependency( window: window )
let window = UIWindow() window.rootViewController = ... return AppDependency( window:
window )
let networking = Networking() let window = UIWindow() window.rootViewController =
ListVC( userService: UserService( networking: networking ), detailVCFactory: { DetailVC( repoService: RepoService( networking: networking ) ) } ) return AppDependency( window: window )
let networking = Networking() let window = UIWindow() window.rootViewController =
ListVC( userService: UserService( networking: networking ), detailVCFactory: { DetailVC( repoService: RepoService( networking: networking ) ) } ) return AppDependency( window: window )
let networking = Networking() let window = UIWindow() window.rootViewController =
ListVC( userService: UserService( networking: networking ), detailVCFactory: { DetailVC( repoService: RepoService( networking: networking ) ) } ) return AppDependency( window: window )
let networking = Networking() let window = UIWindow() window.rootViewController =
ListVC( userService: UserService( networking: networking ), detailVCFactory: { DetailVC( repoService: RepoService( networking: networking ) ) } ) return AppDependency( window: window )
let networking = Networking() let window = UIWindow() window.rootViewController =
ListVC( userService: UserService( networking: networking ), detailVCFactory: { DetailVC( repoService: RepoService( networking: networking ) ) } ) return AppDependency( window: window )
let networking = Networking() let window = UIWindow() window.rootViewController =
ListVC( userService: UserService( networking: networking ), detailVCFactory: { DetailVC( repoService: RepoService( networking: networking ) ) } ) return AppDependency( window: window )
let networking = Networking() let window = UIWindow() window.rootViewController =
ListVC( userService: UserService( networking: networking ), detailVCFactory: { DetailVC( repoService: RepoService( networking: networking ) ) } ) return AppDependency( window: window )
let networking = Networking() let window = UIWindow() window.rootViewController =
ListVC( userService: UserService( networking: networking ), detailVCFactory: { DetailVC( repoService: RepoService( networking: networking ) ) } ) return AppDependency( window: window )
AppDelegate AppDependency
class AppDelegate { var window: UIWindow? func application( _ application:
UIApplication, didFinishLaunchingWithOptions ... ) -> Bool { self.window = UIWindow(...) self.window?.makeKeyAndVisible() return true } }
class AppDelegate { let dependency: AppDependency var window: UIWindow? func
application( _ application: UIApplication, didFinishLaunchingWithOptions ... ) -> Bool { self.window = UIWindow(...) self.window?.makeKeyAndVisible() return true } }
class AppDelegate { let dependency: AppDependency var window: UIWindow? private
override init() { } func application( _ application: UIApplication, didFinishLaunchingWithOptions ... ) -> Bool { self.window = UIWindow(...) self.window?.makeKeyAndVisible() return true } }
class AppDelegate { let dependency: AppDependency var window: UIWindow? private
override init() { self.dependency = AppDependency.resolve() } func application( _ application: UIApplication, didFinishLaunchingWithOptions ... ) -> Bool { self.window = UIWindow(...) self.window?.makeKeyAndVisible() return true } }
class AppDelegate { let dependency: AppDependency var window: UIWindow? private
override init() { self.dependency = AppDependency.resolve() } func application( _ application: UIApplication, didFinishLaunchingWithOptions ... ) -> Bool { self.window = self.dependency.window self.window?.makeKeyAndVisible() return true } }
Composition Rootо పझ ജ҃ীࢲ प೯غ ঋب۾
Composition Rootо పझ ജ҃ীࢲ प೯غ ঋب۾ UIApplicationMain( CommandLine.argc, CommandLine.unsafeArgv, NSStringFromClass(UIApplication.self),
NSStringFromClass(NSClassFromString("MyTests.TestAppDelegate") ?? AppDelegate.self) )
Composition Rootо పझ ജ҃ীࢲ प೯غ ঋب۾ UIApplicationMain( CommandLine.argc, CommandLine.unsafeArgv, NSStringFromClass(UIApplication.self),
NSStringFromClass(NSClassFromString("MyTests.TestAppDelegate") ?? AppDelegate.self) ) https://github.com/devxoul/Pure
Composition Rootח పझ ജ҃ীࢲ प೯غݶ উػ
Composition Rootח పझ ജ҃ীࢲ प೯غݶ উػ ࢤࢿ ഐ ৻ ٘ח
ઁ
ۿ જ݅ അप ޙઁ
ۿ જ݅ അप ޙઁ ઓࢿ Ӓېী ࣘೞ ޅೠ
AppDelegate UIWindow ListVC DetailVC UserService RepoService Networking Module Module
AppDelegate UIWindow ListVC DetailVC UserService RepoService Networking Module Module
AppDelegate UIWindow ListVC DetailVC UserService RepoService Networking Module Module
ઓࢿ Ӓېী ࣘೞ ޅೠ
ઓࢿ Ӓېী ࣘೞ ޅೠ. ৵?
ઓࢿ Ӓېী ࣘೞ ޅೠ. ৵? 1. ੋఠಕझী ઓೠ
ઓࢿ Ӓېী ࣘೞ ޅೠ. ৵? 1. ੋఠಕझী ઓೠ UserService.shared.fetchUser()
ઓࢿ Ӓېী ࣘೞ ޅೠ. ৵? 1. ੋఠಕझী ઓೠ 2.
ੋझఢझܳ ࢤࢿೠ UserService.shared.fetchUser()
ઓࢿ Ӓېী ࣘೞ ޅೠ. ৵? 1. ੋఠಕझী ઓೠ 2.
ੋझఢझܳ ࢤࢿೠ let detailVC = DetailVC() UserService.shared.fetchUser()
ೞաঀ ೧Ѿ೧ ࠇद.
Ҿӓ ݾ
Ҿӓ ݾ ݽٚ ېझо ઓࢿ Ӓېী ࣘೞѱ ػ
AppDelegate UIWindow ListVC DetailVC UserService RepoService Networking Module Module
Ҿӓ ݾ ݽٚ ېझо ઓࢿ Ӓېী ࣘೞѱ ػ അप ݾ
Ҿӓ ݾ ݽٚ ېझо ઓࢿ Ӓېী ࣘೞѱ ػ അप ݾ
যઁࠁ ؊ ա ٘ܳ ࢿೠ
AppDelegate UIWindow ListVC DetailVC UserService RepoService Networking Module Module যઁ
AppDelegate UIWindow ListVC DetailVC UserService RepoService Networking Module Module য়ט
AppDelegate UIWindow ListVC DetailVC UserService RepoService Networking Module Module ղੌ
AppDelegate UIWindow ListVC DetailVC UserService RepoService Networking Module Module ղੌ+1
AppDelegate UIWindow ListVC DetailVC UserService RepoService Networking Module Module ղੌ+2
AppDelegate UIWindow ListVC DetailVC UserService RepoService Networking Module Module ղੌ+3
1. ੋఠಕझী ઓೠ 2. ੋझఢझܳ ࢤࢿೠ let detailVC
= DetailVC() UserService.shared.fetchUser() ઓࢿ Ӓېী ࣘೞ ޅೠ. ৵?
1. ੋఠಕझী ઓೠ UserService.shared.fetchUser()
1. ੋఠಕझী ઓೠ ࢤࢿ۽ ׳߉ח UserService.shared.fetchUser()
1. ੋఠಕझী ઓೠ ࢤࢿ۽ ׳߉ח UserService.shared.fetchUser() init(userService: UserService)
1. ੋఠಕझী ઓೠ ࢤࢿ۽ ׳߉ח UserService.shared.fetchUser() init(userService: UserService) self.userService.fetchUser()
۽షਃ? рചחਃ??
അप ݾ যઁࠁ ؊ ա ٘ܳ ࢿೠ
അप ݾ যઁࠁ ؊ ա ٘ܳ ࢿೠ যب ৻ࠗীࢲ ੑೡ
ࣻ ѱ غ
അप ݾ যઁࠁ ؊ ա ٘ܳ ࢿೠ যب ৻ࠗীࢲ ੑೡ
ࣻ ѱ غ ਃ೧ ٸ ۽షਸ ٜ݅
1.1 ੋఠಕझী बпೞѱ ઓೠ UserService.shared.fetchUser()
1.1 ੋఠಕझী बпೞѱ ઓೠ UserService.shared.fetchUser()
1.1 ੋఠಕझী बпೞѱ ઓೠ UserService.fetchUser()
1.1 ੋఠಕझী बпೞѱ ઓೠ ࢤࢿ۽ ఋੑਸ ׳߉ח UserService.fetchUser()
1.1 ੋఠಕझী बпೞѱ ઓೠ ࢤࢿ۽ ఋੑਸ ׳߉ח UserService.fetchUser() init(userServiceType:
UserService.Type)
1.1 ੋఠಕझী बпೞѱ ઓೠ ࢤࢿ۽ ఋੑਸ ׳߉ח UserService.fetchUser() init(userServiceType:
UserService.Type) self.userServiceType.fetchUser()
2. ੋझఢझܳ ࢤࢿೠ let detailVC = DetailVC()
2. ੋझఢझܳ ࢤࢿೠ let detailVC = DetailVC() ࢤࢿ۽ ಂషܻܳ
׳߉ח
2. ੋझఢझܳ ࢤࢿೠ let detailVC = DetailVC() ࢤࢿ۽ ಂషܻܳ
׳߉ח init(detailVCFactory: () -> DetailVC)
2. ੋझఢझܳ ࢤࢿೠ let detailVC = DetailVC() ࢤࢿ۽ ಂషܻܳ
׳߉ח init(detailVCFactory: () -> DetailVC) let detailVC = self.detailVCFactory()
ࠂೠ ۽о դޖೞ ঋਸөਃ??
അप ݾ যઁࠁ ؊ ա ٘ܳ ࢿೠ
അप ݾ যઁࠁ ؊ ա ٘ܳ ࢿೠ যب ৻ࠗীࢲ ੑೡ
ࣻ ѱ غ
അप ݾ যઁࠁ ؊ ա ٘ܳ ࢿೠ যب ৻ࠗীࢲ ੑೡ
ࣻ ѱ غ ࠂ೧ݶ Factory ఋੑਸ ೞ
ف ೧Ѿ ߑߨ ҕా
ف ೧Ѿ ߑߨ ҕా ઓࢿ ৻ࠗী ਤೠ. init(userService: UserService) init(detailVCFactory:
() -> DetailVC)
ف ೧Ѿ ߑߨ ҕా ઓࢿ ৻ࠗী ਤೠ. ਃী ٮۄ ਗೞח
ѐܳ ੑೡ ࣻ . ListVC(detailVCFactory: { DetailVCMock() }) UserVC(userService: UserServiceMock())
ઁ ઓࢿ Ӓېী ࣘೞѱ ٜ݅
ઁ ઓࢿ Ӓېী ࣘೞѱ ٜ݅ Rootীࢲ оө ࣽࢲ۽
AppDelegate UIWindow ListVC DetailVC UserService RepoService Networking Module Module য়ט
AppDelegate UIWindow ListVC DetailVC UserService RepoService Networking Module Module ղੌ
AppDelegate UIWindow ListVC DetailVC UserService RepoService Networking Module Module ղੌ+1
AppDelegate UIWindow ListVC DetailVC UserService RepoService Networking Module Module ղੌ+2
AppDelegate UIWindow ListVC DetailVC UserService RepoService Networking Module Module ղੌ+3
window.rootViewController = ListVC( ) য়ט
window.rootViewController = ListVC( userService: UserService( ) ) ղੌ
window.rootViewController = ListVC( userService: UserService( networking: networking ) ) ղੌ+1
window.rootViewController = ListVC( userService: UserService( networking: networking ), detailVCFactory: {
DetailVC( ) } ) ղੌ+2
window.rootViewController = ListVC( userService: UserService( networking: networking ), detailVCFactory: {
DetailVC( repoService: RepoService( ) ) } ) ղੌ+3
window.rootViewController = ListVC( userService: UserService( networking: networking ), detailVCFactory: {
DetailVC( repoService: RepoService( networking: networking ) ) } ) ղੌ+4
AppDelegate UIWindow ListVC DetailVC UserService RepoService Networking Module Module
పझ ജ҃ীࢲ AppDelegateо प೯ظਃ DetailVCী ۄఠܳ ֈӝҊ रযਃ ಂషܻ ۽о
ցޖ ࠂ೧ઉਃ
Pure https://github.com/devxoul/Pure