๐คฏ ์๋๋ก์ด๋ ๊ฐ๋ฐ์ ์ถฉ๊ฒฉ! iOS TCA ์ดํด๋ณด๊ธฐ. ์ด ๋ฐฉ์์ด ๋ง๋๊ฑธ๊น? ๐คฏ
๊ฐ์ธ ๊ด๊ณ ์์ญ
์ด ๊ธ์ Android ๊ฐ๋ฐ์์ธ ํ์๊ฐ TCA ์ผ๋ถ๋ฅผ ์ฌ์ฉํด ๋ณด๊ณ ๊ฒฝํํ ๋ด์ฉ์ ๋ฐํ์ผ๋ก ์ ๋ฆฌํ์๊ณ , ์ด ๋ฐฉ์์ด ๋ง๋ ๊ฒ์ผ๊น์ ๋ด์ฉ์ ํฌํจํ๋ค.
์ค๋ฅ๊ฐ ์์ ์ ์์ผ๋ ์ค๋ฅ๊ฐ ์๋ค๋ฉด ์ ๊ทน ์๋ ค์ฃผ๋ฉด ์ข๊ฒ ๋ค.
TCA๋ iOS์์ ์์ฆ ๋ง์ด ํ์ฉํ๊ณ ์๋ The Composable Architecture์ด๋ค.
TCA๋ ๋ค์์ ๊ธฐ์ค์ผ๋ก ํ๋ค.
- State management
- Composition
- Side effects
- Testing
- Ergonomics
ํ์ง๋ง ์ค์ ์ฌ์ฉํด ๋ณด๋ฉด ๋ฆฌ๋์ค๋ผ๊ณ ๋ณด๋ ๊ฒ์ด ๋ง๋ค. ์น์์๋ ๋ฆฌ๋์ค๊ฐ ๋๋ฌด ๋ณต์กํ๊ธฐ ๋๋ฌธ์ ์ฌ์ฉํ์ง ์๋ ๊ฑธ๋ก ๋ค์๋ค.
์ค์ TCA๋ ๋งค์ฐ ๋ณต์กํ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง๊ณ ์์ง๋ง swiftUi์ ํจ๊ป ์ฌ์ฉํ๊ธฐ์๋ ์ข๋ค๊ณ ํ๋ค.
์ด ๊ธ์์๋ ์๋๋ก์ด๋ ๊ฐ๋ฐ์๊ฐ ๊ฐ๋ณ๊ฒ TCA๋ฅผ ์ฌ์ฉํ๋ฉด์ ๊ฒฝํํ ๋ด์ฉ์ ์ ๋ฆฌํด ๋ณธ ๊ธ์ด๋ ์ฐธ๊ณ ๋ง ํ์๊ธธ.(์ค๋ฅ๋ ์ธ์ ๋ ๋๊ธ๋ก)
์ด ๊ธ์์๋
- ํ์๊ฐ ์๊ฐํ๋ Composable ๊ตฌ์กฐ๋?
- ๊ฐ๋จํ ์ํ ์ฝ๋๋ฅผ ํตํ ์์๋ณด๊ธฐ
ํ์๊ฐ ์๊ฐํ๋ ํธํ ๊ตฌ์กฐ
ํ์๋ ๊ฐ๋ฐํ๊ธฐ ํธํ ๋ฐฉ์์ ์ ํธํ๋ ํธ์ด๋ค.
๋ณธ ๋ธ๋ก๊ทธ์์๋ ์ฌ๋ฌ ๋ฒ ์ ์๋ ๋ด์ฉ์ด์ง๋ง ํ์์ ์ ํธ๋ ์๋์ ๊ฐ๋ค.
ํ๋ฉด์ ํน์ View๋ฅผ ๊ณตํตํํ๋ค๋ ๊ฐ์ ์ ํด๋ณด์.
ex) back ๋ฒํผ์ ์ด๋ ํ๋ฉด์์๋ ์ด์ ํ๋ฉด์ผ๋ก ๋์๊ฐ๋ ๊ณตํต์ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง๋ค.
- ์ฐธ๊ณ : ์ฌ๊ธฐ์ back ๋ฒํผ์ ์ค๋ช ํ๋ ์ด์ ๋ ๋๊ฐ ๋ณด์๋ ๊ฐ์ฅ ๊ณตํตํ ์ํค๊ธฐ ์ฌ์ด ๊ตฌ์กฐ๋ผ ์๊ฐํ์ฌ ์ ํํ์๋ค.
๋จ,
- Back ๋ฒํผ์ ๋ฐ์ดํฐ๋ฅผ ๋ก๋ฉ๊ณผ ๋ฌด๊ดํ๊ฒ Back๋ง ์ฒ๋ฆฌํ ์ ์์ด์ผ ํ๋ค.
- Back ์ด๋ฒคํธ ์์๋ ์ด์ ํ๋ฉด์ผ๋ก์ ์ด๋์ ํ๊ฑฐ๋, ์ํฉ์ ๋ฐ๋ผ alert ์ ์ง๋ฌธ์ ๋ฐ๊ณ ์ข ๋ฃํ๊ธฐ๋ ํ๋ค.
์์ ๊ฐ์ ๋จ์๋ ๋ฌ์๋ณด์๋ค.
๊ทธ๋ ๋ค๋ฉด ํ์๊ฐ ์๊ฐํ๋ ๊ตฌ์กฐ๋ ์๋์ ๊ฐ์ด ์์ฑํด ๋ณผ ์ ์๋ค.
- View์๋ Back ๋ฒํผ ๋ง์ ํฌํจํ๋ Composable ํจ์๋ฅผ ์์ฑํ๋ค.
- View์ ๋ํ ๋ก์ง์ ์ฒ๋ฆฌํ๋ ๊ณณ์์ ์ด๋ฒคํธ๋ฅผ ์ ๋ฌ๋ฐ๋๋ค.
- router๋ฅผ ํตํด ์ด์ ํ๋ฉด์ผ๋ก ์ด๋ํ๋ผ๋ ์ฒ๋ฆฌ๊ฐ ์ผ์ด๋๋ค.
- ์ฌ๊ธฐ์ ์ด์ ์ด๋ผ๋ ๊ฐ๋ ์ ๋ค๋น๊ฒ์ด์
- ๋ค๋น๊ฒ์ด์ ์ ์ฃผ์ ํด๋ ์ ๋ณด์ ๋ฐ๋ผ Back์ ์ฒ๋ฆฌํ๋ค.
์ด๋ฌ๋ฉด ๊ณตํต์ View๊ฐ ํ๋ ๋์๋ค. ๋๊ตฌ๋ ์ข์ํ๋ ์ํคํ ์ฒ ๊ตฌ์กฐ๋ ๋ฐ๋๊ณ , View๋ง์ ์ค์ค๋ก ์ฒ๋ฆฌํ ์ ์๋๋ก ์ฒ๋ฆฌํ๋ค.
์ฌ๊ธฐ์ ๋๋ ์๋ฌธ์ ?
back์ ํ๋๋ฐ ์ด ์ด๋ฒคํธ๋ ๋๊ฐ ๋ฐ์์ ์ฒ๋ฆฌํ๋๊ฐ? ์ค์ค๋ก ์ฒ๋ฆฌํ๋ค๊ณ ํ์๋ค. ํ์ง๋ง ์ ๊ทธ๋ด ๊ฒฝ์ฐ๋ ์๋ค. ์ฌ๊ธฐ์๋ ์ด๋ฐ ๋ถ๋ถ์ ๋ํ ๊ณ ๋ฏผ์ ์ ๋ ๊ฒ์ ์๋๋ค. TCA์์๋ upstream ๋ฐฉ์์ผ๋ก ์ด๋ฌํ ์ด๋ฒคํธ๋ฅผ ์์์ ์ฐ๊ฒฐํ์ฌ ์ฒ๋ฆฌํ๋ค.
๋จ ๊ทธ ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํ์ง ์์ผ๋ฉด ์๋ฌด๋ฐ ๋์๋ ์ผ์ด๋์ง ์๋๋ค๋ ์ ์ด๋ค.
๋์์์
๊ณตํต์ View๋ ์ด๋ค Screen์ด ๋ ์ด๋์ ์์นํ๋ Back ๋ฒํผ์ ์ญํ ์ ํ ์ ์๋ ์ด๋๋ ๋ถ์ฐฉ๋์ด ๋์ํ ์ ์๋ค.
๋จ, ํ์ํ ๊ฒฝ์ฐ ๋ค์์ ์ฒ๋ฆฌํ ์ ์๋ ๋ก์ง ํ๋ฆ์ ์ฒ๋ฆฌํด ์ค์ผ ํ์ง๋ง ์ด๊ฑด ์ต์ ์ด๋ฉฐ, View๋ง ์ฐ๊ฒฐํ๋ค.
Composableํจ์() {
HStack/Column {
BackButton() // << ์ด ๋ฒํผ์์ ์์์ ๋์ํ๋ค.
}
}
TCA์์๋?
TCA๋ ์ ์ฌํ๊ฒ ๋ง๋ค ์ ์๋ค. ํ์ง๋ง ๋ค์์ ๊ณผ์ ์ ๊ฑฐ์ณ์ผ ํ๋๋ฐ, ๋๋ฌด ์ฌ์ด ๋ถ๋ถ๋ง์ ๊ฐ์ ธ์์ ์ค๋ช ํ๋ค ๋ณด๋ ์ค๋ช ์ด ๋ถ์กฑํ ์ ์์ผ๋ฉฐ, ์ํ ์ฝ๋๋ ๋จ์ ์ฐธ๊ณ ํด ์ฃผ์๊ธธ
public struct BackButtonCellView: View {
public var store: StoreOf<BackButtonCell>
public init(store: StoreOf<BackButtonCell>) {
self.store = store
}
public var body: some View {
BackButton() // View
.onTapGesture {
viewStore.send(.back)
}
}
}
Reducer๋ฅผ ๊ตฌ์ฑํ๋ค. ์ฌ๊ธฐ์๋ State, Action์ ํฌํจํด์ผ ํ๋ค.
์ด Reducer๋ ํ๋ฉด์ ๋น์ฆ๋์ค ์ฒ๋ฆฌ์ ๋์์ ์ฒ๋ฆฌํ๊ธฐ ์ํจ์ด๋ค.
public struct BackButtonCell: Reducer {
public struct State: Equatable {
public init() {
// do nothing
}
}
public enum Action: Equatable, ErrorAction {
public enum Delegate: Equatable { // ์์๋ก ์ ๋ฌํ event
case back
}
case back // ํ์ฌ View์ ๋ํ ์ด๋ฒคํธ
}
public init() {}
public var body: some ReducerOf<Self> {
self.core
}
// ์์์ ์ ์ํ event์ ๋ํ ๋์ ์ ์
@ReducerBuilder<State, Action>
var core: some ReducerOf<Self> {
Reduce { state, action in
switch action {
case .back:
return .run { send in
await send(.delegate(.back))
}
case // ์ฌ๊ธฐ์์ ์ฌ์ฉํ์ง ์์ ์ด๋ฒคํธ๋ค์ ์ฌ๊ธฐ์ ๋ชจ๋ ํฌํจ
.delegate:
return .none
}
}
}
}
์ฌ๊ธฐ๊น์ง๋ ๊ณตํต์ View๋ฅผ ๋ง๋ค์๋ค. Android์์ Compose๋ฅผ ํ์ฉํ ์ด๋ฒคํธ ์ ์์ ์ ์ฌํ๋ค.
์ ์ฉํด ๋ณด์
Android์์๋ ์ด๋ป๊ฒ ๊ตฌ์ฑํ์๋์ง์ ๋ฐ๋ผ ๋ค๋ฅด๊ฒ ์ง๋ง TCA์์๋ ์ด๋ฅผ ์ ์ฉํ๋ ค๋ฉด ์ ์ฉํ View/Reducer์ ์ฝ๋๋ฅผ ๊ฐ๊ฐ ์ ์ํด์ผ ํ๋ค.
๋จผ์ ํฌํจํ View์๋ ๋ค์๊ณผ ๊ฐ๋ค.
IfLetStore(
self.store.scope(
state: \.backButtonCell,
action: Some.Action.backButtonCell
),
then: BackButtonCellView.init(store:)
)
Reducer์์๋ ์๋์ ๊ฐ์ด ํฌํจํ๋ค.
public struct Some: Reducer {
public struct State: Equatable {
var backButtonCell: BackButtonCell.State? // ์ฌ์ฉํ State ์ ์
public init() {
self.backButtonCell = .init() // ๊ฐ์ฒด ์์ฑ
}
}
public enum Action: Equatable { // Action ์ ์
case backButtonCell(BackButtonCell.Action)
}
// Cell ๊ฐ์ฒด ์์ฑ
public var body: some ReducerOf<Self> {
self.core
.ifLet(
\State.backButtonCell,
action: /Action.backButtonCell
) {
BackButtonCell()
}
}
// ์์์ ์ ์ํ event์ ๋ํ ๋์ ์ ์
@ReducerBuilder<State, Action>
var core: some ReducerOf<Self> {
Reduce { state, action in
switch action {
case .backButtonCell(.back): // ๋ฐ์ ์ด๋ฒคํธ์ ๋ํ ์ฒ๋ฆฌ
return .none
case .backButtonCell: // ๋๋จธ์ง ๋ชจ๋ ์ด๋ฒคํธ๋ ์์๋ก ๋ณด๋ธ๋ค.
return .none
}
}
}
}
๋ง์ฝ ์ ์ด๋ฒคํธ๋ฅผ ํด๋น View์์ ํ์ฉํ์ง ์๋๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ด ReducerBuilder
์ ์๋ฅผ ์์ ํ๋ค.
// ์์์ ์ ์ํ event์ ๋ํ ๋์ ์ ์
@ReducerBuilder<State, Action>
var core: some ReducerOf<Self> {
Reduce { state, action in
switch action {
case .backButtonCell: // backButtonCell์ ๋ํ ๋ชจ๋ ์ด๋ฒคํธ return.
return .none
}
}
}
๊ฐ๋จํ๊ฒ ์์ฑํ ์ฝ๋๋ผ์ ์ดํด๊ฐ ์ด๋ ต์ง ์์ ๊ฒ ๊ฐ๋ค.
์ด๋ฒคํธ์ ํ๋ฆ
์์ ์์ฑํ ํ์๊ฐ ์๊ฐํ๋ ์๋๋ก์ด๋์์์ Composable์ ๋ํ ๋ฐ์ดํฐ ํ๋ฆ์ ๋ค์๊ณผ ๊ฐ๋ค.
- Back ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ค.
- Back์ ๋ํ ๋น์ฆ๋์ค ๋ก์ง์์ ์ค์ค๋ก router ์ฒ๋ฆฌํ๋ค.
- ํ์ํ๋ค๋ฉด ์์๋ก ์ ๋ฌํ์ฌ ์ฒ๋ฆฌํ๋ค.
์ด์ง๋ง ํต์ฌ์, View๋ง ๊ฐ์ ธ๋ค ์ฌ์ฉํ ์ ์๋๊ฐ์ด๋ค.
fun SomeScreen() {
BackButton() // ์ด๋ ๊ฒ๋ง ํ ์ ์๋๊ฐ?
}
ํ์ง๋ง TCA๋ view์ reducer๋ฅผ ๊ตฌ์ฑํด์ผ ํ๊ณ , ์ด ์ด๋ฒคํธ๋ฅผ ํ์ฉํ๊ธฐ ์ํ ๋ณด์ผ๋ฌ ํ๋ ์ดํธ ์ฝ๋๊ฐ ์๋ฉ ๋ค์ด๊ฐ์ผ ํ๋ค.
ํน์ดํ๊ฒ๋ upstream ์ด๋ฒคํธ๋ A/B/C/D๋ผ๋ ์์๋๋ก ํ๋ฉด์ด ์ด๋ ธ๊ณ , D์์ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด A/B/C ๋ชจ๋๊ฐ ์ด ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํ ์ ์๋ค. ๊ทธ ๋ง์ .backButtonCell ์ด๋ฒคํธ๋ฅผ ๋ชจ๋๊ฐ ๋ฐ์ ์ ์๋ค๋ ๋ง์ด๋ฉฐ, ๋ถ๋ฆฌ๋ ๊ฐ๋ฅํ๋ค.
์ด๋ป๊ฒ ๋ณด๋ฉด ์ฅ์ ์ด์ง๋ง ์ด ๋ฐ์ดํฐ ํ๋ฆ์ ์๊ฐ ์์ด ์ธ ์ ์๋ค๋ ์ด์ผ๊ธฐ๋ค.
๊ทธ๋ผ ๊ทธ๋งํผ ๋ณต์ก๋ ์ญ์ ๋งค์ฐ ๋์์ง ์ ์๋ค.
๋๊ตฌ๋ ์ดํดํ๊ธฐ ์ฌ์ด ํ๋ฆ์ด๋?
์ฌ๊ธฐ์ ํ ๋ฒ ๋ ์๊ฐํด ๋ณผ ๋ถ๋ถ์ ๋๊ตฌ๋ ์ดํดํ๊ธฐ ์ฌ์ด ๋ฐ์ดํฐ ํ๋ฆ์ ๋ง๋ค ์ ์๋๊ฐ์ด๋ค.
A unidirectional data flow(UDF), ๋จ๋ฐฉํฅ ๋ฐ์ดํฐ ํ๋ฆ์ ์ด์ผ๊ธฐํ ์ ์๋ค. TCA๊ฐ ์ข๊ธด ํ์ง๋ง UDF ์ ์ผ๋ก ๋ณธ๋ค๋ฉด ๋๋ฌด ์ด๋ ค์์ง๋ค๋ ๋จ์ ์ด๋ค. ์ด๋ฐ ์ด์ ๋ก ์น์์๋ ๋ฆฌ๋์ค๋ฅผ ์ฌ์ฉํ์ง ์๋ ๊ฑฐ ์๋๊น ์ถ๋ค.
๊ฐ๋ฐ ํธ์์ฑ ๋ง์ ๋ณธ๋ค๋ฉด ์์์ผ ํ ๊ฒ์ด ๋๋ฌด ๋ง๋ค.
์ด๋ฐ ์ํคํ ์ฒ๋ ์์์ผ ํ๊ณ , ๋ฐ์ดํฐ์ ํ๋ฆ๋ ์ดํดํด์ผ ํ๊ณ , ์ด ํ๋ฆ์ ๋์ด ์ด๋์ง๋ ์ฐพ์ผ๋ ค๋ฉด ํ๊ณ ํ๊ณ ์ด๊ฒ ์ด๋์์ ์ฒ๋ฆฌํ๊ณ ์๋๊ธธ๋ ์ ์ด๋ฐ ๋์์ ํ ๊ฒ์ธ๊ฐ?์ ๋ํ ๊ณ ๋ฏผ์ด ๋ง์์ง๋ค.
์ค๊ณ์ ์ธ ๊ด์ ์์ ์ฌ์ฌ์ฉ ๊ตฌ์กฐ๋ฅผ ์ต๋ํ ๋ง๋ค์ด์ฃผ๋ ๊ฒ์ด ๋น์ฐํ ์ข๋ค. ๊ทธ๋์ผ ๊ฐ๋ฐ์์ ํธํ๊ธฐ ๋๋ฌธ์.
์กฐ๋ฆฝ์ ์ง๋ ์ง์ด๊ธฐ ๋๋ฌธ์ ์กฐ๋ฆฝ์ ์ํ๋ ๊ฒ๋ ๋งค์ฐ ์ข์ ์ค๊ณ๋ค.
ํ์๋ ์ด๋ค ์ํคํ ์ฒ๋ ์ ๋ง๋ค์ด๋ด์ผ ํฉํ ๋ฆฌ ํจํด์ด๋ผ๊ณ ์๊ฐํ๋ค.
๊ทธ๋งํผ ํฉํ ๋ฆฌ์ฒ๋ผ ์ ๊ฐ์ ธ๋ค ํ์ฉํ ์ ์๋ ๊ตฌ์กฐ๋ฅผ ๋ง๋ค์ด์ผ ํ๋๋ฐ, TCA๋ ๋ณด์ผ๋ฌ ํ๋ ์ดํธ ์ฝ๋๊ฐ ๋๋ฌด ๋ง์ด ์๊ธด๋ค๋ ๋จ์ ์ด ์๋ค.
๊ฑฐ๊ธฐ์ ์ ์คํธ๋ฆผ(event)/๋ค์ด ์คํธ๋ฆผ(data) ํ์ฉ์ ์ ์ ํ๊ฒ ๋ถ๋ฆฌํ์ง ์๋๋ค๋ฉด ์ฐ์ผ๋ก ๊ฐ ์ ์๋ค.
์๋๋ก์ด๋์์ ํ์ฉํด ๋ณผ ๋ฒํ ๊ฒ์?
ํ์๋ MVI ํจํด์ ์ ํธํ์ง ์๋๋ค. ์ด์ฐจํผ ๋ฆฌ์ํธ์ด๊ณ , ๋ฆฌ์ํธ์ ๊ฐ๋ ๋ค์ ๊ฐ์ ธ์จ ๊ฒ์ด๋ค.
๋ง์ฝ MVI ํจํด์ Reducer๊น์ง ์ ์ ์ฉํ์๋ค๋ฉด MVI ๋ผ๊ธฐ๋ณด๋จ ๋ฆฌ์ํธ๋ฅผ ์ ์ ๋ฆฝํ ๊ฐ๋ ์ด๋ผ ์๊ฐํ๋ค.
ํ์ง๋ง ๋๋ถ๋ถ MVI ํจํด์ ์ฌ์ฉํ๋ค๊ณ ํ๋ฉด ๋๋ถ๋ถ ๋ค์ ์ ๋๊ฐ ์ ์ฉ๋์ด ์๋ค.
- Action๊ณผ State ์ ์ฉ
- UiState ์ ์ฉ
- Action view to event
์ด ๋ด์ฉ์ ๊ตฌ๊ธ ์๋๋ก์ด๋ ์ํคํ ์ฒ์ ํฌ๊ฒ ๋ค๋ฅด์ง ์๋ค.
์ฐจ๋ผ๋ฆฌ circuit ๊ณผ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํ์ฉํ๋ค๋ฉด Reducer ๊ฐ๋ ์ ์ฌ์ฉํ๋ ๊ฒ์ ์ถ์ฒํ๋ค. ์๋๋ฉด Flow๋ฅผ ํ์ฉํด Reducer ๊ฐ๋ ์ ์ถ๊ฐํ์ฌ๋ ์ข๋ค.
- SlackHQ - circuit - Link
- [Circuit] Circuit ์ฐ๋จน ํด๋ณด๊ธฐ(์ด์งํ๋ ์์ฑ) - Link
- [Circuit] rememberRetained, produceRetainedState ํจ์ ๋ถ์(1)(์ด์งํ๋ ์์ฑ) - Link
- [Circuit] rememberRetained, produceRetainedState ํจ์ ๋ถ์(2)(์ด์งํ๋ ์์ฑ) - Link
- [Circuit] collectAsRetainedState, rememberStableCoroutineScope ํจ์ ๋ถ์(์ด์งํ๋ ์์ฑ) - Link
๋ง๋ฌด๋ฆฌ
ํ์๋ ๊ฐ๋ฐ์ ์์ด์ ์ ์ฉ์ด ์ฝ๊ณ ๊ฐ๊ฒฐํ ๊ฑธ ์ ํธํ๋ ์ชฝ์ ์ ํํ๋ค. ๋ฌด์์ ๊ฐ๊ฒฐํ ๊ฒ์ด ์๋ ์ข ๋ ์ฝ๊ฒ ์ ์ฉํด ๋ณผ ๋ฒํ ๊ฒ์ ์ ํธํ๋ ๊ฒ์ด๋ค.
TCA๋ ์์ง ๊ทธ ์ ๋๋ ์๋๋ ์๊ฐ์ด ๋ ๋ค. ์น์์๋ ๋ฆฌ๋์ค๋ฅผ ๋ณดํต ์ฌ์ฉํ์ง ์๋๋ค๊ณ ํ๋๋ฐ, ๊ตฌ์กฐ ์์ฒด๊ฐ ๋๋ฌด ๋ณต์กํด์ง๋ ๊ฒฝํฅ์ด ๊ฐํด ๋ณด์ฌ์์ธ๋ฏํ๋ค.
๊ทธ๋ฆฌ๊ณ ์ด๋ฐ ์ด๋ฒคํธ ์ฒ๋ฆฌ์ ์์ด์ ๋ฑํ ์ฅ์ ์ด ๋ณด์ด์ง ์๋ ๊ฒ๋ ์ด์ ์ด๊ธฐ๋ ํ๋ฐ, delegate๋ฅผ ํตํด ์ด๋ฒคํธ๋ฅผ ๋ฐ์์ ์ฒ๋ฆฌํ ์ ์๋ ํธํจ์ ์์ง๋ง ์ด ์ด๋ฒคํธ ํต๋ก๋ ์ฑ์ ํ๋๋ผ๊ณ ์๊ฐํ๋ค๋ฉด, ์ค์๋ก ๊ตฌํํ์ง ์์ ์๋ ์๊ณ , ์ค์๋ก ๊ตฌํํ์ง ์์๋ ์ด์ํ๊ฒ ๋์ํ๊ฒ ๋๋ ์ผ์ด์ค๋ ๋ฐ๊ฒฌ๋ ๊ฐ๋ฅ์ฑ์ด ์ปค ๋ณด์ธ๋ค.
๊ทธ๋ผ ์ด๋ป๊ฒ ๋๋ฒ๊น ์ด ํธํ ๊น? EventBus์ ๋๋ฒ๊น ์ด ์ด๋ ค์ ๋ ๊ฒ์ฒ๋ผ TCA ์ญ์ ๋น์ทํ ๋๋์ ๋ฐ์๋ค.
๊ทธ๋ ๋ค๊ณ ํด๋ ์ฌ๋ฏธ์๋ ์ํคํ ์ฒ์์ ํ๋ฆผ์๊ณ , UDF๋ฅผ ์ ๊ตฌ์ฑํ์ฌ ๊ณ ๋ฏผํด ๋ณธ๋ค๋ฉด ์ถฉ๋ถํ ์ข์? ์ํคํ ์ฒ๋ผ๊ณ ์๊ฐํ๋ค.
์๊ฐ๋ณด๋ค ๋งค์ฐ ์ฌ๋ฏธ์์๊ธฐ์ ์ด๋ฐ ๊ธ๋ ์์ฑํด ๋ณธ๋ค.
Comments