Slide 1

Slide 1 text

Reactive Architecture in Flutter Burhanuddin Rashid Technogise @burhanrashid52

Slide 2

Slide 2 text

What is Architecture ?

Slide 3

Slide 3 text

Architecture Software architecture refers to the high level structures of a software system and the discipline of creating such structures and systems. Each structure comprises software elements, relations among them, and properties of both elements and relations. The architecture of a software system is a metaphor, analogous to the architecture of a building. It functions as a blueprint for the system and the developing project, laying out the tasks necessary to be executed by the design teams.

Slide 4

Slide 4 text

Ahmedabad

Slide 5

Slide 5 text

Separation of Concerns

Slide 6

Slide 6 text

Expectations

Slide 7

Slide 7 text

Reality

Slide 8

Slide 8 text

Reactive

Slide 9

Slide 9 text

Ahmedabad

Slide 10

Slide 10 text

Reactive ● Asynchronous data streams ● Events ● Triggers by data streams ● Notify Listeners

Slide 11

Slide 11 text

Architecture in Flutter ● Redux ● Scoped Model ● BLoC

Slide 12

Slide 12 text

Architecture in Flutter ● Redux ● Scoped Model ● BLoC

Slide 13

Slide 13 text

Scoped Model

Slide 14

Slide 14 text

Allow to pass a data Model from a parent Widget down to it's descendants (child). Ahmedabad Parent Child Child

Slide 15

Slide 15 text

Counter Example ... return Scaffold( ... body: Center( child: Text('$_counter', style: Theme.of(context).textTheme.display1), ), floatingActionButton: FloatingActionButton( onPressed: _incrementCounter, child: Icon(Icons.add), ), ); ... class _MyHomePageState extends State { int _counter = 0; void _incrementCounter() { setState(() { _counter++; }); } }

Slide 16

Slide 16 text

Building complex app is never easy

Slide 17

Slide 17 text

Let’s see the code

Slide 18

Slide 18 text

Step 1: Add Dependency pubspec.yaml dependencies: scoped_model: ^0.3.0

Slide 19

Slide 19 text

Step 2: Create a Model class CounterModel { int _counter = 0; int get counter => _counter; void increment() { // First, increment the counter _counter++; } } extends Model // Then notify all the listeners. notifyListeners();

Slide 20

Slide 20 text

Step 3: Add Scope Model class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return } } MaterialApp( debugShowCheckedModeBanner: false, home: HomePage(), model: CounterModel(), ScopedModel( child: ), );

Slide 21

Slide 21 text

Step 4: Add Scope Model Descendant class HomePage extends StatelessWidget { ... return Scaffold( ... body: Center( child: ), floatingActionButton:..., ); } ScopedModelDescendant( }, ), Text(model.counter.toString(), style: Theme.of(context).textTheme.display1); builder: (context, child, model) { return

Slide 22

Slide 22 text

Step 5: Update Scope Model Descendant return Scaffold( ... body: Center(...), ... floatingActionButton: ); ScopedModelDescendant( }, ), FloatingActionButton( onPressed: () { model.increment(); }, child: Icon(Icons.add), ); builder: (context, child, model) { return

Slide 23

Slide 23 text

Demo

Slide 24

Slide 24 text

No content

Slide 25

Slide 25 text

Pros

Slide 26

Slide 26 text

Independent Widget return Scaffold( appBar: AppBar( title: Text("Scope Model"), actions: [CartCount()], ), body:(...), floatingActionButton: ScopedModelDescendant( ... ), ); class CartCount extends StatelessWidget { @override Widget build(BuildContext context) { return Center( child: Stack( children: [ // Cart icon, Align( ... child:Text("1")), ], ), ); } }

Slide 27

Slide 27 text

ScopedModelDescendant( builder: (context, child, model){ return }, ) return Center( child: Stack( children: [ // Cart icon, Align( ... child: ), ], ), Text(model.counter.toString()); CardCount

Slide 28

Slide 28 text

No content

Slide 29

Slide 29 text

Cons

Slide 30

Slide 30 text

Rebuild all the ScopedModelDescendant<> Widgets

Slide 31

Slide 31 text

No content

Slide 32

Slide 32 text

Disabled rebuild ScopedModelDescendant( rebuildOnChange: false, builder:..., )

Slide 33

Slide 33 text

BLoC Business Logic Component

Slide 34

Slide 34 text

Business Logic ● UI Independent ● Rely on Streams ● Platform independent ● Environment independent ● One or several BLoCs

Slide 35

Slide 35 text

What is Streams ?

Slide 36

Slide 36 text

Conveyor Belt ● is Stream ● is data controrol by StreamController ● is listeners

Slide 37

Slide 37 text

Ahmedabad Conveyor Belt

Slide 38

Slide 38 text

Step 1: Add Dependency pubspec.yaml dependencies: rxdart: ^0.19.0

Slide 39

Slide 39 text

Let’s see the code

Slide 40

Slide 40 text

Step 1: Create BLoC class CounterBloc { int _counter = 0; void incrementCount() { _counter++; } } StreamController _counterController = StreamController.broadcast(); Stream get outCounter => _counterController.stream; _counterController.sink.add(_counter); void dispose() { _counterController.close(); }

Slide 41

Slide 41 text

Step 2: Adding StreamBuilder StreamBuilder( ) key: // Optional, the unique ID of this Widget... stream: // The stream to listen to... initialData: // Any initial data builder: (BuildContext context, AsyncSnapshot snapshot){ if (snapshot.hasData){ return // Widget to be built based on snapshot.data } return // Widget to be built if no data is available },

Slide 42

Slide 42 text

Step 2: Adding StreamBuilder @override Widget build(BuildContext context) { return Scaffold( ... body: Center( child: StreamBuilder( )... final CounterBloc _counterBloc = CounterBloc(); initialData: 0, stream: _counterBloc.outCounter, builder: (context, snapshot) { return Text(snapshot.data.toString(), style: Theme.of(context).textTheme.display1); },

Slide 43

Slide 43 text

Step 3: Update Widgets final CounterBloc _counterBloc = CounterBloc(); ... return Scaffold( ... body: Center( child: StreamBuilder(...), ), ); ... floatingActionButton: FloatingActionButton( onPressed: () { }, child: Icon(Icons.add), ), _counterBloc.incrementCount();

Slide 44

Slide 44 text

Demo

Slide 45

Slide 45 text

No content

Slide 46

Slide 46 text

Problem Need to create BLoC for every widget

Slide 47

Slide 47 text

BlocProvider

Slide 48

Slide 48 text

Didier Boelens https://medium.com/@boeledi

Slide 49

Slide 49 text

Generic BlocProvider class BlocProvider extends StatefulWidget { } final T bloc; final Widget child; BlocProvider({ Key key, @required this.child, @required this.bloc, }): super(key: key);

Slide 50

Slide 50 text

BlocBase abstract class BlocBase { void dispose(); } class CounterBloc implements BlocBase { ... @override void dispose() { _counterController.close(); } ... }

Slide 51

Slide 51 text

Implementation MaterialApp( home: BlocProvider( bloc: CounterBloc(), child: MyHomePage(), ), ) class MyHomePage extends StatelessWidget { @override Widget build(BuildContext context) { CounterBloc _counterBloc = BlocProvider.of(context); return .. } class CartCount extends StatelessWidget { @override Widget build(BuildContext context) { CounterBloc _counterBloc = BlocProvider.of(context); return ... }

Slide 52

Slide 52 text

Demo

Slide 53

Slide 53 text

No content

Slide 54

Slide 54 text

Ahmedabad

Slide 55

Slide 55 text

WhatTodo

Slide 56

Slide 56 text

Ahmedabad Create Task Create Project Create Label

Slide 57

Slide 57 text

Ahmedabad

Slide 58

Slide 58 text

Ahmedabad

Slide 59

Slide 59 text

Resources ● Didier Boelens blog https://www.didierboelens.com/2018/08/reactive-programming---streams-- -bloc/ ● Scope Model https://pub.dartlang.org/packages/scoped_model ● WhatTodo https://github.com/burhanrashid52/WhatTodo ● Scope Model Example : https://bit.ly/2Q5gEQN ● BLoC Example : https://bit.ly/2OQs2ve ● Bloc Provider Example : https://bit.ly/2DJYsq9 ● MTechViral : https://bit.ly/2Sb5isS

Slide 60

Slide 60 text

Burhanuddin Rashid, Technogise @burhanrashid52 Thank you!

Slide 61

Slide 61 text

No content

Slide 62

Slide 62 text

No content

Slide 63

Slide 63 text

Q&A https://burhanrashid52.github.io