Dependence day insurgence

Post on 23-Jan-2018

307 views 0 download

transcript

#Swift3Arch

Dependence day: Insurgence

Jorge D. Ortiz Fuentes @jdortiz

A Canonical Examples Production

#Swift3Arch

#Swift3Arch

Agenda

The Problem

Solutions

Recommendations

The Problem

#Swift3Arch

Job Description

Understand the problem

Identify the right set of pieces

Put proper names

Make them run together properly

#Swift3Arch

Social Network Option A

Social Network

#Swift3Arch

Video

Text

Image

Social Network Option B

User PostGroup

Discussion

Promotion

DM

#Swift3Arch

Single Responsibility Principle

ViewControllerPresenter

View ModelModel

Presentation logic

Business Logic

Data Source

Data Source

Data Source

Navigation

The Jigsaw Puzzle

#Swift3Arch

Making it workObjects require other objects to work -> Dependencies

Each object creates its dependencies

Bad idea™

• Another responsibility

• What if we want to use it with different sets of pieces?

Instanciation =

alien is born

Test environment

#Swift3Arch

How to Provide Dependencies

Initializer

Property

Method

But Who?

Frameworks to the rescue

#Swift3Arch

Inversion of Control

Hollywood Principle

#Swift3Arch

Dependency Inversion Containers

Dip

Swinject

Cleanse

#Swift3Arch

DipCreated by Olivier Halligon, maintained by Ilya Puchka

Beautifully simple

Nice way to inject in Storyboards

Scopes, Named definitions, Runtime arguments, Circular dependencies, Auto-wiring & Auto-injection, Type forwarding, Storyboards integration, Weakly typed components, Easy configuration, Thread safety, Helpful error messages, and configuration validation.

#Swift3Arch

Dipfunc configure(container: DependencyContainer) { container.register(.unique) { InMemoryRepo() } container.register(.unique) { try UseCaseFactory(entityGateway: container.resolve() as InMemoryRepo) }

DependencyContainer.uiContainers = [showProgrammersListModule] }

let showProgrammersListModule = DependencyContainer { container in container.register() { try ProgrammersListPresenter(useCaseFactory: container.resolve() as UseCaseFactory) } container.register(tag: "ProgrammersTableVC") { ProgrammersTableViewController() } .resolvingProperties { container, viewController in viewController.presenter = try container.resolve() as ProgrammersListPresenter } }

extension ProgrammersTableViewController: StoryboardInstantiatable {}

#Swift3Arch

SwinjectCreated by Jakub Vano, Wolfgang Lutz, Yoichi Tagala

Pure Swift Type Support, Injection with Arguments, Initializer/Property/Method Injections, Initialization Callback, Circular Dependencies, Object Scopes, Reference & Value Types, Self-registration, Container Hierarchy, Property Injection from Resource files, Thread Safety, Modular Components, Storyboard

#Swift3Arch

Cleanse

Created by Square

Early version, but promising

No Swift 3 Yet*!

The World Outside

#Swift3Arch

Java for Android

Standard annotations for DI (JSR330)

Introspection & Reflection

Many frameworks available

Some owned by Google (Guice & Dagger 2)

Maturity

What then?

Traditional methods

#Swift3Arch

Assemble the Piecesclass ProgrammersListConnector {

// MARK: - Constants

let entityGateway: EntityGatewayProtocol weak var presenter: ProgrammersListPresenter!

func assembleModule(view: ProgrammersTableViewController) { let useCaseFactory = UseCaseFactory(entityGateway: entityGateway) let presenter = ProgrammersListPresenter(useCaseFactory: useCaseFactory) view.presenter = presenter view.connector = self presenter.view = view self.presenter = presenter } }

#Swift3Arch

Factories are your friendprotocol UseCase { func execute() }

class UseCaseFactory {

enum Use { case showProgrammersList(completion: ShowProgrammersListCompletion) // … }

func create(useCase whichUseCase: Use) -> UseCase { switch whichUseCase { case let .showProgrammersList(completion: completion): return ShowProgrammersListUseCase(entityGateway: entityGateway, completionHandler: completion) // … } }

Recap

#Swift3Arch

Take aways

Make your dependencies explicit

Use factories

Understand how it a container works

Use DI frameworks with caution

Thank You!

@jdortiz #Swift3Arch