Skip to content
dahun-lee-daji edited this page Jul 13, 2022 · 3 revisions

작성 중...

@startuml
' STYLE START
hide empty members
skinparam shadowing false
' STYLE END


class "NetworkService" as NetworkService << (P, GoldenRod) protocol >> { 
  ~request(with:)
  ~request(with:) 
}
class "DefaultNetworkService" as DefaultNetworkService << (C, DarkSeaGreen) >> { 
  ~networkRequester : NetworkRequesting
  ~init(requester:)
  ~request(with:)
  ~request(with:) 
}
class "NetworkRequesting" as NetworkRequesting << (P, GoldenRod) protocol >> { 
  ~get(url:session:)
  ~getWithoutDecode(url:session:) 
}
class "DefaultNetworkRequester" as DefaultNetworkRequester << (C, DarkSeaGreen) >> { 
  ~get(url:session:)
  ~getWithoutDecode(url:session:) 
}
class "EndPoint" as EndPoint << (S, SkyBlue) struct >> { 
  ~scheme : String
  ~host : String
  ~path : String
  ~method : HTTPMethod
  ~init(scheme:host:apiPath:httpMethod:)
  ~asURL() 
}
class "AppFlowCoordinator" as AppFlowCoordinator << (C, DarkSeaGreen) >> { 
  ~navigationController : UINavigationController
  -appDIContainer : AppDIContainer
  ~init(navigationController:appDIContainer:)
  ~start() 
}
class "AppDIContainer" as AppDIContainer << (C, DarkSeaGreen) >> { 
  -apiNetworkService
  -toaster
  -imageCacher
  ~makeSceneDIContainer() 
}
class "SceneDIContainer" as SceneDIContainer << (C, DarkSeaGreen) >> { 
  -dependencies : Dependencies
  ~init(dependencies:)
  ~makeBanChanRepository()
  ~makeFoodImagesRepository()
  ~makeMainFoodViewFlowCoordinator(navigationController:)
  ~makeMainFoodUseCase()
  ~makeMainFoodViewModel(action:)
  ~makeMainFoodViewController(actions:)
  ~makeDetailFoodUseCase(detailHash:)
  ~makeDetailFoodViewModel(action:prepare:)
  ~makeDetailFoodViewController(actions:prepare:) 
}
class "AppDelegate" as AppDelegate << (C, DarkSeaGreen) >> { 
  ~application(_:didFinishLaunchingWithOptions:) 
}
class "SceneDelegate" as SceneDelegate << (C, DarkSeaGreen) >> { 
  ~window : UIWindow?
  ~appDiContainer
  ~appFlowCoordinator : AppFlowCoordinator?
  ~scene(_:willConnectTo:options:) 
}
class "DefaultBanChanRepository" as DefaultBanChanRepository << (C, DarkSeaGreen) >> { 
  ~networkService : NetworkService
  ~init(networkService:)
  ~fetchBestSection()
  ~fetchIndividualSection(api:)
  ~fetchFoodDetail(hashId:) 
}
class "DefaultFoodImagesRepository" as DefaultFoodImagesRepository << (C, DarkSeaGreen) >> { 
  ~networkService : NetworkService
  ~imageCacher : ImageCacher
  ~init(networkService:imageCacher:)
  ~fetchFoodImage(with:)
  -setCache(data:id:)
  -getCache(id:) 
}
class "APIEndPoint" as APIEndPoint << (S, SkyBlue) struct >> { 
  ~{static} getSectionsEndPoint(api:)
  ~{static} getFoodDetailEndPoint(hash:) 
}
class "ImageCacher" as ImageCacher << (C, DarkSeaGreen) >> { 
  ~{static} shared
  -init()
  ~container 
}
class "DetailPreparation" as DetailPreparation << (S, SkyBlue) struct >> { 
  ~productName : String
  ~hashId : String
  ~badge : [String]? 
}
class "DetailFoodUseCase" as DetailFoodUseCase << (P, GoldenRod) protocol >> { 
  ~fetchDetail()
  ~fetchFoodImage(imageString:)
  ~mockOrder(orderCount:) 
}
class "DefaultDetailFoodUseCase" as DefaultDetailFoodUseCase << (C, DarkSeaGreen) >> { 
  -banchanRepository : BanChanRepository
  -foodImageRepository : FoodImagesRepository
  -detailHash : String
  ~init(banchanRepository:foodImageRepository:detailHash:)
  ~fetchDetail()
  ~fetchFoodImage(imageString:)
  ~mockOrder(orderCount:) 
}
class "MainFoodUseCase" as MainFoodUseCase << (P, GoldenRod) protocol >> { 
  ~fetchBestSections()
  ~fetchIndividualSection(api:)
  ~fetchFoodImage(imageString:) 
}
class "DefaultMainFoodUseCase" as DefaultMainFoodUseCase << (C, DarkSeaGreen) >> { 
  -banchanRepository : BanChanRepository
  -foodImageRepository : FoodImagesRepository
  ~init(banchanRepository:foodImageRepository:)
  ~fetchBestSections()
  ~fetchFoodImage(imageString:)
  ~fetchIndividualSection(api:) 
}
class "BanChanRepository" as BanChanRepository << (P, GoldenRod) protocol >> { 
  ~fetchBestSection()
  ~fetchIndividualSection(api:)
  ~fetchFoodDetail(hashId:) 
}
class "Repository" as Repository << (P, GoldenRod) protocol >> { 
  ~networkService : NetworkService 
}
class "FoodImagesRepository" as FoodImagesRepository << (P, GoldenRod) protocol >> { 
  ~fetchFoodImage(with:) 
}
class "Cacher" as Cacher << (P, GoldenRod) protocol >> { 
  ~container : NSCache<NSString, T>
  ~setCache(with:id:)
  ~getCache(id:) 
}
class "MainFoodViewFlowCoordinatorDependencies" as MainFoodViewFlowCoordinatorDependencies << (P, GoldenRod) protocol >> { 
  ~makeMainFoodViewController(actions:)
  ~makeDetailFoodViewController(actions:prepare:) 
}
class "MainFoodViewFlowCoordinator" as MainFoodViewFlowCoordinator << (C, DarkSeaGreen) >> { 
  -navigationController : UINavigationController?
  -dependencies : MainFoodViewFlowCoordinatorDependencies
  -toaster : Toaster
  ~init(navigationController:dependencies:toaster:)
  ~start()
  -pushFoodDetailView(prepare:)
  -presentAlert(bool:)
  -showToast(text:) 
}
class "DetailFoodViewModelActions" as DetailFoodViewModelActions << (S, SkyBlue) struct >> { 
  ~presentAlert : (Bool) -> Void 
}
class "DetailFoodViewModelInput" as DetailFoodViewModelInput << (P, GoldenRod) protocol >> { 
  ~touchOrderButton() 
}
class "DetailFoodViewModelOutput" as DetailFoodViewModelOutput << (P, GoldenRod) protocol >> { 
  ~productName : Observable<String>
  ~eventBadge : Observable<[String]>
  ~detailDescImage : Observable<Data>
  ~thumbnailImage : Observable<Data>
  ~itemCountToPurchase : BehaviorSubject<Int>
  ~totalPriceToDisplay : BehaviorSubject<String>
  ~productDescription : Observable<String>
  ~foodPrices : Observable<[String]>
  ~deliveryFee : Observable<String>
  ~deliveryInfo : Observable<String>
  ~pointToEarn : Observable<String> 
}
class "DetailFoodViewModel" as DetailFoodViewModel << (P, GoldenRod) protocol >> {  
}
class "DefaultDetailFoodViewModel" as DefaultDetailFoodViewModel << (C, DarkSeaGreen) >> { 
  -disposeBag
  -detailFoodUseCase : DetailFoodUseCase
  -actions : DetailFoodViewModelActions?
  -itemPrice : Int
  -loadedData : BehaviorSubject<FoodDetail>
  ~productName : Observable<String>
  ~eventBadge : Observable<[String]>
  ~detailDescImage : Observable<Data>
  ~thumbnailImage : Observable<Data>
  ~productDescription : Observable<String>
  ~foodPrices : Observable<[String]>
  ~deliveryFee : Observable<String>
  ~deliveryInfo : Observable<String>
  ~pointToEarn : Observable<String>
  ~itemCountToPurchase : BehaviorSubject<Int>
  ~totalPriceToDisplay : BehaviorSubject<String>
  ~init(detailFoodUseCase:actions:prepare:)
  -loadData()
  -totalPriceBind() 
}
class "DefaultDetailFoodViewModel" as DefaultDetailFoodViewModel12 << (X, Orchid) extension >> { 
  touchOrderButton() 
}
class "DetailFoodViewController" as DetailFoodViewController << (C, DarkSeaGreen) >> { 
  ~imagePagingScrollView : UIScrollView!
  ~imagePageController : UIPageControl!
  ~productNameLabel : UILabel!
  ~productDescriptionLabel : UILabel!
  ~productPrice : UILabel!
  ~eventBadgeStackView : UIStackView!
  ~deliveryFeeLabel : UILabel!
  ~deliveryInfoLabel : UILabel!
  ~pointLabel : UILabel!
  ~foodDescImageStackView : UIStackView!
  ~quantityStepper : UIStepper!
  ~quantityCountLabel : UILabel!
  ~totalPriceLabel : UILabel!
  ~orderButton : UIButton!
  -disposeBag
  -viewModel : DetailFoodViewModel!
  ~viewDidLoad()
  ~{static} create(with:)
  ~bind()
  -addContentScrollView(image:) 
}
class "MainFoodViewModelActions" as MainFoodViewModelActions << (S, SkyBlue) struct >> { 
  ~pushFoodDetailView : (DetailPreparation) -> Void
  ~showToast : (String) -> Void 
}
class "MainFoodViewModelInput" as MainFoodViewModelInput << (P, GoldenRod) protocol >> { 
  ~didSelect(item:)
  ~sectionTouched(sectionName:sectionItemCount:) 
}
class "MainFoodViewModelOutput" as MainFoodViewModelOutput << (P, GoldenRod) protocol >> { 
  ~sceneTitle : String
  ~mainSectionRelay : BehaviorRelay<[MainSection]>
  ~dataSource : RxTableViewSectionedAnimatedDataSource<MainSection>
  ~sectionData : [MainSection] 
}
class "MainFoodViewModel" as MainFoodViewModel << (P, GoldenRod) protocol >> {  
}
class "DefaultMainFoodViewModel" as DefaultMainFoodViewModel << (C, DarkSeaGreen) >> { 
  -disposeBag
  -mainFoodUseCase : MainFoodUseCase
  -actions : MainFoodViewModelActions?
  ~mainSectionRelay : BehaviorRelay<[MainSection]>
  ~sceneTitle : String
  ~dataSource : RxTableViewSectionedAnimatedDataSource<MainSection>
  ~sectionData : [MainSection]
  ~init(mainFoodUseCase:actions:)
  -loadData() 
}
class "DefaultMainFoodViewModel" as DefaultMainFoodViewModel13 << (X, Orchid) extension >> { 
  didSelect(item:)
  sectionTouched(sectionName:sectionItemCount:) 
}
class "FoodListItemCell" as FoodListItemCell << (C, DarkSeaGreen) >> { 
  ~foodImageView : UIImageView!
  ~foodTitleLabel : UILabel!
  ~foodDescriptionLabel : UILabel!
  ~foodPriceLabel : UILabel!
  ~eventBadgeStackView : UIStackView!
  ~disposeBag
  ~detailHashId
  ~awakeFromNib()
  ~prepareForReuse()
  ~bind(with:data:) 
}
class "FoodListHeader" as FoodListHeader << (C, DarkSeaGreen) >> { 
  ~sectionTitleButton : UIButton!
  ~init(reuseIdentifier:)
  ~init(coder:)
  ~awakeFromNib()
  ~setTitle(text:) 
}
class "MainFoodViewController" as MainFoodViewController << (C, DarkSeaGreen) >> { 
  ~mainFoodTableView : UITableView!
  ~disposeBag
  -viewModel : MainFoodViewModel!
  ~viewDidLoad()
  ~{static} create(with:)
  -setupView()
  -bind()
  -setTableViewCell() 
}
class "StoryboardInitiating" as StoryboardInitiating << (P, GoldenRod) protocol >> { 
  ~{static} defaultFileName : String
  ~{static} instantiateViewController(_:) 
}
class "Toaster" as Toaster << (C, DarkSeaGreen) >> { 
  ~showUpWith(text:to:) 
}

MainFoodViewFlowCoordinator <-up DetailFoodViewController: present
MainFoodViewFlowCoordinator <-up MainFoodViewController: present
StoryboardInitiating <|--down DetailFoodViewController : inherits
StoryboardInitiating <|--down MainFoodViewController : inherits

NetworkService <|.. DefaultNetworkService : confirms to
NetworkRequesting <|.. DefaultNetworkRequester : confirms to
URLConvertible <|-- EndPoint : inherits
MainFoodViewFlowCoordinatorDependencies <|-- SceneDIContainer : inherits
BanChanRepository <|-- DefaultBanChanRepository : inherits
FoodImagesRepository <|-- DefaultFoodImagesRepository : inherits
Cacher <|-- ImageCacher : inherits
DetailFoodUseCase <|.. DefaultDetailFoodUseCase : confirms to
MainFoodUseCase <|.. DefaultMainFoodUseCase : confirms to
Repository <|.. BanChanRepository : inherits
Repository <|.. FoodImagesRepository : confirms to
DetailFoodViewModelInput <|.. DetailFoodViewModel : confirms to
DetailFoodViewModelOutput <|.. DetailFoodViewModel : confirms to
DetailFoodViewModel <|.. DefaultDetailFoodViewModel : confirms to

MainFoodViewModelInput <|.. MainFoodViewModel : confirms to
MainFoodViewModelOutput <|.. MainFoodViewModel : confirms to
MainFoodViewModel <|.. DefaultMainFoodViewModel : confirms to


DefaultDetailFoodViewModel <.. DefaultDetailFoodViewModel12 : ext
DefaultMainFoodViewModel <.. DefaultMainFoodViewModel13 : ext

@enduml

class "MainFoodViewController" as MainFoodViewController << (C, DarkSeaGreen) >> { ~mainFoodTableView : UITableView! ~disposeBag -viewModel : MainFoodViewModel! ~viewDidLoad() ~{static} create(with:) -setupView() -bind() -setTableViewCell() } class "StoryboardInitiating" as StoryboardInitiating << (P, GoldenRod) protocol >> { ~{static} defaultFileName : String ~{static} instantiateViewController(_:) } class "DetailFoodViewController" as DetailFoodViewController << (C, DarkSeaGreen) >> { ~imagePagingScrollView : UIScrollView! ~imagePageController : UIPageControl! ~productNameLabel : UILabel! ~productDescriptionLabel : UILabel! ~productPrice : UILabel! ~eventBadgeStackView : UIStackView! ~deliveryFeeLabel : UILabel! ~deliveryInfoLabel : UILabel! ~pointLabel : UILabel! ~foodDescImageStackView : UIStackView! ~quantityStepper : UIStepper! ~quantityCountLabel : UILabel! ~totalPriceLabel : UILabel! ~orderButton : UIButton! -disposeBag -viewModel : DetailFoodViewModel! ~viewDidLoad() ~{static} create(with:) ~bind() -addContentScrollView(image:) } class "MainFoodViewFlowCoordinator" as MainFoodViewFlowCoordinator << (C, DarkSeaGreen) >> { -navigationController : UINavigationController? -dependencies : MainFoodViewFlowCoordinatorDependencies -toaster : Toaster ~init(navigationController:dependencies:toaster:) ~start() -pushFoodDetailView(prepare:) -presentAlert(bool:) -showToast(text:) }

DetailFoodViewController <-down MainFoodViewFlowCoordinator : present MainFoodViewController <-down MainFoodViewFlowCoordinator : present StoryboardInitiating <|--down DetailFoodViewController : inherits StoryboardInitiating <|--down MainFoodViewController : inherits

class "DefaultBanChanRepository" as DefaultBanChanRepository << (C, DarkSeaGreen) >> { ~networkService : NetworkService ~init(networkService:) ~fetchBestSection() ~fetchIndividualSection(api:) ~fetchFoodDetail(hashId:) } class "DefaultFoodImagesRepository" as DefaultFoodImagesRepository << (C, DarkSeaGreen) >> { ~networkService : NetworkService ~imageCacher : ImageCacher ~init(networkService:imageCacher:) ~fetchFoodImage(with:) -setCache(data:id:) -getCache(id:) } class "BanChanRepository" as BanChanRepository << (P, GoldenRod) protocol >> { ~fetchBestSection() ~fetchIndividualSection(api:) ~fetchFoodDetail(hashId:) } class "Repository" as Repository << (P, GoldenRod) protocol >> { ~networkService : NetworkService } class "FoodImagesRepository" as FoodImagesRepository << (P, GoldenRod) protocol >> { ~fetchFoodImage(with:) }

FoodImagesRepository <|-- DefaultFoodImagesRepository : inherits BanChanRepository <|-- DefaultBanChanRepository : inherits Repository <|.. BanChanRepository : inherits Repository <|.. FoodImagesRepository : confirms to

class "NetworkService" as NetworkService << (P, GoldenRod) protocol >> { ~request(with:) ~request(with:) } class "DefaultNetworkService" as DefaultNetworkService << (C, DarkSeaGreen) >> { ~networkRequester : NetworkRequesting ~init(requester:) ~request(with:) ~request(with:) } class "NetworkRequesting" as NetworkRequesting << (P, GoldenRod) protocol >> { ~get(url:session:) ~getWithoutDecode(url:session:) } class "DefaultNetworkRequester" as DefaultNetworkRequester << (C, DarkSeaGreen) >> { ~get(url:session:) ~getWithoutDecode(url:session:) } class "EndPoint" as EndPoint << (S, SkyBlue) struct >> { ~scheme : String ~host : String ~path : String ~method : HTTPMethod ~init(scheme:host:apiPath:httpMethod:) ~asURL() }

class "APIEndPoint" as APIEndPoint << (S, SkyBlue) struct >> { ~{static} getSectionsEndPoint(api:) ~{static} getFoodDetailEndPoint(hash:) }

EndPoint <-down APIEndPoint : dependency

AppDIContainer <-down DefaultNetworkService : assiciation DefaultNetworkService <-down DefaultNetworkRequester : association DefaultNetworkService <-down EndPoint: dependency

NetworkService <|.. DefaultNetworkService : confirms to NetworkRequesting <|.. DefaultNetworkRequester : confirms to

class "DetailFoodUseCase" as DetailFoodUseCase << (P, GoldenRod) protocol >> { ~fetchDetail() ~fetchFoodImage(imageString:) ~mockOrder(orderCount:) } class "DefaultDetailFoodUseCase" as DefaultDetailFoodUseCase << (C, DarkSeaGreen) >> { -banchanRepository : BanChanRepository -foodImageRepository : FoodImagesRepository -detailHash : String ~init(banchanRepository:foodImageRepository:detailHash:) ~fetchDetail() ~fetchFoodImage(imageString:) ~mockOrder(orderCount:) } class "MainFoodUseCase" as MainFoodUseCase << (P, GoldenRod) protocol >> { ~fetchBestSections() ~fetchIndividualSection(api:) ~fetchFoodImage(imageString:) } class "DefaultMainFoodUseCase" as DefaultMainFoodUseCase << (C, DarkSeaGreen) >> { -banchanRepository : BanChanRepository -foodImageRepository : FoodImagesRepository ~init(banchanRepository:foodImageRepository:) ~fetchBestSections() ~fetchFoodImage(imageString:) ~fetchIndividualSection(api:) } class "DetailFoodViewModelActions" as DetailFoodViewModelActions << (S, SkyBlue) struct >> { ~presentAlert : (Bool) -> Void } class "DetailFoodViewModelInput" as DetailFoodViewModelInput << (P, GoldenRod) protocol >> { ~touchOrderButton() } class "DetailFoodViewModelOutput" as DetailFoodViewModelOutput << (P, GoldenRod) protocol >> { ~productName : Observable ~eventBadge : Observable<[String]> ~detailDescImage : Observable ~thumbnailImage : Observable ~itemCountToPurchase : BehaviorSubject ~totalPriceToDisplay : BehaviorSubject ~productDescription : Observable ~foodPrices : Observable<[String]> ~deliveryFee : Observable ~deliveryInfo : Observable ~pointToEarn : Observable } class "DetailFoodViewModel" as DetailFoodViewModel << (P, GoldenRod) protocol >> {
} class "DefaultDetailFoodViewModel" as DefaultDetailFoodViewModel << (C, DarkSeaGreen) >> { -disposeBag -detailFoodUseCase : DetailFoodUseCase -actions : DetailFoodViewModelActions? -itemPrice : Int -loadedData : BehaviorSubject ~productName : Observable ~eventBadge : Observable<[String]> ~detailDescImage : Observable ~thumbnailImage : Observable ~productDescription : Observable ~foodPrices : Observable<[String]> ~deliveryFee : Observable ~deliveryInfo : Observable ~pointToEarn : Observable ~itemCountToPurchase : BehaviorSubject ~totalPriceToDisplay : BehaviorSubject ~init(detailFoodUseCase:actions:prepare:) -loadData() -totalPriceBind() } class "MainFoodViewModelActions" as MainFoodViewModelActions << (S, SkyBlue) struct >> { ~pushFoodDetailView : (DetailPreparation) -> Void ~showToast : (String) -> Void } class "MainFoodViewModelInput" as MainFoodViewModelInput << (P, GoldenRod) protocol >> { ~didSelect(item:) ~sectionTouched(sectionName:sectionItemCount:) } class "MainFoodViewModelOutput" as MainFoodViewModelOutput << (P, GoldenRod) protocol >> { ~sceneTitle : String ~mainSectionRelay : BehaviorRelay<[MainSection]> ~dataSource : RxTableViewSectionedAnimatedDataSource ~sectionData : [MainSection] } class "MainFoodViewModel" as MainFoodViewModel << (P, GoldenRod) protocol >> {
} class "DefaultMainFoodViewModel" as DefaultMainFoodViewModel << (C, DarkSeaGreen) >> { -disposeBag -mainFoodUseCase : MainFoodUseCase -actions : MainFoodViewModelActions? ~mainSectionRelay : BehaviorRelay<[MainSection]> ~sceneTitle : String ~dataSource : RxTableViewSectionedAnimatedDataSource ~sectionData : [MainSection] ~init(mainFoodUseCase:actions:) -loadData() }

DetailFoodUseCase <|.. DefaultDetailFoodUseCase : confirms to MainFoodUseCase <|.. DefaultMainFoodUseCase : confirms to

DetailFoodViewModelInput <|.. DetailFoodViewModel : confirms to DetailFoodViewModelOutput <|.. DetailFoodViewModel : confirms to DetailFoodViewModel <|.. DefaultDetailFoodViewModel : confirms to DefaultDetailFoodViewModel <- DefaultDetailFoodUseCase : association

MainFoodViewModelInput <|.. MainFoodViewModel : confirms to MainFoodViewModelOutput <|.. MainFoodViewModel : confirms to MainFoodViewModel <|.. DefaultMainFoodViewModel : confirms to DefaultMainFoodViewModel <- DefaultMainFoodUseCase : association

class "AppFlowCoordinator" as AppFlowCoordinator << (C, DarkSeaGreen) >> { ~navigationController : UINavigationController -appDIContainer : AppDIContainer ~init(navigationController:appDIContainer:) ~start() } class "AppDIContainer" as AppDIContainer << (C, DarkSeaGreen) >> { -apiNetworkService -toaster -imageCacher ~makeSceneDIContainer() } class "SceneDIContainer" as SceneDIContainer << (C, DarkSeaGreen) >> { -dependencies : Dependencies ~init(dependencies:) ~makeBanChanRepository() ~makeFoodImagesRepository() ~makeMainFoodViewFlowCoordinator(navigationController:) ~makeMainFoodUseCase() ~makeMainFoodViewModel(action:) ~makeMainFoodViewController(actions:) ~makeDetailFoodUseCase(detailHash:) ~makeDetailFoodViewModel(action:prepare:) ~makeDetailFoodViewController(actions:prepare:) } class "SceneDelegate" as SceneDelegate << (C, DarkSeaGreen) >> { ~window : UIWindow? ~appDiContainer ~appFlowCoordinator : AppFlowCoordinator? ~scene(_:willConnectTo:options:) } class "ImageCacher" as ImageCacher << (C, DarkSeaGreen) >> { ~{static} shared -init() ~container } class "Cacher" as Cacher << (P, GoldenRod) protocol >> { ~container : NSCache<NSString, T> ~setCache(with:id:) ~getCache(id:) } class "MainFoodViewFlowCoordinatorDependencies" as MainFoodViewFlowCoordinatorDependencies << (P, GoldenRod) protocol >> { ~makeMainFoodViewController(actions:) ~makeDetailFoodViewController(actions:prepare:) }

class "Toaster" as Toaster << (C, DarkSeaGreen) >> { ~showUpWith(text:to:) }

SceneDelegate <-down AppDIContainer : association SceneDelegate <-down AppFlowCoordinator : association

AppDIContainer <-down SceneDIContainer: dependency

AppDIContainer <-down Toaster : assiciation AppDIContainer <-down ImageCacher : assiciation

MainFoodViewFlowCoordinatorDependencies <|-- SceneDIContainer : inherits

Cacher <|-- ImageCacher : inherits

Clone this wiki locally