Flutter Architecture: BloC and DDD, Talks by Felix Angelov and Majid Hajian

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] hey everybody can you see me can you hear me any feedback yes perfect so uh thanks for the patience we had some little technical issues uh you know probably it's our first virtual meetup this time so as you can see we are streaming live from nuremberg which is in my bag um just a quick question where are you all from that's uh the first thing which actually interests me uh because we have like an international um audience right now we can stream internationally um we have international speakers so just post into the uh chat where you're from nuremberg great italy yeah we're from italy or anyone else venice nice okay the others wow nice taiwan poland great okay cool so uh under franken okay so uh yeah i've prepared actually um as we are from nuremberg i of obviously have to drink my beer and this is not sponsored and my pretzel so nothing can go wrong from my side so uh now i'd like to introduce you to um our speakers there was a little um uh switch on the schedule so uh the schedule um as you could see announced felix as first speaker but um we just uh switched the schedule so uh majid will be the first speaker all right majid are you ready absolutely perfect so um yeah majid happy to have you here thanks thank you oh wait i nearly forgot something i have to switch places from nuremberg to oslo welcome to oslo all right thanks a lot for joining us today um the first the first time uh i met you was actually on flutter europe which was a great event um as we probably all know or a lot of us know so there was also uh where i i listened to your talk and it was great thanks for that uh and so for me it was actually uh clear that i wanted to have you both uh on a stream here um and so majid um i know that you are an organizer of gdg uh oslo a co-organizer uh an organizer of diff more others meetups in oslo could you probably introduce yourself because you can do it better than i can yes yes sure my name is majid as you said i am a passionate developer just like you um and also um i do a lot of things regarding the organizing meetups and conferences i do organize flutter oslo gdg oslo mobile oslo and also we have couple of conferences in oslo mobile era you may have heard also we have ng viking i'm one of the organizer and a few others so i'm very very into the community i really like to contribute to community in any way that i can so meetups and conferences are one way and also i'm a speaker as you see i regularly speak especially about flutter and pwa this is my two passion and um i also have written a book here so i'm gonna show it actually my slide later and today well that is the talk that you mentioned i gave in flutter europe but with a lot of modification i have received a lot of feedbacks and a lot of contribution actually to the repo thanks to everyone who contributed and then we now have um a better maybe a better slides and also like presentation as well as uh code base and architecture for both simple apps and a little bit large apps like enterprise apps which initially was my target but now i also can propose to smaller and simpler apps and we're not talking about block a lot so then the next stack will be awesome so you have to stay and then you have to watch felix afterwards because in my talk my favorite of course my favorite library is blog and then you have to listen to flicks afterwards definitely so how did you start yeah cool again happy to have you here so go for it thank you thank you very much so then let's get started uh i um just show me like a red uh like a green light if everyone sees my everyone sees my my slides right now yes all right perfect then let's uh let's get started as you see here i'm gonna talk about the strategy domain driven design and today and see how actually ddd can help to improve our architecture then i will come up with some architecture proposal for you for both enterprise and simple apps which of course i have implemented in my apps uh during the last one and a half year when i started working with flutter and then this is our mostly my experience so let's uh let's uh get started so as i mentioned i upgraded everything uh this month so if even if you have heard about my talk in flutter europe you still may see a few new topics here so it's not it's not going to be the same as i gave this talk in flutter europe let's move on so when we are actually building a software we're going to have like a lot of things that we need to figure out we need to talk to business we need to talk to other developers maybe other teams you know a lot of things that we need to take care and of course well when it comes to software development or maybe app development um we will actually learn from all of those experiences that people share with us like with blogs and a lot of things so um but of course sharing experience is great but uh we will always get back to best practices and sometimes we combine these best practices and create patterns and when we actually add a little bit of philosophy to all of this then we create methodologies so here is one of those methodologies so domain driven design which it says that it's here to help us to tackle complexity of the software development but let's let's see here today why we need to main driven design why i'm actually talking about this why i'm i really like the ddd and how it can help us so most of the theory behind the talk about the strategic domain even design is from of course the main book the blue book eric evans so you may have heard or you have read that already and two other books which is like a complimentary to this book there are other books as well professional dvd and and uh also the implementing dvd so you can also go through amazon or other you know book library and get and read that if you are interested to read more so but uh imagine the first book is around like maybe eight seven hundred pages and each of the other books are around 700 pages i'm not able to like summarize maybe 2 000 pages in 30 minutes or 40 minutes it's a lot of things that needs to be discussed a lot of a lot of ideas and a lot of um theory here as well as a lot of practical uh you know examples but we're gonna we're gonna go through some of them but the reason that i really like dvd is that you know when we start a project it is very very uh like a normal uh chart you may have seen in your career so far so we have of course sometimes uh like a resource capacity is limited or it's fixed and then as project is growing so the complexity of the project also grows that is very obvious but what adv helps us and promise us is to at least tackle this complexity until it can be manageable for the team and the the whole organization that is the promise so of course it it depends on like how you do you implement it how you you know take advantage of it a lot of things but that is what it says to us but why and and when ddd can help like especially in floater app let's say but let me let me tell you this uh when we are talking about flutter app maybe we can categorize it in four different uh categories let's say um the apps or software in general that they are dealing with data the big data and other things some apps or some softwares they need just performance and some of them needs be they have like a business logic a complex business logic like erp systems a lot of things that needs to be handled there and and some of the apps are just a technical complaint they have just technical complexity right like um you need to come up with an algorithm to solve a problem and that's not a business it's just a technical complexity when ddd shines is where you your app or your software is uh focusing on business logic complexity or or there is business logic complexity so if your app doesn't have this complexity you should probably not even look into the dvd at all so we're talking about this layer of complexity when we are talking about dvd and dvd is a great example of the com combination of two great principles of software yagni you're not gonna read it and kiss which is keep it short and simple and probably right now many of you just say like well ddd is a very very complex topic so and you're saying that keep it short and simple but of course uh we're talking about like a very big system right and uh in this talk of course we're going to take advantages of these principles but the main important thing is that we want to be inspired by ddt we're not gonna actually uh implement the whole ddd you know things into a one slaughter app but we're gonna be inspired and see how it can help us that is very important so at the end of this talk i will show you some proposal uh regarding the architecture as well as uh folder structure and etc and you see that i will tell you that this is not just a hard rule you have to follow but you need to be inspired and then take advantage of it and then change it in a way that it works for you so uh very quickly summary about the talk today of course we're gonna go through dddd if you're not familiar with the concept and the terms the most important ones we go through it today very quickly and don't worry about it you will learn about it today strategy domain driven design is one part of the ddb so which is the main focus of this talk we're gonna talk mostly about the theories of course not the implementation how you have to write a code that is mostly up to you and that's completely different but the most important part of the part of this talk is to show you how you can leverage a strategy domain even designed to architect your app or close yourself to the business and then i'm gonna have two proposals for you uh enterprise architecture and then a simple architecture which uh i have implemented in my simple apps and it works for me very well for for sure we're gonna see the demos as well so uh i don't think i need to introduce a game myself but that was my plan to introduce at this time um you know just ask me in the beginning of the cops that talk so i guess you all know me right now uh so i'll just move on to the next slide let's uh go back to the ddd what is the main driven design the domain direct design is telling us when we develop a software actually the main focus usually we as a developer we are very geek we want to just sit and write code you know but but the ddd says that this is the technology we are using is not the things that you need to focus probably it's the business things that you need to focus and of course there are business problems that these softwares that we are writing codes for or we are creating they're going to solve those problem so for for writing those code and building these apps we of course need to understand our clients needs right so and when it comes to the client's need and and our software then of course the domain is very important the domain is where these software is going to serve that is the core domain in dvd so let's uh uh go back to the ddd and two part of it so dddd has uh as proposed in the book has two uh part strategic design tools and tactical design tools this strategy part is mostly focusing on the theories and how you should create your domain your core domain your sub domain context and etc that we are going to go through today and the tactical part is mostly dealing with the implementation and writing code how you have to organize your code write your function the name of function and etc so very deep so we're not going to touch that today it's very little time for this talk but we go through the strategy part of that now so imagine that in a strategic part of the domain driven design why i think it's so important is that because when you are planning to create a city and if if you have a plan if you have a strategy how to create it you may end up creating a city like the picture on the right it seems like it seems like modules and and you know it's very organized that they are they have ways to each other no colliding so you you clearly see the path but on the left side when of course when there is no plan everyone can create everything so maybe in the beginning one two three house is great but then when you have millions of house then you will end up having a mess that's why the strategy part of the domain driven design is very important so we need to very seriously take into account when we build our software and as i show you in the picture the strategy part is mostly about decomposing so decomposing your software into the different sub domains and of course you need to understand your core domain and what is the code name the core domain is where you are building software to serve the business to solve the problem even if you are a software company still you you have a core domain in your company and well in let's give an example for instance if there is a veterinarian uh office for instance the core domain is like serving and helping pets and people you know and etc but of course the software here the the core domain is quite broad and very big so we need to take it to the smaller piece that we can manage it so that this veterinarian could have employees management could have uh like appointment management maybe something else you know these are finding these sub domains that there is a problem there and you need to solve it right so another example is let's say we want to build a manufacturer app so we're going to help a manufacturer to have an app to solve their problem here so we're going to have of course us different sub domains here we're going to have cells accounting product catalog marketing manage employees these are and maybe more these are the sub domains of this main core domain app let's say so when it comes to these sub domains when we are going to solve the problem then each of this subdomain may have their own entities but of course these entities can also be shared like for instance in cells we have a customer an employee department or subdomain we have customer marketing we have customer accounting we have customer and these are our customer same customers same id but the thing is that each sub domain they have their own interpolation of these as customers so the customer in sales they are interested in different things they are maybe interested in the interest of the user but in the marketing or maybe in accounting they are very interested in their payment method and how much they paid you know and in employees maybe customer is very important to know about the emails and names and etc when we are actually creating these isolated of entities and these problems that we are going to solve here with the solutions then we are creating these bounded contexts so you can imagine that in our app we can actually create these bounded contexts by maybe name space or maybe folder and maybe like maybe different projects so you can think of it like this and each bounded context it's going to have a ubiquitous language when i say ubiquitous language language the first thing it came to the mind is that okay that means everyone should speak one language well well that's not going to work um the ubiquitous language in domain driven design is meant to be isolated into the bounded context so that means so if you are in sales and you are talking about customer everyone in that sales including a product owner developers business everyone should talk the same language you need to unify this language between stakeholders and developers and business and that is very important so when when in cell or when an employee is up to may or like that folder you're talking about a customer everyone including the product owner and business should understand what you're saying and also you need to reflect this on your code you should not uh have something on the map or on the pitch page and then you write a different name on your code that is what we are talking about this ubiquitous language but there is no such a software that every single sub domain is isolated and they don't need to talk each other that's that's impossible right so we need to we need to uh these sub domains and bounded contexts they need to actually talk to each other so and when they actually go and talk to each other they asking about some information that is when we are creating the context map there are different ways of doing that as proposed in dvd for instance if if we let all the sub domains uh in this case here a bounded context i correct myself if we let all the bandwidth contexts talk to each other in any way then we will end up have a mess right so we should have a better plan we should have something that works better here one thing that is suggested and i really like and i think it works in flutter app too very well is shared kernel you just think of it as a common module or a common folder that contains all the common things that you need to use in different parts of your application and of course all the different developers or maybe if you have more teams more teams working on one uh one app maybe they all can contribute to these share kernel this is one one example here is like user authentication that is something that should be shared between all the supplements so everyone can log in and get access or be authenticated and authorized right that works very well but then it comes to a way that if everyone wants to actually come take care of one thing or one common thing then it's gonna be a little bit risky because well you you rely on me to fix this bug and then i wait for you because you are also responsible and then at the end of the day no nobody does that right maybe sometimes uh we need to come up with a better idea and one of the things that actually is proposed in dvd is creating an open host service that is a tiny or a thin layer in each bounded context that has a public interface to other uh bounded context so if you need to get something from cells from order instead of going through the whole sub domain whole things you just go through this api okay i translate open house service to our language that is actually an api so you just go through the api and that is a public api which more or less stay the same always so if you want to change everything under the hood it's fine you can change it but your public api for other um bounded context remains the same always so but eric here once uh created this navigation map he called this navigation man you see that it's a lot of thing in this map and a lot of theory that we need to learn about it of course i'm not also an expert in ddd um just sharing my experience how i used it and what i explained by now and i'm gonna actually use it is only a few part of it and if you want to learn more definitely you should get back to the book and all the other books and tutorials and read more about it and try to see an actual implementation of all of these things in this map okay but how that could help in flutter right let's uh talk about the enterprise app i'm talking about an app that is super big i was part of an app which we developed over a year and that has a lot of screen like maybe around 600 or 700 by now and it's a very complex app a lot of logic and also it's an iot app which means um it also has like ai things inside the app a lot of things is happening in this app and many many developers were part of developing this app so then when we started maybe a year and a half ago and then well at that time flutter was quite new no architecture or at the moment if you search you will find probably a lot of different things for flutter too but at that time it was a little so we came up with our ideas and how we can create an architect that work for us so then we could do this way so this architecture is very very similar to onion architecture plus a clean architecture from uncle bob and inspired by layer architecture and the some part of these two architecture as well like combining three different architecture as i say right now again you can definitely choose maybe just clean architecture that's of course uh you know well known and maybe you should stick on that there is also onion architecture there is also layer architecture you know but this is what we did in our app very close to these um solutions but i like to share this and show you how we did it so you may learn and continue learning afterwards we split our app to the different uh sub-domains as i said so that is what i'm suggesting so if you are creating like an e-commerce app you can create your cells up domain you can create your catalog or common folder as i mentioned so the first layer here so the enterprise architecture we're gonna have four layers so the top layer is presentation here of course what i'm proposing here is to create screens widgets that have ui and of course logic holder my favorite logic holder here for managing the state is of course block so in the simple architecture i'm going to talk more about block here and so um you create your smart uis where you want to have these screens and show based on the route maybe they have a route and they show something and then maybe you also have some widgets which is shared between these screens too so and the second layer is application layer where you have your facade pattern that means you're simplifying all the other layers underneath to a very simplified layer that presentation layer and later api has access to it so then the third layer is your domain layer that is the most important part of these layers for each sub domain because what they do they are completely isolated and they just know about this domain they know about the interfaces that we are going to create for this domain entities object values and logics everything here in this layer none of the other layers this layer cannot get anything from other layers but other layers can definitely get access to it and know about this domain okay good and that's the last and the fourth layer is infrastructure where you get the data so it's that the data layer is where you are asking for different source of data local data remote data gel location or other stuff you create your model you serialize the serialize and at the end of the day you have a repository that also can combine different data sources and decide what to send up to the application layer so for instance if you have a connectivity problem in your app and if you want your user to get access to the cache data based on the connectivity of course you create two different data sources and in in repository then you decide based on this connectivity where to send which one to get and send it up so and how does it work in in from top to bottom so as you see here the suggestion is what we did is that the presentation layer get everything from application and the application goes to domain and infrastructure so and the first thing infrastructure that is the application is uh working from that is um um sorry i got a message and then i was redistricted so and it's a repository so and then infrastructure of course they know about the domain so what kind of functions we need to implement and what is our entities and these models should what should that do that and those kind of things and if the suggestion here and what we did is here so um if you need to get access to some data for instance catalog is a main uh soft domain in this app right so you need to get access to the catalogs to the product catalogs so the cells can get access not through all the other layers but you create a tiny things like api and you expose those things that you want others to get access to it and that api will remain same even though you're changing underneath everything so for instance if your um data sources is changing from serializing from json to i don't know from maybe xml that does not affect any other layers so just in one layer and one tiny part and then the api everyone else every other subdomain they are safe and fine but the good thing about this is that we created a lot of encapsulated packages in our repository we have uh local packages and in the app and we could you could create local packages and then if you create a second app or third app so simply you can use these packages that is a great way of decomposing your application to smaller piece but how about the smaller app this is a lot of layers and a lot of boilerplate code for a smaller app right maybe my app is smaller and i just need to leverage but not that much because you know if you're developing a very simple app maybe 20 30 screens then why should you even do all of this maybe you should go simpler yes uh i propose two layer architecture here and the presentation layer as we discussed but with less headache the thing is that you create your screen and you definitely use block here and block in this manner works very well because in each screen you can have your own state management with block and that is encapsulated into the screen that is the best way of decomposing your small piece of application into the subdomains let's say so my recommendation and what i did and works very well is block and of course we have an awesome developer on the car right now so he's gonna talk about he's gonna elaborate about that soon so the second and just the second layer is logic and the logic layer i'm proposing to create your repositories and business logic here if you want to change any things and you want to send it up to your block in that case and your screen can get access to ads so repositories are where you are combining again all of those data sources and merging and then sending up and also adding your logic and then send the state to your blog and blog can send it over to screen to update the ui and a shared layer between all of that is because your app is small maybe not too many data sources is just a data layer for all of them so you don't need to create uh probably an an encapsulated layer for each of these subdomains that could be like a general data layer and then you could have your data sources remote or local and then your models to serialize and deserialize your data sources way smaller like two layer presentation logic you can simply create your application uh you decompose your application to smaller piece and then you have your data layer and get the data and send it up to other layers very simple let's uh quickly look at uh these links will be pro hopefully post uh to the twitch or other uh um stream um places also i will tweet uh these uh um slides afterwards so you can get access to everything no worries but that is the url i created for my demo app very quickly let's go through it the advanced or enterprise architecture this is how we decompose that is one example the catalog as you see here uh that is very uh the the one of the criticizers i get in front of europe people came to me and said it's too many folders here so of course uh this is my probably and my team um taste but if you don't like this folder and the structure feel free to just remove them and add your name to files and then have a flat folder the the most important thing is that you should know about these layers and you should interact with them accordingly that is important but how you uh structure it or different way it's totally up to you be inspired as i've said so let's go to the simple one and the simple one as you see is very simple very here we have a presentation layer for catalog and that has two screens and each screen has this uh it's its own state management which is block as i said it works very well in this architecture and i strongly recommend it and then you have your shared module common put your common modules and widgets over there and then use it in different sub domains and then you have data sources which is shared again i don't have to talk about dependency injection in this architectures because it is also very important how you manage these dependencies but of course uh you have time on your time your free time go through the github and also my presentation time to time and try to go back to it and learn about it maybe you come up with other ideas too and if you have any questions regarding the dependency injection just tweet me i will definitely answer as i said here this is not hard rules that is only a guidance for you and i believe that we should let dvd guide us not just tell us what to do exactly so just be inspired and follow your uh way to implement that things and what we learned today quickly we go we went through dvd and the main important uh like terms in ddd and we went through the strategic part of it so how we could uh use some of this and the composer application and we then see some architecture inspired by those ideas and by that said um thank you very much again to listening to me if you have any questions later tweet me or send me an email i'll definitely answer your question that is the link to the slides if you want to go back to it i will definitely also tweet it afterwards and i don't want to wear i keep felix waiting he has a lot to say about black i'm very uh passionate right now to just see him so i'm done uh majid there's uh i just posted a link where the audience could ask questions so you can open that uh or should i open questions um you can see it in twitch but i can also pause it here right actually i don't have twitch open so because i don't wanna see myself delayed a little bit i just posted it in this uh yeah all right [Music] so the first one while domain driven example provide many technical benefits do you mean this one yes okay uh while domain driven doesn't provide many technical benefits it should be applied only to complex domains what do you think well i said uh i think in the beginning of the talk i i agree so um the domain driven design usually is there for those apps that have a lot of business logic complexity but if your app doesn't have that definitely go don't go for that but i also mentioned that although it's designed for those complex apps but nothing has stopped us to learn from those good ideas and then use it in our application right like decomposing and making a smaller piece of the application to be more maintainable it's a good practice why not doing that just that is exactly my point in this talk so we should do that that that is my understanding of uh these tdd at least many actually argue that ddd is not for frontend too i also argue that it's not for front-end maybe but we can take a good part of it and then apply to front-end too so front-end is also like because people write javascript doesn't mean that they don't write code they also write code so they can they can have like a decomposed version of the application smaller pieces and then maintain that and scale that better of course now should i go through all of these questions that means i guess just uh pick pick um some of them but if you have the time ask them yes of course i have time i'm not sure how how how much time you have or feelings have so i can i can answer some of them maybe i can randomly yeah okay okay so let's uh answer this question so someone asked that can you give an example where dvd is not really applicable of course like if you are creating a twitter app similar to twitter don't use dvd so so twitter definitely doesn't have that much business logic for instance it has more algorithm complexity or let's say technical complexity and maybe performance uh complexity so you need your app to work very fast you know compared to be so modular but take again take the good part of the cdd and may apply to those applications too but deeply go through ddd for all apps doesn't work as i said if you're creating like a very big app to or software to create an erp that is definitely where you should look into the dvd uh do you write unit tests during the development of flutter app and what is your thinking process well of course i write test unit tests and in the architecture i again my time was a little bit limited so i couldn't mention that but there are parts of the application that you definitely need to test for instance maybe the domain layer where all of your main important logic or the logic layer in the simple app where all the important logic it's there the unit test is necessary i'm not also a big fan of maybe 100 test coverage under percentage coverage maybe you can go lower maybe 80 or something but it's important to test those piece of application that has the critical port of your application especially the logic layer or let's say the domain layer also regarding the tdd so many ask me okay if tdd works with the domain events of course it works if you like tdd style if you write test before writing code that works very well and if you write code and then test that also works very well combination of both works very well so that means maybe sometimes when you know exactly what you want to do and you have your plan the tdp works very well you don't you don't maybe lose that much time but if you don't have you're experimenting with api let's say uh is this working or maybe something else or maybe something else and that's where you probably should write your code and then test it later when you know exactly the code is done right so you don't waste time to just fix the test even if you don't know what you are going to do at all uh that is my understanding so felix maybe can elaborate on that later um [Music] why the application layer uh talks directly to the infrastructure wouldn't be better if talks only to the main layer domain layer is where is actually the main layer is the core of your application so that is our isolator right but the domain label should tell other layers what is inside this layer and what are those interfaces what are those entities and models and value op keys right so that the application layer goes to the infrastructure because it needs to get data from somewhere and the repository where you combine all of those data sources and add your logic to it to send it off is where it needs to get access to and it goes to domain layer because it needs to know what should get access to what is the entity to get it we'll get it or we receive it later you know that's the reason um why do you think about 100 megawatt google store limited i i don't think this is the ddd uh what was your test strategy we used both as i mentioned the tdd and code first test later so some of some part of our application was fairly clear and we wrote tdd but some part of the application wasn't clear and we were experimenting to eva to evolve the api and then we wrote code then we tested when we it was confirmed um okay um i think uh you explained very well you answered very well to all the questions or um nearly all the questions um let's make a clear cut right now here sure maybe um for the audience we will have a short break of five to ten minutes let's say 10 minutes to simply regain energies uh get some drinks um or something to eat and we'll see back here in 10 minutes so thank you all for joining thanks majit for this great talk um see you back in a minute [Music] [Music] [Music] [Music] so [Music] um [Music] hey i think we are back can you hear me hear me and see me and felix hello testing feedback from the chat no one's answering they're all like we've seen majeed's amazing talk so we're good now okay hi felix so you hear us folks do a thumbs up or something hit me hard okay marco do you think that we are we can go okay let's simply start so thanks again i hope you got some drinks uh something to eat uh you regained your energies um i'd like to introduce to you felix oh i forgot again i have to switch places let's go from oslo to chicago um yeah gloom in hello chicago okay felix um thanks for joining us thanks for having me yeah you're one of the great maintainers of the flutter community in my opinion you uh maintain the flutter libraries uh which make it easy to implement the flood the block pattern uh in any of other applications so um yeah i just send over the word to you introduce yourself and um thanks for being here awesome yeah thanks for having me so yeah i'll do a quick intro um as you mentioned my name is felix angelo i'm a software engineer currently working at very good ventures so for those of you who don't know very good ventures they made the hamilton application and they were like one of the first companies like focused strictly on building mobile applications in flutter so they do like pretty much everything from building apps from scratch and flutter to helping augment existing companies who are trying to transition into flutter so if you have any questions about any of that feel free to reach out to me and before that i was at bmw and i helped i was fortunate enough to help bmw go through their transformation of going from two code bases one ios and one android into flutter so we had that opportunity to go over the course of like a year and a half rewrite the entire bmw connected mobile application in flutter and a lot of what you'll see in this talk basically came out of that period of time where we were trying flutter early on before it was even 1.0 and experimenting with different ways to structure our apps and manage state and that type of thing so yeah that's pretty much a quick summary about me and today we're going to be talking about i want to start off just talking about like the block pattern itself like what is the pattern really and then how does the block library fit into that pattern and then hopefully do some live coding i will try to make this presentation more live coding oriented and if you're curious to see like a more um like slide driven presentation i'd encourage you to check out the flutter europe talk and i'll um have a link for that at the very end so you can check that out on youtube or you can look at the slides so yeah without further ado let's get started so for those of you who don't know um as majid mentioned like uh the block pattern is something that is pretty prevalent in the flutter community it was one of like the earlier patterns proposed by google for how to manage save and decouple ui from business logic and it's kind of like this just theoretical concept or at least that's how it started off um and there were like a couple of rules that you had to follow just so that you had this like block component and i tried to like find those rules and enumerate them to the best of my ability and so like in general we can define a block in this block pattern context as being a component that basically separates its logic and is encapsulated like totally in isolation it has no idea what platform it's running on it has no idea if it's flutter on the other end consuming it or if it's angular dart or if it's a dart cli so it's removed as far as possible from the ui layer it relies on sinks and streams so for those of you who are familiar with like asynchronous programming and dart um you'll use things in streams to basically represent a continuous flow of data in your application as opposed to futures which are just like one-time asynchronous operations and then like obviously we want the blocks to be platform independent and environment independent so like one of the main things that the block pattern was trying to accomplish early on was we wanted to be able to share code between angulardart and flutter since flutter for web didn't exist early on and so that was like a really cool thing that you got out of using this pattern was like you can reuse like maybe 75 of your logic in your application and just rewrite the front end and then um yeah you don't have to take that like step of converting everything over from like angular dart to flutter so you get more of a true cross-platform experience and so um if we had to draw like a little diagram this is like i'm not a great artist but i tried to kind of make a diagram showing you what the block pattern kind of might look like so like in the center we have our business logic component right and then we can have widgets or whatever it is on the other side it doesn't have to be widgets like i mentioned that are pumping events into this block and notifying it like hey this happened that happened whatever the block then says like okay widget one gave me whatever information i'm going to do something with it and i'm going to push it out from the other end and have this stream that anyone on the other end can listen to so it could be that like the same widget is adding and listening it could be that one widget is adding and another widget is listening it's very flexible and like you can see how this could be really useful in terms of isolating the logic none of these components really know what's happening inside of this box they just say like here take whatever piece of information that you need and then on the other end give me the result back and so with that pattern um we can basically see an example of a potential implementation of this don't worry too much about like every single line of code and understanding it but like this is kind of um describing our progression at bmw and uh continuing at vgv of how block like how our experience is shaped where we are today and so initially we started off saying like this is a cool pattern and we think it's really powerful and obviously like google's using it internally and stuff like that we see all the advantages so let's give it a try and let's try to implement it and we tried implementing it with rx dart at the beginning so we i used behavior subjects and published subjects and then we basically take this like super simple counter example right like the traditional create or flutter create gives you that counter application where you can just click on a floating action button and increase a number and so if we were to basically create a block for this we can have the value of our account and then we can expose a stream that anyone can listen to who cares about what the value of that counter is and we can expose a sink to anyone who wants to be able to make changes to that counter but no one knows actually what happens when the sync has something added to it they just basically listen on the other end to the stream and then they react to whatever comes out of that stream and so we encapsulate this logic which in this case is just this one line where we're incrementing our counter and then pushing it out on the stream and everything works really nicely but there were a couple things that we weren't super thrilled with like i don't know if people are familiar with rx dart or like reactive programming in general but it can get really complex especially for people who aren't familiar with it and at a large scale it's really important to have all your developers feel comfortable with the tooling that you're using in my opinion and so like the steep learning curve of reactive programming was kind of a turn off for us because we had bad experiences in the past of like oh we use rx swift everywhere in our ios code bases and like um it basically like becomes a mess at some point if you don't really like um try to be diligent and maintain like a unidirectional data flow and like keeping your subjects private and stuff like that like it can get really messy so that was one concern that we had and then the other one was this like memory management or resource management piece where we have to always be careful about um not forgetting to close our subjects and cancel subscriptions and things like that and it's just like a manual step that's really easy to forget um and so like we're kind of like this is really cool but at the same time like there's some things that we would like to improve upon and if we looked at like a flutter application consuming that block we can use the built-in stream builder widget in flutter within a stateful widget so we'll create our counter block instance our stream builder can take the counter stream which comes out of the block and then use this builder which comes with the stream builder widget to basically react to any time something is emitted from the stream and of course we have to remember to call dispose on our block whenever our widget gets disposed so that we can free all the resources and cancel subscriptions and things like that and so pretty straightforward like everything works it accomplishes the goals of separating ui from business logic but there are some trade-offs like potential increased complexity because of rx or potentially forgetting to free resources and you deal with async snapshots and forgetting to handle error cases things like that um so we decided to try to basically take a step back and take the things that we liked from this pattern and abstract them and make our own implementation or interpretation of the pattern and that's where kind of the block library fits into everything so it consists of a bunch of different packages there's the core block package which is just the dart components that gives you actually like the block class itself and some other core aspects like what a transition or state changes i'll talk more about that later there's a block test package which you would just add as a dev dependency kind of like the regular flutter test or dart test package and it'll help you write unit tests for your blocks the flutter block package which gives you useful widgets basically kind of like a stream builder and other widgets um to basically consume those blocks from within a flutter application so that they're just like widget helpers you can think of them as and then we have a similar thing for angular dart with angular block so if you're building angular dart applications you can still reuse the same block across flutter and angular dart and before i go on like it's actually really funny a few days ago i just was able to release 4.0 so it's a good time actually if you're interested in trying it because it'll uh hopefully there'll be no major changes like anytime soon so it'll be relatively stable and even the 4.0 upgrade was really straightforward in my opinion so if you have any questions definitely let me know and i'll have a link to the website where there's like official documentation and examples later but if you're curious block library.dev is where it's all at right now and so building on top of like the block pattern like the theoretical pattern that i just mentioned um we decided to try to like simplify things and make things a bit more strict and so in terms of the block library we defined a block as a business logic component that only has one input so only one sync and only one output only one stream and anytime a ui component or anyone from the presentation layer needs to notify a block of something it will add an event to the block and then anytime someone cares about the result of the block or the blocked state they will subscribe to the block state stream and that's pretty much it you know everything there is to know about about blocker at least like 95 of it from just this one um picture pretty much so just keep that in mind the whole time and as i mentioned like this works with rx dart this works with um if you use stream controllers like this is not particular to the block library you get this nice separation of concerns so as i mentioned like if we're using this block in the context of flutter the flutter app has no idea what's going on here if i just tap on this increment button as a user the ui layer is telling my block okay the user tapped on this increment button the block is going to do its thing it's complex business logic in this case it'll be like okay my previous state was zero i got an increment event so let me do some really complex math and say okay the next state is going to be one i will toss that one over the wall to the presentation layer the presentation layer will be like oh cool i got a new state from the block it happened to be a one this time so i'm going to update my ui with a one and that's pretty much it so you can swap out the presentation layer you can swap out the block independently of each other they're not tightly coupled which is really cool because you can do things like write an angular dart application as i mentioned on the left and a flutter application on the right using the exact same business logic and all you have to do is write the ui twice as long as your use case stays the same or as long as your feature set stays the same for the most part you should be able to reuse almost all of the business logic which is really cool less code we have to write and maintain and test so it's a big win and so at this point i'm going to diverge from the flutter europe presentation format and go into some live coding and i want to make sure everyone can see everything so can we get like a thumbs up that everyone can read let me just open a file i guess i'll create a file can everyone see this or is it i think we can see it okay cool let me make it tiny bit smaller for myself so my plan uh was basically to kind of go through like a production quality counter if you will and basically show kind of like what are the typical steps that you would take every single time when making or integrating block into an existing application and so i pretty much just have an empty folder here called flutter example actually i'm going to even delete this folder and i'm going to go to my desktop and i'm going to run flutter create most of you are probably familiar with this and i'll just call it block example right so we're literally starting from scratch there's no code yet let me open up oops block example nvs code and let's get started so pretty much uh we have a flutter application oh or we don't where am i block example there we go so we have a flutter application right everyone's probably familiar with this i always do like the same few things at the very beginning so bear with me we're just going to wipe out a lot of these comments and we're going to basically clean up this app so that it only has the bare minimum that we need we don't need cupertino icons we'll come back to tests hopefully if we have time um i'm going to keep material icons for convenience and yeah so let's save that up flutter packages run will do its thing i'm gonna delete the test folder for the errors um and let's just start with we're having my app and uh we're not even gonna actually touch flutter let's just skip flutter for a second so we said blocks are basically decoupled from the platform that they're on and so for that reason we can do something like create a directory we'll call it like packages and in here we can basically create a new package and we'll call this package our counter block so i can take my pub spec from the previous and just swap it out we'll say this is a reusable counter block uh we won't plan on publishing this yet and we need to add instead of a dependency on flutter we will add a dependency on the block library so we said it's at 4.0 and with that we should be able to save and we can do the typical create a library because we're going to be reusing this so we're going to call this counter dot dart don't worry about all this you can re-watch hopefully this later let me call this counter block for consistency and we're going to now get started actually writing the counter block so in our source which is private to our package we can basically use some snippets that i have and you can get these snippets too if you use vs code by just searching for the block extension um wow that's huge but yeah you can check this out it has useful snippets and then also has some other cool things like it helps you create blocks from scratch um and creates the folder structure for you and everything so i'm gonna do it by hand for the most part so that everyone is like on the same page and following along but yeah that's just something that you can do and of course vs code is freaking out so let me restart it um yeah so we're going to start from scratch we're going to create a counter block and we have to define our events in our state so what is our counter block actually going to be converting right and so for sake of simplicity again we're gonna just say like we're only gonna handle one type of event um and it's gonna be this increment event so we're gonna define it as an enum and then it's just going to be converting those events into states again we have to define an initial state so we'll say our counter starts at zero and then our block is going to be converting counter events into integers so that's what this function is is doing so map event to state gets called every single time a block gets a new event and so we have access to that event and our responsibility within this function is to convert that event into some sort of new state potentially you don't even have to you can choose to ignore the event if you want to it's totally up to the block what it decides to do with the event and so let's fix that so it's a little bit better and so now we can basically do a switch in this case because we have an enum so we can switch on the event and in the case where it's a counter event dot increment we can yield state plus one at this point people are sometimes confused and they're like okay where is this magical state coming from um and state is actually a property of this base block class and it allows you to basically ask the block hey at this exact moment in time what is your state value and so at the very beginning it should give us back zero when we yield state plus one if we print what state is right here it should give us 1 and so you can use the internal state variable to basically emit state changes that depend on previous states and so in this case we're just saying we're going to emit whatever our previous state value was plus one right and at that point uh we pretty much are done right so we can create in our um oh of course i forgot i should have created a counter block this is what happens when you rush a counter block folder and let's just move all of the stuff inside of counter block because we can have more than one package inside of our packages so let's just drag those in there and that's probably why vs code was getting mad at me earlier too okay so at this point what you can do with packages is typically you'll see like people put example directories inside of their package so that um you can run that package in isolation and see how it's used so we can create a main.dart in our example and we can basically define a main function and we can say we want to create an instance of our counter block that we just defined counter block did i call it counter block uh i did call it counter block and of course now that i'm moving folders around vs code is freaking out again uh let me restart one last time hopefully that's the last time i've been having analyzer issues recently for some reason especially when moving directories around but hopefully now we're good we have our example we can hopefully import counter block yep oh and i forgot um it's good practice to export the private or the public components that you want available from your library from within that library file so i want people to have access to the counter block when they use the counter package and so we should be able to change this to just use our package as a normal package import and not access source because you shouldn't do that and so now we can basically do some cool things like we can say counterblock.listen and anytime we get a new state from our counter block we can print and then we can do stuff like counter block dot add you guessed it we only have one event that we support so now we can basically come into packages counter block example and if we run this main dot dart we should see yeah we get zero one two three right we're listening anytime the state changes in the block and we're adding a couple of events to it so it starts off at zero and then we add three increments to it and at each point we've updated our counter value so that's cool we see again like this has nothing to do with flutter this is just all dart code right now and um yeah so the next thing i think that is cool to go over is there are some hooks that you can use in block that give you access to things like anytime an event is added or anytime a state changes or anytime an error happens and so i won't go through in detail for the sake of time but the most useful one in my opinion is this on transition and it gets fired right before every state change and the transition contains the current state of the block at the time of the transition it contains the event that was added to trigger the state change and then what the next state is going to be and so we can basically just print transition here and if i rerun the exact same app let me collapse this so it's a little easier to read you'll see we have our initial state gets printed um so that's back here in main our initial state gets printed we add increment and then that's going to trigger on transition we see that okay our block is changing states from zero to one because of an increment event and it's changing from one to two because of another one and two to three because of another one and so you can see like it's pretty powerful that you have this one input and one output to your block and now you're able to basically do things like add universal logging for developers or for analytics or whatever without having to manually write log statements everywhere you can just hook into this on transition callback in blocks and print out or log to firebase analytics or whatever you want to do anytime a state change happens and so um it's actually funny like people were asking tdd should you write tests first should you write tests last i personally write tests immediately after i write whatever code i've written and that's just a habit that i've gotten into um i think like majid mentioned like there's no right or wrong it's whatever really works well for you so in this case i'm going to stay true to the way i do things and i will write some tests so we'll create a test folder and we can do counter block test dot dot that's the customary way to name everything it has to end in underscore test and then just like everything else we need to have a main function and now we can start working on our tests and so in order to write some tests we need to add dev dependencies to our application and we'll need the test package for dart i don't remember exactly what version it is so we'll find out in a second and then i'm going to add a dependency on this block test package that i was mentioning and so let's take a look at what versions of so block test i already know it's five let's see what version is test it's 114.2 and this one i should have known it's five so we lock down our dev dependencies uh it's just good practice so that you avoid them potentially just like having breaking changes and ruining your ci or or whatever locally testing and so we have our dependencies and now in our main uh the first thing i typically do is i'll create a group and that group is going to represent the thing that i'm going to be testing so i'll have one overarching group for the thing i'm writing unit tests for so in this case that's going to be our counter block so have a group and then we can have some basic test cases right like we can have a test that says initial state is zero right we want to make sure that our counter block always starts at zero so what we can do is we can basically say i want to expect that when i create a new counter block its initial state is zero right and you can use like the super cool integration with vs code to run the test directly from your code open up our little testing tab same thing in android studio i just like vs code and there we go it's booting up and yay we have our first test passing and it's nothing special like you're probably not impressed by this um but the next few tests should hopefully be a little more um cool or interesting at least and we're going to use the block test package to write those tests and those tests are going to be testing the actual behavior of the block in response to new events right so let's say we want to basically test we're going to make a group just to be organized that's going to be testing for counter event dot increment right so this group is going to test how the block reacts to this event and so we can instead of using the regular test package we can import the block test package and the block test package is built on top of the regular test package but it makes things a little more structured and it also gives you some useful like internal functionality that helps like the test give you better feedback if they fail and also helps make them fail faster so you don't have timeouts that cause your test to take 30 seconds or whatever before you actually see any logs so it has some useful things like that built into it but at the core it's very similar to the regular test so if you're familiar with that hopefully this will be familiar to you as well so the description again we need just like with every other test so in this case we're going to say when our counter block has the counter event increment added it will emit basically one right because it's going to start at zero and now we can basically say our block test is going to be testing what block it's going to be testing an instance of a counter block so build in the block test is just responsible for setting up your test and returning whatever block is going to be tested um then we have our act and act is going to basically take the output of build so whatever block we return counter block give it to you and then here you can do whatever you want to that block so we're going to say in our act we're going to add the increment event and then the last thing the most important one right rx our expect and at this point we would expect our block to have emitted a one and so every single test uh it's nice using block tests in my opinion because they'll all look the same regardless of how complex your block is like you can take something really complex or something really simple and the structure will always follow the same three parts build act expect build act expect and so we can run it just like a regular test and fingers crossed yay everything works properly so we have counter block counter event uh emits one and we can do other things with block test where we can like chain multiple events right like we can do multiple ads right so i had two counter event if i can type and increment and so we're basically chaining these um we can rewrite this a little bit to be easier to read maybe let me make this smaller and so um yeah so what is this complaining about here oh we need to make it async yeah okay cool and so yeah we're gonna add multiple events here and now we're gonna expect instead of just one we're going to expect one and two to be emitted i should have changed the description one two when multiple whatever events are added you get the idea and so with this pattern you can basically write your block or write the test first whichever you prefer and have confidence that the business logic that you've just written inside of the block is working properly in more complex cases when your block has dependencies you can use things like mokito to mock those dependencies and then just inject a mock into your block and you can do things like well let me leave that for a second but let's say we had just for the sake of example our block has a dependency on some like counter service or counter repository we can say like counter repo equals mock counter repo using mojito we can say like when counter repo dot whatever i don't know get count is called um then return or then answer blah blah blah right so we're stubbing out whatever our blocks dependency is doing and then we can basically pass a mock into our block and then the exact same structure will work we'll basically be able to mock the blocks dependency and test how the block behaves in all of these different scenarios and so that's all i'll talk about for testing for now but if you have any questions definitely reach out and also like i mentioned the block library dot docs have some examples that have tests that are like fully unit tested so you can take a look at those um as resources and yeah reach out if you have any other questions and i'll jump before we get too low on time into how we would actually integrate this into flutter now so close all our windows we have packages with our counter block it's a reusable piece of business logic in this case and it's inside of our flutter app right so we can say i want our flutter app to basically have a dependency on our counter block which lives in packages counter block we should be able to pull that in hopefully yeah okay and then we can also add a dependency on flutter block which is also at 4.0 right now and that will give us the useful widgets that i mentioned that help you bind to blocks in the flutter application layer and so with that we can now focus on the flutter aspect right so we're calling run app we have let's just wipe out all this code and start over we'll start over with our counter app and we'll say our counter app is just a stateless widget for now that returns a material app and our material app will have home counter page right we have some page let's just define counter page down below so it doesn't yell at me and then let's return a scaffold with some body just so we can make sure everything is working hello right and i'm gonna try running this on web so wish me luck uh so i'm on the beta channel um and i should be able to do flood floater run on chrome and if all goes well we will see our flutter web app that has just a scaffold with hello centered and then we'll see how to actually pull in the counter block and consume it from flutter all right got our flutter app booted up yay we have hello let me split screen it all right let's collapse so um now i guess the first thing we need to do is we need to see we need to basically create an instance of the counter block that we had and provide it to our application so that we can have access to it throughout the widget tree right one approach you could do is you can make this a stateful widget let's say our counter page needs a counter block right and we could create counter block whatever right counter block counter block and then we could also override dispose and say counter block dot close and that's totally valid and that's something that like makes sense for some cases where you want the block to only be encapsulated within this one widget and totally valid like definitely that's a perfectly fine approach what i'm going to do instead though is the flutter block package depends on provider so if you're familiar with provider it's a wrapper around inherited widget and it allows you to provide pretty much anything to your widget tree and so coming out of the flutter block package there's a block provider which basically just allows you to provide blocks to your widget tree and so we can say like our counter block needs to have access to a block and how are we going to get access to it we're going to get access to it using block provider from the flutter block package and block provider similar to other providers gives you an api to create things in this case we're not going to use the context but you have access to a build context if you need to look things up in order to create the block but in our case we don't need to look anything up our counter block oops our counter block has no dependencies on anything so we can just create it and what we've done just now is we've made it possible to anywhere from counter page or counter pages children look up the same instance of counter block that we've just created in our counter application and so we can do something like if we want to instead of hello get the value of the counter that we have we can do context dot block counter block and then we can say give us the state right and we need to convert it to a string i guess i'll just put a two string in at the end for now i know this is kind of ugly but bear with me let me format this a bit so now we have our text widget that's asking the counter block when build gets called what is your state and rendering it as um the text inside so if i do a hot restart we'll see yay we see the zero let me give this uh some styling oops some style so we can make this a little bigger so i'm just accessing the text theme um from the theme and i'm going to make this like a headline i don't know headline two there we go so you see a nice big counter and this is cool but now if for some reason our counter changes it's not going to notify the counter page to actually update the value because it's only being asked for the value once when build is called and maybe the next time if we get lucky when build gets called again we'll get an updated value but we're not in control right now of when build is called um so in order to actually make this a bit more reactive and hook up to the stream of the block instead of looking it up like this we're going to use a widget called block builder and block builder is exactly like stream builder so i'm actually going to use the snippet for stream builder replace stream with block and we just need to give it um well let's do it manually first i'll show you oops i'll show you a couple ways to do this so a block builder instead of a stream it takes a block right so we said we can look up our block by saying context.block counter block right this is also equivalent to doing if some of you are more familiar with the syntax block provider of counter block context so those two lines are exactly the same this one is just a little less typing using extensions so i typically try to type a little less so i'll use that approach and so we're saying okay block builder i want you to subscribe to the state of our counter block and anytime our block state changes i want you to call our builder and builder has access to state right so we can call state.2string instead and we should be able to see a hot restart and yay we see 0 again nothing has changed we can actually change this to use string interpolation um and let me restart make sure that flutter web is cooperating cool and so yeah so we saw how we can bind to the stream of the block and now you can actually since we're using block provider we don't even need to provide this line as long as we tell the block builder hey i want you to listen for changes in a counter block that convert or that handles integers as its state and internally block builder will do this lookup for you and so that's one less line that we can avoid having to type so we can hot restart again and hopefully everything is gonna update yeah cool and now the last part is like okay how can you how can we wire this up to actually add events to it um and so for that we can just use the nice built-in floating action button as everyone is familiar with probably uh where we'll just give it a child with some icon icons.add and then most importantly the on pressed right and so on pressed again we can look up our block right counter block and then we can say i want to add counter event dot increment to you and so now what we're saying is oops there we go let me make this a little bit bigger um now what we're saying is every time we tap on our floating action button we're going to look up the block and flutter web just died we're going to look up the block from build context and we're going to add the increment event to it and ideally our block builder is always listening so our block will do its thing it's going to commute compute what the next stage should be and then when that happens block builder will get the update and return a text widget so once it fires back up we should be able to see end to end everything working hopefully you should see a floating action button yeah and if i press it i can see the state changes yay and in like the last five minutes i will quickly try to introduce the concept of uh block delegate and so block delegate is basically a way to kind of type less code and still get those um transition callbacks that i was mentioning in the counter block so if we look at counter block again we override this on transition here right and so if i actually open up the console um in my flutter web app we can see like every time i click on the button i'm getting transitions logs that's pretty cool um but if you have like 50 blocks in your application and you're building a huge enterprise app like majid was talking about it's going to be really annoying to have to write the same code in each of these blocks so we can actually remove that override we can create i don't recommend doing all this in one file but just for the sake of simplicity i'm going to do it in one file we have a snippet for my block delegate call it whatever we want and all we have to remember is we have to extend this block delegate that comes from the block package the pure dart package again this has nothing to do with flutter yet and so in here we have access to these overrides anytime an event is added we can print it anytime an error happens we can print it anytime a transition happens we can print it and these are all optional so again i'm going to get rid of those just for the sake of simplicity and i'm going to just print the transition right so nothing should change but we need to remember to initialize the delegate my block delegate right and so with those changes i should be able to do a hot restart taking an unexpectedly long time hot restart come on yay okay and i should still see my transitions even though i only overrode on transition function once for every single block using block delegate and so you can think about like okay maybe i want to pass some sort of logger right and maybe in development this logger this logger could just be like a facade or a abstract class or an interface um and maybe in development we pass like a logger that just prints to the console like i'm doing here but in production we log to firebase analytics right so instead of print we would call like logger.log whatever we have access to also the block itself so if we modify a log statement we can say also blocked runtime type and then transition and so let me fix this so that we don't have errors do a high restart go back to web and you see now not only do we have can i make this bigger yeah there we go not only do i have the transition that happened but i also have access to the block that was responsible for that transition so you can see with very little code like you can build a pretty robust um set of like or a system for analytics and developer logs and also it'll help you debug potentially issues if you can get like reports from consumers saying like oh this app got in a really weird buggy state you can take all these logs for the user and see exactly how they got to the state that they got to and then play that back without having to constantly go back and forth and like ask for videos or ask for reproduction steps or that type of thing you have your reproduction steps because you have this like transaction log basically for your entire application and hopefully that was i know that was a lot but um hopefully it gets you like a good high level overview of like what it takes to actually build and test blocks so just to recap we've unit we fully unit tested our counter block i know it's very simple but we've still done it so that's something and we've integrated it into a flutter application and we've gotten logging for free pretty much with just this little bit of code right here and yeah and it works on web which is awesome so i will switch back to the slides um i only have like two more slides so the only things i want to add are as i mentioned earlier you can check out blocklibrary.dev it has like um lots of like written um documents explaining like core concepts again so if you thought this talk was like really fast you can go through and read those at your own pace or you can watch like the flutter europe talk at your own pace if you want to go like slide by slide i talk about every single widget one by one and show like snippets um one at a time instead of live coding through everything so it'll be a bit easier to go through everything at your own pace um there's also a lot of example applications at blocklibrary.dev with tutorials so like if you're interested in implementing firebase um or implementing login with firebase off using block there's an example app if you want to do a github search application using the real github api with block you can see the example and there's so many more like to do's from brian egan's architecture samples there's a weather application using a free weather api so it'll give you somewhat reliable weather data but it is integrated with an api and fully unit tested so there's lots of examples to look at for inspiration and lastly i just want to say thank you for everyone who tuned in i know it's friday and i really appreciate everyone taking their time to join the meetup and check it out and hopefully everyone's staying safe it's crazy out there but hopefully everyone's staying safe and helping each other out as they can and yeah with that i'll end it thanks so much thanks felix that's great no problem should we go through questions yeah all right careful okay yes i'm at the link right now so we have it seems block has two responsibilities handle states and events and handle logic do you think it's better to handle logic with a different controller um i'm not sure i fully understand but i i would think of it as like the block only responsibility is to transform events into states so if you think about it that way it's basically just like a slightly more powerful stream controller so it's taking one type of input and converting it or transforming it into a different type of output so hopefully that answered your question i typically don't handle logic in a different controller i think the blocks responsibility should be to actually you have the logic for how to transform the events into the states hopefully that answers your question next we have do you use mocks in flutter can you recommend a good one so if everyone can still see my screen i highly recommend using i mentioned it briefly makito works really well um and basically what it allows you to do is it allows you to um say like let me show let me find a good example so let's say we have a class cat right and we want to um test a block which depends on this class cat for some reason um we don't want our block in our test to have a real instance of class cat because then we can't really control how the class cat behaves so instead we can create a mock cat and all you have to do to create a mock is just this one line of code say what's my mock class's name i have to extend mock which comes from the makito package and then what interface it's implementing so in this case it's this cat interface and then we can just create an instance of a mock cat object and then later we can do things like when someone calls cat dot sound we're going to hijack that call and then instead of returning what it would normally return we're going to return per for example so you have really good control over the dependencies of the thing that you're testing i highly recommend it it's really awesome and the api is really straightforward in my opinion so definitely check it out next we have when did you start to develop the block library how long did it take to do from the first release um okay so i started developing i mean we can check actually i think it was like october let's just quickly check october of 2018 maybe i don't even remember it's been a while but um it was oh yeah october 2018 and actually it didn't take long from when we had the idea to when we actually published the first release because if you actually look at how much code at that point there was just a block package there was no like flutter block angular block all that stuff it was just the block package and the code if you look at it on github there's more comments and documentation than there is like actual dart code it's very simple and you can definitely like fork it and check out the code but it didn't take that long to like get the proof of concept out and then it's taken a lot longer honestly to iterate and like gather feedback from the community build out comprehensive documentation and examples i think that's been like the really time consuming part but luckily i've had a lot of help from the community people have contributed examples documentation even offered to translate the documentation into different languages so if you're ever interested in trying to help there's plenty of things that we could use help with so just just reach out um we have why don't you use android studio um i guess i'm just used to vs code i think both are good in my opinion android studio is a bit heavier i find my computer struggles a bit more when i use android studio than vs code and i also like um i used to do a lot of web development and use typescript and node before and like i found it really seamless to be able to use vs code and switch between flutter and dart and typescript or javascript and like you can just control what plugins and extensions you have also i'm a little biased because i have to maintain uh plugins and extensions for both android studio and vs code for the block stuff that i showed you and it's a lot easier in my opinion i had a better developer experience building plugins for vs code than for intellij so i think it's a lot easier to build out tooling um which also like makes me use vs code a bit more but i definitely think both are really powerful they're almost at future parity i think so you should be able to accomplish the same thing using both of them and i'd say like use whichever one you're most comfortable with um we have what option is best for block state representation so this is a good question this comes up a lot i think the hardest part about block actually is like coming up with how you're going to represent your state and also coming up with how you're going to name your states and how you're going to name your events actually writing the business logic is usually easier but the naming and the representation of the state is the hardest part and so what i would say is um basically you need to think about like the use case right like if my use case or my um like feature can be in a loading state and have data at the same time like if that is technically possible um then it probably doesn't make sense to represent your state in terms of different subclasses it probably makes sense to have like one base state class that has like maybe a status enum for like i could be loading loaded um or have an error or whatever uh but if there are cases where like it's impossible to be loading and have data at the same time like that is just gonna violate like the entire definition of the feature or use case then i think it makes sense to represent your state using subclasses and have a base like abstract base class for the customer state in this case you have and then have a customer loading loaded error that extend from that because you want to make it impossible to get into these like weird scenarios where the case makes no sense right like if we had one base class for this case um that has loading and data and we said it was impossible to both be in a loading state and have data technically that that is still representable it's possible to represent that in code and so you want to just model in a way that is impossible to run into cases that should not be possible i guess so i think you have to play around like i don't think there's a one answer um for every scenario you have to just try it and see what feels better also another thing to consider is freezed i'm not sure if people have checked it out yet but remy who's the maintainer of provider he released a library called freezed which basically gives you sealed classes and union unions pretty much so it does use code generation behind the scenes so you do have to use build runner but it's really handy for basically cases where you have like this inheritance and you always want to make sure that like my state is one of these types you can use like the when on freeze and it will basically ensure that you've handled every possible case you never forgot to handle a loading or like an air case by accident in your ui so i highly recommend checking that out as well uh we have did you develop the library completely during your like regular work or how much free time i did not develop it during my regular work because uh it was not a priority at the time actually like we were just full speed ahead like working on uh transitioning our two mobile apps into flutter and so like we had deadlines that we had to meet and all the usual stuff so like we couldn't take lots of time to like do a ton of research like we had a window at the beginning where we did pocs for flutter and made sure that we were sure that we wanted to use flutter but we didn't have like a ton of free time to investigate like okay can we open source things actually bmw was like not really open sourcing a lot at the time so that was a challenge and like we didn't have a lot of time to like say okay let's try redux uh block scope model blah blah blah and like be able to change our mind later we wanted to kind of like be agile and like try to be smart and tactical about the approaches we took so like we started off with redux we did uh like a few months of development with redux and then like a bunch of us were like okay yeah this isn't really working like we have to teach a bunch of people these concepts that aren't that straightforward and also like they're cases where it becomes awkward and our global state model becomes super huge and complicated so can we figure out something else and so in our free time we started like experimenting with block we did a lot of extra work to convert to rx dart and block and then again in our free time we were like okay rx is powerful but we don't want developers to directly be using rx everywhere because it'll cause like spaghetti code in the long term if we're not careful and so then again in our free time we were like how can we come up with an abstraction for all of this and i think like it worked out i mean we spent a lot of extra hours but it was good to see that it was helping the community as well it wasn't just internal and i think it also opened the door for bmw as a company to consider open source more and they started open sourcing a lot of other flutter packages you can check out bmw tech at github and they have like an open source mapping package and some like a logger they have some testing packages so it's pretty cool that we kind of change the mindset there by doing that and we have would you agree that block should contain only pure dark code yes i think that's a big thing like i see people trying to handle navigation in blocks and they'll pass in a build context i'll see people handling like animations and they'll try to access like animation controllers inside of a block and i'd say ideally you should be able to remove your block from your flutter app and drop it into angulardart app and you shouldn't have to change anything in your block code um i guess that's like a very pure way of thinking about it so like definitely you might say like oh i already know i'm never going to need angular dart so it's okay to couple it to flutter but i think like there's value in keeping it pure dart like you can extract it into its own package you can write pure dart tests for it um you don't need like the flutter sdk just so that you have this piece of business logic that really doesn't care or shouldn't care about the presentation layer so i would say like definitely try to keep the blocks pure dark and that's why like it might seem like overkill that i pulled it out into its own package but really doing this kind of makes it easier to see those things because i can easily see like i only have a dependency on the dart sdk i don't have a dependency on flutter right like it's really obvious if someone opens a pr now and says oh i'm going to add flutter to my block and then everyone will be like whoa whoa why are you adding flutter to your block and you can have that conversation so i think separating things out that way helps enforce that separation of dependencies um and then how do you measure performance of your library that's a good question so you can do it a number of ways like i initially had benchmark tests that i was writing using a package called benchmark let me see if it still exists benchmark harness yeah so you can check it out it's not very popular but it allows you to basically specify like what code you want executed and then run this like benchmark harness and specify how many times you want to run and then it'll give you a bunch of like statistics about like the average um execution time max execution time tons of stuff so you can analyze and even integrate into the pipeline also i think another good measure is like building apps using block like for example building flutter apps that use it and then you can profile those using the regular profile profiling tools that are pretty powerful and the flutter team has done a lot of work to improve you should definitely check out um philip uh rossig's talk he's one of the flutter gde um uh devrel uh he's on the demo team and he had an awesome talk at flutter europe that's on youtube that you can check out about how to profile for performance and find out where performance issues are happening and how to fix them so yeah the built-in tooling is really really helpful for that but like this package is also kind of useful for just like in isolation doing some simple benchmarks you can check that out as well and it's maintained by google employees as well well i think that's all the questions that i see so far great thanks felix yes great talk a lot of insights in the library uh and uh pretty good explain from zero to 100 so yeah hopefully it wasn't too much hope it was a good overview yeah i think so um and uh thank you very much um i hope you have a great day i think in the u.s yeah yeah we still have some time yeah have a great evening for you right yeah you too and for the audience um i will quickly post um a jitsi meat link so for all who actually want to join us uh want to talk a bit later um just just come into this room join us there and we can talk and yeah we'll see each other there also you to have so many people here from all over the world um let's make this worldwide right now so uh travel the world yes thank you very much again so see you on jitsi in a minute or uh if not elsewhere oh and i'll send the links to those resources too if anyone's interested and you can share those you
Info
Channel: GDG Nuremberg
Views: 2,635
Rating: undefined out of 5
Keywords:
Id: cvh3NAFhFiY
Channel Id: undefined
Length: 114min 35sec (6875 seconds)
Published: Mon Sep 21 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.