Slide 1

Slide 1 text

FRÉDÉRIC MAQUIN @EPHREAD CocoaHeads Strasbourg NOVEMBER 17TH, 2016 PATTERNS Trends & ! BETA

Slide 2

Slide 2 text

There are lots of competing architectural styles and design patterns. 2

Slide 3

Slide 3 text

There are lots of competing architectural styles and design patterns. (By lots I mean three, really.) 2

Slide 4

Slide 4 text

MVC CONTROLLER MODEL VIEW 3

Slide 5

Slide 5 text

MVVM VIEW MODEL MODEL VIEW (UIVIEW + UIVIEWCONTROLLER) Works best with Reactive Programming™ 4

Slide 6

Slide 6 text

VIPER PRESENTER INTERACTOR VIEW (UIVIEW + UIVIEWCONTROLLER) For the worthy only. 5 ROUTER ENTITY

Slide 7

Slide 7 text

— Well-known anonymous person MVC stands for Massive View Controller “ ” 6

Slide 8

Slide 8 text

— Soroush Khanlou MVVM is Not Very Good “ ” 7

Slide 9

Slide 9 text

— Ash Furrow MVVM is exceptionally OK “ ” 8

Slide 10

Slide 10 text

— Random Android guy on the Internet MVP is the gold standard “ ” 9

Slide 11

Slide 11 text

MVVMMVCMVPMVVMCVIPERMVVMMV CMVPMVVMCVIPERMVVMMVCMVPMV VMCVIPEMVVMMVCMVPMVVMCVIPER MVVMMVCMVPMVVMCVIPERRMVVMM VCMVPMVVMCVIPERMVVMMVCMVPM VVMCVIPERMVVMMVCMVPMVVMCVIP ERMVVMMVCMVPMVVMCVIPERMVVM 10

Slide 12

Slide 12 text

Which one should I choose? 11

Slide 13

Slide 13 text

Everyone has their own preferences, opinions and biases. 12

Slide 14

Slide 14 text

— Christian Tietze Don’t force any architectural patterns down your throat. Strive for higher testability first. “ ” 13

Slide 15

Slide 15 text

How do we strive for higher testability and higher maintainability? 14

Slide 16

Slide 16 text

SINGLE RESPONSABILITY PRINCIPLE #1 15

Slide 17

Slide 17 text

Split features across small components. One feature per component. single responsability principle 16

Slide 18

Slide 18 text

single responsability principle class UIViewController: CBCentralManagerDelegate, CLLocationManagerDelegate { var bluetoothManager: CBCentralManager! var locationManager: CLLocationManager! func viewDidLoad() { bluetoothManager.delegate = self locationManager.delegate = self } } 17

Slide 19

Slide 19 text

single responsability principle class UIViewController { var bluetoothManager: BluetoothManager! var locationManager: LocationManager! } 17

Slide 20

Slide 20 text

single responsability principle Andy Matuschak did an amazing talk on how to refactor with the SRP in mind. 18

Slide 21

Slide 21 text

#2 LOOSE COUPLING 19

Slide 22

Slide 22 text

Loose coupling allows you to test modules independently from each other. Use dependency injection to decouple modules. 20

Slide 23

Slide 23 text

The idea is to provide dependencies, rather than create/retrieve them. dependency injection 21

Slide 24

Slide 24 text

without dependency injection class Model☰ { let electricalMotor: ElectricalMotor = InductionMotor() } " Tight Coupling! 22

Slide 25

Slide 25 text

class Model☰ { let electricalMotor: ElectricalMotor init(electricalMotor: ElectricalMotor) { self.electricalMotor = electricalMotor } } class Model☰ViewController { var electricalMotor: ElectricalMotor! } CONSTRUCTOR METHOD with dependency injection 23

Slide 26

Slide 26 text

class Model☰ { let electricalMotor: ElectricalMotor = Injector.resolve(ElectricalMotor.self) } # BAD! ⚠ Inversion of Control is important! with dependency injection 24

Slide 27

Slide 27 text

tools for dependency injection TYPHOON DIP SWINJECT* [] & * my favorite! CLEANSE 25

Slide 28

Slide 28 text

What about decoupling the app flow? performSegueWithIdentifier("startCar", sender: self) STORYBOARD pushViewController(CarStarter(), animated: true) presentViewController(CarStarter(), animated: true, completion: nil) OLD FASHIONED WAY 26

Slide 29

Slide 29 text

There is a way. 27

Slide 30

Slide 30 text

New Kid on the Block THE COORDINATOR 28

Slide 31

Slide 31 text

The coordinator plugs into existing patterns. Except for VIPER, where it’s already there. 29

Slide 32

Slide 32 text

MVVM-C MVC-C
 WHATEVER-C 30

Slide 33

Slide 33 text

The app coordinator handles the navigation flow, decoupling the controllers from each others. coordinator 31

Slide 34

Slide 34 text

coordinator APP COORDINATOR AUTHENTICATION COORDINATOR FEED COORDINATOR […] AUTHENTICATION VIEW CONTROLLER PROFILE VIEW CONTROLLER FEED VIEW CONTROLLER DETAIL VIEW CONTROLLER 32

Slide 35

Slide 35 text

So, which pattern should you choose? 33

Slide 36

Slide 36 text

Rule of % Very simple app App with a lot of UI states and asynchronous behaviors Very complex app built with a large team MVC MVVM VIPER 34 Not meant to be taken as a hard rule.

Slide 37

Slide 37 text

Don’t try too hard to pick a fitting pattern. Try harder to keep the code clear, testable and maintainable, because… 35

Slide 38

Slide 38 text

— Christian Tietze You need knowledge and experience and creativity. When you can come up with something on your own, you can interpret the rules of VIPER, layered architecture, or whatever else you find on the web properly. You can pick up new ideas and come up with solutions on your own instead of looking for a fitting solution out there. “ ” 36

Slide 39

Slide 39 text

Questions ? 37

Slide 40

Slide 40 text

38 resources iOS Architecture Patterns @borlov MVVM is Not Very Good @khanlou MVVM is Exceptionally OK @ashfurrow MVVM Is Quite Okay at What It Is Supposed to Do @ctietze Let’s Play: Refactor the Mega-Controller @andy_matuschak

Slide 41

Slide 41 text

39 resources Coordinators Redux @khanlou Improve your iOS Architecture with FlowControllers @merowing Coordinators with Storyboards @apokrupto