Skip to content

Instantly share code, notes, and snippets.

@shawnkoh
Created May 15, 2020 08:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shawnkoh/738840958616fa1bcd5c262099c7b739 to your computer and use it in GitHub Desktop.
Save shawnkoh/738840958616fa1bcd5c262099c7b739 to your computer and use it in GitHub Desktop.
// 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