Last active
February 20, 2017 20:14
-
-
Save ncreated/780c58c25d0731b93f9106be694adebe to your computer and use it in GitHub Desktop.
Comparison of Imperative vs Reactive ways
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
// Imperative | |
protocol EditableMapSourceDelegate: class { | |
func sourceDidChangeActiveTerritory(_ source: EditableMapSource) | |
func sourceDidChangeData(_ source: MapDataSource) | |
} | |
final class EditableMapSource: MapDataSource { | |
weak var delegate: EditableMapSourceDelegate? | |
// ... | |
private(set) var territories: [TerritoryData] = [] { | |
didSet { | |
delegate?.sourceDidChangeData(self) | |
} | |
} | |
private(set) var activeTerritory: TerritoryData? { | |
didSet { | |
delegate?.sourceDidChangeActiveTerritory(self) | |
} | |
} | |
var activeTerritoryIndex: Int? { | |
if let activeTerritory = activeTerritory { | |
return territories.index(of: activeTerritory) | |
} else { | |
return nil | |
} | |
} | |
// MARK: Navigating between territories | |
func moveToNextTerritory() { | |
if let index = activeTerritoryIndex { | |
let nextIndex = (index + 1) % territories.count | |
activeTerritory = territories[nextIndex] | |
} | |
} | |
func moveToPreviousTerritory() { | |
if let index = activeTerritoryIndex { | |
let previousIndex = (index > 0) ? (index - 1) : (territories.count - 1) | |
activeTerritory = territories[previousIndex] | |
} | |
} | |
// ... | |
// MARK: Editing territories | |
func hexBelongsToTerritory(_ hex: Hex) throws -> Bool { | |
// ... | |
} | |
func addHexToTerritory(_ hex: Hex) throws { | |
// ... | |
} | |
func removeHexFromTerritory(_ hex: Hex) throws { | |
// ... | |
} | |
// ... | |
func changeNumberOfUnitsInTerritoryByValue(_ value: Int) throws { | |
// ... | |
} | |
// ... | |
} |
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
// Reactive | |
final class EditorViewModel { | |
// ... | |
private let stateVariable: Variable<EditorState> | |
private let disposeBag = DisposeBag() | |
// ... | |
// MARK: - Inputs | |
func set(hexSelected rx_hexSelected: Observable<Hex>, | |
nextTerritory rx_next: Observable<Void>, | |
previousTerritory rx_previous: Observable<Void>, | |
moreUnits rx_more: Observable<Void>, | |
lessUnits rx_less: Observable<Void>) | |
{ | |
let rx_state = stateVariable.asObservable() | |
let rx_territoryIndexChange = Observable | |
.of( rx_next.map { 1 }, rx_previous.map { -1 } ) | |
.merge() | |
let rx_numberOfUnitsChange = Observable | |
.of( rx_more.map { 1 }, rx_less.map { -1 } ) | |
.merge() | |
// Calculate state changes | |
let rx_stateAfterProcessingHex = rx_hexSelected | |
.withLatestFrom(rx_state) { $0 } | |
.map { (hex, state) in state.nextByProcessing(hex: hex) } | |
let rx_stateAfterChangingActiveTerritory = rx_territoryIndexChange | |
.withLatestFrom(rx_state) { $0 } | |
.map { (change, state) in state.nextByChangingActiveIndex(by: change) } | |
let rx_stateAfterChangingNumberOfUnits = rx_numberOfUnitsChange | |
.withLatestFrom(rx_state) { $0 } | |
.map { (change, state) in state.nextByChangingNumberOfUnits(by: change) } | |
// Update state variable | |
Observable | |
.of(rx_stateAfterProcessingHex, rx_stateAfterChangingActiveTerritory, rx_stateAfterChangingNumberOfUnits) | |
.merge() | |
.bindTo(stateVariable) | |
.addDisposableTo(disposeBag) | |
// Create outputs | |
rx_viewData = rx_state | |
.map { state in | |
return (map: CustomMapSource(territories: state.territories, colorsOrder: colors), | |
current: Territory(data: state.currentActive), | |
previous: state.previousActive.map { Territory(data: $0) } ) | |
} | |
.asDriver(onErrorDriveWith: .empty()) | |
// ... | |
} | |
// MARK: - Outputs | |
private(set) var rx_viewData: Driver<(map: MapDataSource, current: Territory, previous: Territory?)> = .never() | |
} | |
struct EditorState { | |
// MARK: - Properties | |
let territories: [TerritoryData] | |
let currentActive: TerritoryData | |
let previousActive: TerritoryData? | |
// ... | |
// MARK: - Public | |
func nextByProcessing(hex: Hex) -> EditorState { | |
// ... | |
} | |
func nextByChangingActiveIndex(by change: Int) -> EditorState { | |
// ... | |
} | |
func nextByChangingNumberOfUnits(by change: Int) -> EditorState { | |
// ... | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment