Created
May 15, 2020 08:33
-
-
Save shawnkoh/738840958616fa1bcd5c262099c7b739 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// MARK: - UseCases | |
struct InputData {} | |
protocol InputBoundary { | |
func doSomething(inputData: InputData, presenter: OutputBoundary) | |
} | |
protocol OutputBoundary { | |
var viewModel: ViewModel { get } | |
func present(outputData: OutputData) | |
} | |
struct OutputData {} | |
final class UseCaseInteractor: InputBoundary { | |
func doSomething(inputData: InputData, presenter: OutputBoundary) { | |
// Controls the Dance of the Entities using the InputData | |
// Brings data used by those Entities into memory from the Database | |
// Upon completion, gathers data from the Entities and constructs the OutputData | |
let outputData = OutputData() | |
presenter.present(outputData: outputData) | |
} | |
} | |
protocol Request {} | |
// MARK: - InterfaceAdapters | |
/// Controller packages input data into a plain old Java object and passes this object through | |
/// the InputBoundary to the UseCaseInteractor | |
final class Controller { | |
let interactor: InputBoundary = UseCaseInteractor() | |
let presenter: OutputBoundary = Presenter() | |
let view = View() | |
// CleanArchitecture's controller knows about InputBoundary, OutputBoundary, and View. | |
// Request can also just be params instead. | |
func handle(request: Request) { | |
// Construct InputData using the input parameters. | |
let inputData = InputData() // assume this uses the input string | |
interactor.doSomething(inputData: inputData, presenter: presenter) | |
view.update(viewModel: presenter.viewModel) | |
} | |
} | |
final class Presenter: OutputBoundary { | |
// it looks like they actually store the ViewModel inside the presenter. | |
// but they also expose the ViewModel through the getViewModel() method. | |
// question is: should we store the view model here, or expose it as the | |
// return value of present(outputData:)? | |
var viewModel: ViewModel { | |
guard let viewModel = _viewModel else { | |
fatalError("Presenter has not presented ViewModel") | |
} | |
return viewModel | |
} | |
private var _viewModel: ViewModel? | |
func present(outputData: OutputData) { | |
// Repackage the OutputData into viewable form as the ViewModel | |
_viewModel = ViewModel() | |
} | |
} | |
struct ViewModel { | |
// ViewModel should contain mostly Strings and flags that the View | |
// uses to display the data. | |
// Whereas the OutputData may contain Date objects, the Presenter | |
// will load the ViewModel with corresponding Strings already formatted | |
// properly for the user. | |
// The same is true of Currency objects or any other business-related data | |
} | |
// MARK: - Frameworks & Drivers | |
final class View { | |
// Updates the View based on the new ViewModel | |
func update(viewModel: ViewModel) {} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment