Slide 1

Slide 1 text

Dobry zwyczaj nie odziedziczaj @_siejkowski siejkowski.net !

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

class A : B

Slide 4

Slide 4 text

BaseViewController BaseDataFetchingViewController :BaseViewController BaseFormPresentingViewController :BaseDataFetchingViewController

Slide 5

Slide 5 text

Przepraszam, czy mogę przeciążyć?

Slide 6

Slide 6 text

super ?

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

NSManagedObject https://github.com/rentzsch/mogenerator

Slide 9

Slide 9 text

BaseViewController : UIViewController ThirdPartyBehaviorEnablingViewController : UIViewController UserAccountDetailsViewController : !

Slide 10

Slide 10 text

struct SomeStruct {} enum SomeEnum {} typealias SomeFunction = (Int -> String) class C : SomeFunction ❗ Inheritance from non-protocol, non-class type 'SomeFunction'

Slide 11

Slide 11 text

agregacja protokoły funkcje

Slide 12

Slide 12 text

ThirdPartyBehaviorEnablingService ThirdPartyBehaviorEnablingDelegate

Slide 13

Slide 13 text

init(accountService: AccountService, transactionService: TransactionService, sessionService: SessionService, favouritesService: FavouritesService, locationService: LocationService, ...)

Slide 14

Slide 14 text

class *-Utils class *-Helper

Slide 15

Slide 15 text

UITableViewDataSource UITableViewDelegate

Slide 16

Slide 16 text

code review TDD style guide clean code

Slide 17

Slide 17 text

agregacja protokoły funkcje

Slide 18

Slide 18 text

protocol SessionAware protocol LocationAware protocol FavouritesFetchable class MyViewController : UIViewController, SessionAware, LocationAware, FavouritesFetchable

Slide 19

Slide 19 text

extension UIViewController : SessionAware

Slide 20

Slide 20 text

protocol SessionAware { func login(username: String, _ password: String, _ callback: (UserDetails) -> ()) } extension MyViewController : SessionAware {} extension SessionAware { func login(username: String, _ password: String, _ callback: (UserDetails) -> ())) { // domyślna implementacja } } ❗ http://nomothetis.svbtle.com/the-ghost-of-swift-bugs-future

Slide 21

Slide 21 text

protocol FavouritesDataSource : UITableViewDataSource { var state: [FavouriteDetails] { get } // "obietnica" stanu } extension FavouritesDataSource { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return state.count // ... protocol FavouritesTableDelegate : UITableViewDelegate { var state: [FavouriteDetails] { get } // "obietnica" stanu } extension FavouritesTableDelegate { func tableView(_ tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { // ... class MyViewController : NSObject, FavouritesDataSource, FavouritesTableDelegate { var state: [FavouriteDetails] = Array() init(newState: [FavouriteDetails]) { state = newState }

Slide 22

Slide 22 text

⬆ dziedziczenie ⬇ ⬅ protokoły ➡

Slide 23

Slide 23 text

agregacja protokoły funkcje

Slide 24

Slide 24 text

func login(username: String, _ password: String, _ callback: (UserDetails) -> ()) func update(view: HeaderView) (_ user: UserDetails) -> UserDetails func fetchFavourites(user: UserDetails) (_ callback: (FavouritesData) -> ()) func update(source: FavoritesDataSource) (_ tableView: UITableView) (_ favourites: FavouritesData)

Slide 25

Slide 25 text

class SomeViewController { let updateHeader = update(headerView) let updateFavourites = update(favouritesDataSource)(tableView) override func viewDidLoad() { // ..., m.in super.viewDidLoad() login("siejkowski","mobilization") { details in fetchFavourites(updateHeader(details))(updateFavourites) } }

Slide 26

Slide 26 text

infix operator |> { associativity left } infix operator <| { associativity right } public func |> (a : A, f : A -> B) -> B { return f(a) } public func <| (f : A -> B, a : A) -> B { return f(a) }

Slide 27

Slide 27 text

infix operator useFor { associativity left } details useFor updateHeader ❗ !

Slide 28

Slide 28 text

login("siejkowski","mobilization") { details in fetchFavourites(updateHeader(details))(updateFavourites) } ⬇ ⬇ ⬇ login("siejkowski","mobilization") { details in (details |> updateHeader |> fetchFavourites) <| updateFavourites }

Slide 29

Slide 29 text

agregacja protokoły funkcje

Slide 30

Slide 30 text

class SomeViewController { let updateHeader = update(headerView) let updateFavourites = update(favouritesDataSource)(tableView) override func viewDidLoad() { super.viewDidLoad() login("siejkowski","mobilization") { details in (details |> updateHeader |> fetchFavourites) <| updateFavourites } } !

Slide 31

Slide 31 text

pure functions Swift functions

Slide 32

Slide 32 text

struct FunctionUsingStruct { let func: String -> Bool init(_ injectedFunc: String -> Bool) { // funkcje można wstrzykiwać func = injectedFunc ... } } !

Slide 33

Slide 33 text

class DIFactory { func realFunc(string: String) -> Bool { ... } // w produkcyjnym kodzie wstrzykujemy prawdziwą funkcję func functionUsingStruct() -> FunctionUsingStruct { return FunctionUsingStruct(realFunc) } class TestCase { func testFunc(string: String) -> Bool { return true } // w testowym kodzie używamy mockowej funkcji let testStruct = FunctionUsingStruct(testFunc) !

Slide 34

Slide 34 text

func login(username: String, _ password: String, _ callback: (UserDetails) -> ()) func fullLogin(loginManager: LoginManager) (_ username: String, _ password: String, _ callback(UserDetails) -> ()) -> () { loginManager.login(username, password, callback) } let login = fullLogin(actualLoginManager) let mockLogin = fullLogin(mockLoginManager)

Slide 35

Slide 35 text

funkcje ❤ protokoły

Slide 36

Slide 36 text

extension MyViewController : SessionAware { func login(username: String, _ password: String, _ callback: (UserDetails) -> ()) { // tutaj przekazany jest domyślnie self } } func login(username: String, _ password: String, _ callback: (UserDetails) -> ()) { // tutaj przekazane jest to co w sygnaturze }

Slide 37

Slide 37 text

func root(double: Double) -> Double? { ... } func root(float: Float) -> Float? { ... } func root(int: Int) -> Int? { ... } protocol Rootable { func root() -> Self? } extension Double : Rootable { ... } extension Float : Rootable { ... } extension Int : Rootable { ... } func useRootable(rootable: Rootable) { rootable.root() }

Slide 38

Slide 38 text

*-able protocol JSONDecodable { static func decode(json: JSON) -> Self } protocol Validatable { func validate(validator: Validator) -> Bool } protocol Hashable : Equatable { public var hashValue: Int { get } }

Slide 39

Slide 39 text

Co jest problemem? nil ErrorType asynchroniczność logowanie sekwencja callback cokolwiek chcesz !

Slide 40

Slide 40 text

func canCauseProblem(input: Int) -> ProblemHiding func possibleProblem(input: String) -> ProblemHiding func yetAnotherProblem(input: Double) -> ProblemHiding let input = 42 ProblemHiding(input) // udajemy że wszystko gra .execute(canCauseProblem) // jakby nic się nie stało .execute(possibleProblem) // bez nerwów, bez ifów .execute(yetAnotherProblem) // jak kwiat lotosu .obtainValue() // sprawdzam!

Slide 41

Slide 41 text

protocol Monad { typealias A typealias B typealias FB func bind(f: A -> FB) -> FB } !

Slide 42

Slide 42 text

extension Optional : Monad { typealias A = Wrapped typealias B = Any // nil jest problemem typealias FB = B? func bind(f: A -> B?) -> B? { return self.flatMap(f) } } extension Array : Monad { typealias A = Element typealias B = Any // wiele wartości to problem typealias FB = Array func bind(f: A -> [B]) -> [B] { return self.flatMap(f) } }

Slide 43

Slide 43 text

enum Result { // możliwy ErrorType to problem case Success(Value) case Failure(ErrorType) } extension Result : Monad { typealias A = Value typealias B = Any typealias FB = Result func bind(f: A -> Result) -> Result { switch self { case .Success(let value): return f(value) case .Failure(let error): return .Failure(error) } } }

Slide 44

Slide 44 text

https://github.com/typelift Swiftx Swiftz https://github.com/thoughtbot Runes Argo https://github.com/robrix Prelude

Slide 45

Slide 45 text

agregacja ❤ protokoły ❤ funkcje

Slide 46

Slide 46 text

agregacja ❤ protokoły ❤ funkcje ❤ dziedziczenie

Slide 47

Slide 47 text

Dziękuję! @_siejkowski !