Design Patterns in the Light of Lambda Expressions. Venkat Subramaniam, Agile developer, inc.

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
okay we're about to start welcome when cut again he will tell about another method sings which every everybody needs to know to be successful thank you well welcome to the talk on design patterns at the light of lambda expressions I'm going to talk about how we can benefit from using design patterns but also mixing lambdas with it but before we get started let's talk a little bit about design and design patterns you know as developers we often are struggling to design the code and the software that we are designing and especially among Java developers I would say we have this fascination towards using design patterns but before we talk about you know using design patterns let me first say that I really hate design patterns I know that was very motivating wasn't it okay well the reason I say that is think about PI for a minute we all know that grandma makes the best pie ever and you've been telling your friends about grandma's pie for so long and your friends come to you and say if grandma makes such a wonderful pie why don't you make that pie for us we want to taste it and see how it is and so what do you do you call grandma and say grandma my friends are coming home on Saturday I've been telling them all to your pie for years and now they want me to make that pie I need your recipe and grandma gives you the recipe and what do you do you start writing the recipe down and you tell grandma slow down tell me every single step and grandma says take some flour add some sugar and you're like well we'll wait a minute tell me exactly how much flour and tell me exactly how much sugar to add and grandma says about two and you're like wait wait is it two spoons our table spoons our teaspoons and you write all this down and you ask grandma grandma what are the best practices what are the do's and don'ts and then after getting all this recipe you start early that Saturday and you make that pie how did that turn out to be a disaster wasn't it the last time I tried something like that I lost the spoon with it as well and you go to the store you get a pie be done with evening animate grandma the next weekend say grandma your recipe is broken it was a disaster and grandma says why did that end up that way why don't we make the pie while we talk and you start noticing that grandma starts making pie and what does grandma do grandma takes two teaspoons of sugar measures it accurately and puts it right no grandma's having a good time talking to you and takes sugar and tosses it in and he said well what was that and grandma says that was sugar how much did you put and grandma says enough and that's when you know grandma doesn't use the recipes that she gave you well what I'm getting to is there are these four guys who wrote the best ever written book on design patterns these four guys are the grandparents of our industry and the worst thing they ever did in their life is write the damn book and everybody thought oh my gosh I can do this now and they read the design patterns book and return application into a monster after that now that I have so very well motivated you to look at design patterns let's talk about design patterns well what I really want to emphasize is that I love design patterns but not for the reason a lot of people get drawn into it I don't think design patterns are a real great design tool I think design patterns are really good communication tool are used to sign patterns to communicate with my fellow developers but the type of solution that I'm using in a given context but the worst way to really use design patterns used to sit down at work and ask the question I wonder what pattern I can use now you know when you're waking up in the morning right as you're about to get off your bed if the thought that comes to your mind is I wonder what design pattern I can use at work today I recommend you call the boss and say I'm feeling very sick today and just fall back on bed there's no point going to work today and the point really is we should really see these patterns emerge in the code and then of course apply them where it makes sense but use it to communicate but having said that I feel that there are patterns we have been using for quite a while that can become a lot better now I started programming a long time ago in languages like C++ and when Java came out I had this you know amazing eagerness to use Java partly because the design patterns I would use in C++ became a lot simpler when I started using them in Java what were monsters and C++ we're kind of baked into the language and I was really happy and and to me to live that happiness one more time in the language Java was amazing because when lambda expressions were introduced I got excited one more time because the patterns I would write in Java became a lot more simpler again in Java thanks to these lambdas and that's what I want to focus on here as lambdas as these design tools so lambda expressions are really an interesting way to design and and to be able to pass these anonymous functions through the application so what are lambda expressions provide for us in general I know you all know lambdas but I'll put a little perspective on that with a little example right in here so suppose let's say we want to create a thread and I'm going to say is equal to new thread and then of course I'm gonna start this thread I'm all that I'm gonna do is simply say in main to say that I'm still in the main thread so when I run this code you can see it simply printed in main but what about the other thread we just started well for that of course you can say new runnable and then within this of course you could write the method called run and within the run method you could say in another thread like this and of course when you run this the other code ran in this other thread as we can see in here but if but when you look at this code this code is an example of a very high signal or very low signal to noise ratio that's a lot of fluff a lot of verbose code but what are we really trying to do in this code what we're really trying to do is to pass a piece of code a function to this particular thread but we couldn't do it in the past because functions were not for class citizens in Java so we were trading functions like kindergarten children this little kid comes to you and says could I go to the neighborhood park we please and he said no child you cannot go alone let me send an adult with you so we started wrapping functions within objects for no good reason well it's kind of like you know as a parent I love watching my children grow up as adults and they go off on their own it's kind of like watching that functions become these kindergarteners and growing up and going on their own and now of course what you can do is rather than writing all that fluffy code you can simply take that little function that you have with you and you can treat it like it's an adult so you can remove that little a method we created right there and we can remove all that noise around that code and keep removing and then of course we can simply put that little lambda expression and write the code to pass it around just like that as we did before so in this case we can simply pass the lambda where we would have passed the object before a single method object so in other words lambdas are anonymous functions and we can pass these anonymous functions around to get our coding done so this become a really nice way to design the code with these lambdas well with that said let's talk about some design patterns we could use I'm sure almost everybody in this room at some point has written a strategy pattern how did you write the strategy pattern just think about it what is the traditional strategy pattern look like in the traditional strategy pattern you have a class that wants to vary part of its implementation so to vary part of the implementation and a function what would you typically do you would pass a interface to it and the interface would do have a function that implements that little variation and then you would create classes that implement that interface so if you were to implement a strategy pattern what do you normally do you create an interface and a bunch of classes and have a corporate design meeting to talk about it that's a lot of work to do strategy isn't it if all you're trying to do is to make a slight variation in a logic why do you have to implement so much code well lambdas can get rid off a lot of that to integrate the start let's look at an example imagine that this is Friday evening and you are at work still and you know how our mind kind of turns off on that Friday evening about 4 p.m. and you are getting extremely nervous and agitated because your body is at work but your mind is not you know that feeling isn't that you have that very important party to go to and all your old friends are coming to town you've been talking about this for weeks and you're so excited you want to go to this party but unfortunately you have to get one piece of work done and that is one of your colleagues in the one who nags you all the time wants you to implement the function called something called total values which is going to take all the values given a collection and total it so what are you gonna do you say here's a list of numbers we'll go ahead and say integer numbers and I'm going to simply say equal to list off let's go ahead and say this is going to be list of numbers 1 to 10 and I want to just total all these numbers together how do you implement it well you're going to implement it you're going to simply say static right here and then you're going to say integer total values this takes a list of integer will call it as values and what are you gonna do with them these values let's write the code in the traditional imperative style to begin with we'll say total is equal to 0 we want to return the total when we are done with it and Whitin here will say for INT element coming from the values all we are gonna do is simply say total plus equal to the element given and we will implement the code like that so you finished this code and you're about to go for this very exciting party and before you could go unfortunately your colleague comes to you and says oh wait a minute not only do we need a function to total the values I also need a function to total all the even values and you take a deep breath and say you mean in addition to total values you also need total even values and your colleague says yeah I need that I need it now and you look at your watch and you really go to this party you're not very excited and then you realize it's not really that bad because most of the code you need is already done so what do you do you think about it for a minute you scare at this code and you tell yourselves there's got to be a reason why they created copy and paste I mean if nobody should use it why would they have a concept of copy and paste in fact it's so integral to what we do we even have shortcut keys for it a ctrl C and a ctrl V how cool that is so you copy and paste it really quickly and you say total even values right here and you simply say if the value of the element Martu is equal to zero then of course you total it otherwise just skip it so you implement that code right away readily and you have that working and you're about to leave when as the fate may have it again your colleague comes to you and says oh I also need a total our values also well you know you're in trouble now because copying and pasting a chord a third time is an act of criminal negligence but it's Friday evening and nobody is watching so what do you do you quietly make a copy of this function one more time and copied and paste it again and then you call this as total art values and then you change this code to a not equal to and you quietly slip away but on the way to the party guilt kicks in because you just realize what how terrible this is and what if somebody looks at your code what would they think of you so immediately you pull by your nearest Starbucks and you start refactoring your code but as fact if it may have again some of your other friends are hanging around the same coffee shop they come and talk to you and before you could close your laptop they take a look at your code and they get to know your dark side and they never return your phone calls anymore why would anybody want to hang around with people who do copy and pasting for a living let's pretend this never happened quietly roll back the code like we never did this so all the way back now imagine you just wrote that code for that particular function which is the total values now that that is done your colleague comes to you and says hey I need one more function to total even values also you asked your colleague do you mean you want this total values but you also need total even values and your colleague says yep that's what I want and walks away well you don't just quite implement it you look at the code and say how do we reuse this code to make that happen so what you're gonna do to do this is before you implement that code you're gonna implement the strategy pattern so what you're gonna do is look at this code and say all right we will take this code and we'll call the total values but we'll do a little bit of refactoring we'll introduce a second argument to this function where the second argument is called a select or and then we will say if the select or test on the element is true then total it otherwise ignore it because when you notice the three duplicated code we had earlier the only difference between the three pieces of code was what's within the if statement so we can extract that as an argument to this particular function so in this case you said select or and if the select or test is true then total not otherwise well the question is what in the world is that select or well the select or as it turns out to be is actually a dot function dot predicate and you can now simply say that you have a predicate right here where the predicate takes an integer and returns a boolean response for the given integer so now you can simply say that you can refactor this and say whatever element you are receiving simply return or true as a response now what you can do is to refactor having reflected that code you can simply say given an element element mark two is equal to zero then total it otherwise ignore it now your colleague comes to you and says hey I need you to do one more function total our values you tell your colleague go back to your desk and do it yourself because we made it so easy to reuse that code we don't have to be duplicating the code over and over so if you look at this code what did we just do in this particular function we created a strategy pattern how so because this function total values provides the engine for the computation but the strategy is determining what value to actually total so in other words you can use the predicate as a way to implement the strategy but of course you know that you can also refactor this code to a more functional style as well so in this case what you could do potentially is you can simply set return value start stream and then in this case of course you can say filter and you can just pass the selector to it and then of course map to int and give an element simply return the element and you perform the sum operation on it and you can return the result as well and you can refactor the to a functional style in this particular case so in other words if you really want to implement the strategy pattern you don't have to invest your time and effort in creating interfaces and classes you can simply use lambda expressions and functional interfaces to get done and the functional interfaces really are placeholders for the lambdas but the essence is that you really are keen on using the single function that you're able to use to really get your work done and that becomes your strategy to provide a fairly easily so that gives you an idea about how you can use the lambdas to implement strategies without much difficulty at all well the next thing we want to talk about here is to delegate to a particular object creation to a later time so before we talk about this let's take a slightly look at a slightly a different example here just to entertain this start I'm gonna use the Scala as an example here but you could use different languages to illustrate this particular point so here is an example in Scala so let's imagine for a minute that I have a function called compute where the function compute takes an integer and all it's going to do is simply print out let's say called over here and then I'm going to simply say over in this case let's say return n times - so the fact I'm returning a number times - on the compute function X equal to four I say if X is less than let's say five and the call to compute of X is greater than seven I want to simply print out let's say path one otherwise what I want to do here is to print out let's go ahead and say path two when I run the score as you know this code is not going to invoke the compute method if the value well if X is greater than 5 let's say it's not gonna invoke the compute method but what if I really wanted to display the value of compute of X over here what the good news is compute is not called still but what if the value of X's is greater than five sadly compute is called twice in this case which is not very efficient so to make this more efficient you could mail both us to a temp and you could then call temp right in here and then of course you could simply assign temp is equal to and assign the compute to this particular function when you execute the code one more time good news in this particular cases that you are not going to take the path to a one but the bad news is compute what's called even though it's not needed but of course if the value of X is greater than 14 compute was called only once that's a good news but if X is not greater than 14 we call compute still which is really unfortunate so what do you do to prevent the call to compute when it's really not needed well what you can do in the case of Scala is you can mark this as lazy so without lazy you notice that compute is actually called but with the word lazy in place when I run the code notice computer is not called because it the first evaluation until it's actually needed so if I put a 14 over here you can see it is calling compute but with the four it is not actually calling it it bypasses that so this is a nice way to defer evaluation until you really need it actually now this is great because we can be efficient and not have to do process that is really not significant or needed well but what about Java though unfortunately Java does not have the facility drew laziness well this is one of the places where I want to think about a way to delegate until we no longer really cannot postpone it so how do we do this so here is an example of that here in Java so I could say public static let's say void compute our our int compute rather and I'm going to say in this case and an input n and all I'm gonna do is return n times to let's say and and let's go ahead an output called no obviously is a trivial function but what imagine this is time consuming what are you gonna do so I'm gonna say X is equal to 4 if X is let's say greater than 5 and the compute of X is greater than 7 I want to print out right here will say path 1 otherwise we'll say else will print out let's say path 2 well the good news in Java is when I run this code you can see compute was not called but on the other hand what if I were to save this into a variable called attempt and then I say in the temp is equal to compute unfortunately the call to compute happened right now even though we really know don't need that value at all so what do we do about it well this is where we can engage laziness of evaluation so how do we do this well this is one of the places again where we can use a level of indirection so what we can do here is we can say what temp is equal to not a call to compute but we will instead pass a lambda expression to it so in other words what if rather than calling compute what if we call a lambda which in turn will call compute but at a later time so what we can do here is to say lazy and this is going to be a lazy of integer if you will and then I'm going to pass to this lazy a lambda expression in the constructor so in this case we are creating an object called lazy and we are telling the lazy object to receive a constructor call which takes the lambda then we can come here and call a get method on this particular object to receive the data so we do make this work obviously the lazy doesn't exist in Java unless you're using something like project llama book you have lazy but otherwise you may have to create one yourself so what I'm gonna do here is to create a class called lazy which takes a type T let's say and then I'm gonna write a private T instance but I'm gonna also keep a supplier of type II will call it supplier so we are gonna bring in the Java dot util dot function darts supplier into the mix over here so now that we have a supplier our lazy contains a supplier and an instance of T then we can write the constructor for the lazy where we pick the supplier of T we'll call it the supplier and all I'm gonna do is simply save the supplier equal to the supplier and put it away then I can create a public t get function where I can say if the instance is equal to null then of course what I could do here is instance is equal to supplier dot get and supplier equal to null and then of course I can simply return the instance that we have this is not thread safe but my intention is not to make it thread safe but that gives you an idea about how we're going to implement it so the Lazy class simply says I'm gonna check my instance to be not null if it is null I'm gonna get the value from the supplier save it into my instance and then of course return the instance whether it is there or not so if I were to run this little example code what's going to happen at this point well ok it's complaining that cannot convert an integer to this particular value obviously because that becomes a lazy so I'll just put a bar over there and now you can see it says path 2 well that's great that's a path to we did not call the function let's go ahead and say over here here and execute the code it's still path 2 but on the other hand if X is 14 you can see that it's actually doing the call to the function and again if I really wanted to print the value that I have from the get you will notice that it's not gonna call the compute more than once so you can see that it's pretty much doing what we intended to do so in other words we can use the supplier to postpone evaluations until a later time so again we can use lambdas to the rescue here where the lambda is really being passed in for the supplier and that becomes a level of indirection in the code so we can use this within a way to postpone evaluations we could also use this for implementing the virtual proxy as well if an object is going to hold on to a reference to a object which is heavyweight we can use a lazy to put the reference so the object comes to life if and only when we need the object not otherwise so we can implement the the the very easily the virtual proxy a virtual proxy is something I really like a lot if you look at the design patterns book for example the proxy pattern is one of the most powerful patterns because it is used in so many different ways virtual proxy remote proxy controlled proxy has smart pointers and so on it's one of the most powerful patterns out there but what the proxy is dear to me because I remember I'm working on an application a long time ago when we had written the code in a very simple way where our object was querying for certain properties in the system everything was working fine for a long time and we were maybe about a week or so before releasing it when a developer came with a panic and said oh my gosh the application is extremely slow when I tried it on a particular you know system and when we looked at it what we realized was in all our tests unfortunately we were using a small test data and the program was working really well but in this particular test environment when we opened up the application it literally it literally had millions of data to process and and once it started going through the millions of their to process our application was hanging up because it was trying to load up all this data and of course the panic ensues when you're close to production and what do you do about it well we sat down and thought about it and said how could we get away with this without spending too much time and effort and we came up with a fairly easy way to solve the problem we literally this object that was doing all this work and just renamed it and we created another class with exactly the same name so the rest of the code would not have any trouble compiling and then this outer new class we created with the name of the old class simply had a pointer to this particular reference to this object but the reference was null and then it would simply create millions of these but those objects were not populated until the user clicked on a particular object on the screen and that's when it'll go out and get the data so in other words it will cache the data on demand but not pre-created and within minutes we had an application that was performing really well without too much code change in the system simply moving this one level and that was an application of virtual proxy and and the point again we didn't sit there designed to use the pattern the problem post itself we devised a solution and then when we came we came back and laughed it you know each with each other and said wow that's amazing how did we solve it oh darn it we used virtual proxy to solve it so that can be a very effective way but similarly you can now of course use something like a lazy to implement it very effectively if you want to so that gives you an idea about how we can implement that particular feature well the next thing I want to show you here is a decorator pattern now I want you to just think about decorator pattern for just a minute do you remember the world famous example of decorator pattern yeah it's called new bufferedreader new data reader new file reader and I see some of you laughing already and you look at that example and you say that's called decorator because the word in English is called ugly when you look at a code like that and then you wonder why they would call a decorator pattern and show an ugly example and we never ever use decorator pattern ever again isn't it because that code is a monster and anybody tells you you can use decorator you start laughing at that point well that's a really terrible example of decorator pattern because that noise completely drowns the benefit of decorator but thankfully we don't have to do that now in Java thanks to lambdas but more important than lambdas there is something else that's absolutely important and that is one of the key things about functional style of programming is not the fact that you can use lambdas but the fact that you can compose functions together and composability is one of the most essential characteristics of functional programming so to understand composability i want to give you an example right in here suppose I write a function called the printed and the printed function takes a number it takes a message will say message but it also takes a function which takes an integer and returns an integer will call it func so we have these three things that are we gonna pass through this punch function call to print it and within this of course I'm gonna bring in function star now what I want to do is I want to simply print out right here and I'm going to say n plus and of course we say 5 and then we'll print the message if you will and then we will say a little : after this and then we will print right here func dot apply and we'll pass the number to it so I want to use this function to get some work done so what am I gonna do now I'm gonna say here function to begin with and and this function let's say integer comma integer we'll call it Inc is equal to given an element return element plus 1 so now I can simply call print it and the printed function simply says 5 comma incremented and I'm going to simply call in on it and I ask you would expect what does it do 5 incremented is 6 and tells you that the value of 5 being incremented is actually 6 great I can similarly come down here and take a 10 10 incremented is 11 well that's great so far isn't it now what I can do is create one more function here and the function is going to take an integer return an integer but this time I'm gonna say doubled is equal to give an element return element times 2 you where I'm going with this I can simply say now five doubled is gonna be doubled and similarly ten doubled is going to be doubled as well and five is double becomes 10 10 becomes doubled becomes 20 and you can see five doubled and 20 doubled but what do we really want to do now now I want to say printed 5 comma incremented and doubled oh dear how do we really do this one where I want to increment it and then I want to double it well here's an idea what I can do is I can create over here function integer comma integer and give it an element this is going to be inked and doubled and then equal to I could say a plus 1 and then times 2 over here now if I do this what is the consequence of this this means no friends isn't it because we just duplicated more code nobody's going to just hang out with us after this and they will get together and talk without us and say that's how he is writing code this is not the way to get around so what are we gonna do well the good news is we don't have to go that route we can beautifully have composability so inc and then so we can say and then doubled and we can compose that very nicely isn't that cute so what you can do is you can take the increment function and you can do it and then on it and you can pass the double to it and as a result now you have a function that is composed of these two other functions inside of that and that is a pretty charming capability where you are able to compose things together so in other words what you just did is you took one function and you composed and the function with it and now you have a bigger function that is a combination of the two functions put together so that gives you the ability so when you make the call on this function that is going to execute this one pass the result to the next function which executes this next function and use it the result after that and becomes your abstraction to move forward with it and that becomes extremely powerful well now that you saw how you can combine this we can now start decorating a record with combinations of things like this let's entertain a thought about how we can actually achieve that and combine functions together to put something together so let's start with a little example to play with it let's say we want to create a class called let's call it as camera right now and the camera function is going to contain a function which is going to be public let's call it color and this is going to be snap which takes a color let's say import and it's going to give us a snap of the color with the output but what do we want to do in it with the camera well typically when you look at a camera what people normally do is you have a nice camera but you put filters on the camera now I have a camera which is you know maybe relatively fancy but not too fancy but I want to take a picture of a mountain most of the pictures you see behind are the things I've taken but I would bring in a little filter so I can take you know much crisper image of something in the distance but then I would remove the filter if I'm in a small room and I want to take a picture of somebody before it was close by so in other words you can start putting filters around a camera that's an example of using a decorator and that's exactly what I want to do here so what I want to do is to say function right here we know what we'll start with baby steps let's simply return the input for now so it just takes a car input and returns that output but let's go ahead and play with it so public static let's say voyda printed and the printer is going to take a camera so we'll simply say camera and all it's going to do is simply output let's say camera dart slap and it says new color and in this case we will pass to it 125 125 and 125 now what in the world is that color I know that's a bit scary but that's Java dot aw t dot color let's say so I'm gonna just pass that color to it and all that the printer is doing is simply printing out the color given to us now what do we want to do let's start with a little example we'll call it print it right now and pass new camera to it and all he would expect it is in this case simply print out the result of the particular call which would be the colors be provided that's all it did great but then what I want to do is to apply a filter to it so the way I'm gonna apply the filter to it is I'm gonna call printed new camera but I'm gonna pass a filter the filter is called give me a color as an import I want to return a colored art brighter so so in this case I'm gonna call the brighter to return the color as a brighter color than what I provided well before we go any further you know I can refactor this as color : : brighter like that so this gives me an ability to pass a brighter color as a filter so the color given will be brighter when I get it as an output how would I really implement this piece of code I'm gonna go to this code right here and I'm going to first of all drink in a function dart function so in this case I'm gonna say private function and this is going to take a color as an input return a color as an output we'll call it a filter notice I'm using the word filter as a singular right now so then what I will do is write a constructor for the class here camera this takes a function color comma color as an input and I'm gonna say a filter will call it filters filters as a plural so I'll pass a var arc to it and then what am I gonna do right in here the first thing I'm gonna do is filter is equal to given an input return the input back to me so I'm assigning a very trivial filter an identity filter to this given an input it turns an output then I'm gonna say far and you know where I'm going with this right function color comma color and I'm gonna say over here a filter this comes from the filters given to us then I'm gonna say filter is equal to and I can say filter and then I can simply add a filter to it so this combines the filters given to us to form a bigger filter so if you pass zero or more filters to me the filter field is going to be a reference which may not hold anything other than an input is going to be output or it may hold a reference to one filter or it may hold a reference to two filters put together so this reference may have really one input to output or one more or a combination and that's what line number twelve is doing is combining those filters together to form that pipeline of those filters now that we created it let's see what the output is going to tell us right now let's go back over here and make that code to work so when I run this code what does it do I got a bunch of warnings right now this is what I love about Java right so we can quit doing real work and make the compiler happy right now so what are we gonna do now we're gonna go to this code and say oh there's a warning on line number eight let's fix that what do we do we will use this beautiful feature called suppress warnings what is really cool about it is these cups up as warnings not just one warning right and then what are we gonna suppress over here you know maybe we'll do unchecked over here and and we can say you know provide whatever that we want to provide and ask you to deal with them so we can specify suppress warnings and get rid of it and that way you can remove the warnings I'll let you do that if you're interested in that but let's get to the code itself and run that now at the bottom you can see what is it going to do we need to apply the filter isn't it let's apply the filter so I come to the line number 18 and say what am I gonna do now return the filter dot apply and pass the input to it so when you run the code this time around you can see the first one is 125 the second one is 178 because it's brighter now you know where I'm going with this we can take this one and say darker if you will and of course it's going to be a little darker and if you look at the output in the very bottom you can see that it says 87 so that shows you that it's a little darker than what was given but now let's come to the actual decoration aspect of things what you can do is you can say brighter , and you can put a darker so now you can start combining different decorators do it so this says given a camera take the input coming in I don't know why but you would want to make it brighter and you're gonna make it darker now in theory if you make something brighter and darker it should be the same as input but theory never meets practice that way so when you run this code what is the output we're gonna see right now you can see it's 124 124 and 124 but it essentially shows the code actually weren't and that becomes a nice way to do the decoration but I'm going to show you one more thing really quickly if if that worked really nicely I'm gonna refactor this code a little bit to make it a bit more functional some of you may have realized what I have done here is an operation called the reduce operation so here's what I'm gonna do to fix this code to a functional style I'm gonna say filter is equal to I'm gonna say stream first of all let's bring in the stream so we'll say stream right here so this is going to become a stream dot so stream this code right here will say stream dot off and what is this this is going to be filters that we bring in then I say reduce and the first thing is given I input return an input then we say over here filters common well this is going to become would say earth filter and then we would say in this case result and simply return from this the result over here dart and then and we will say a filter so this really brings ability to combine all these filters together or to create our filter well what does this do you can see the output from the bottom it still worked if you're happy with that we can refactor there's one more time right in here and we can then say what in the world is this that's a function dart identity what it really is it's an identity function and then you can say this one right here simply is a function double colon and then and so you can refactor that code pretty effectively to reduce all that clutter so rather than writing the code at the top you can refactor that to a very sweet little reduced function and as a result you're combining those objects together and you're forming this pipeline so that's an example of using a decorator pattern using lambda expressions and Method references and of course on the caller side you can see how easy it was to invoke this simply simp assing to the constructor a list of function references method references which are comma separated and that becomes a nice way to decorate it and that's an example of how you can use the decorator pattern with lambdas and method references well the next example I want to show you here is going to be a one that makes the interfaces much more cleaner and for this I will take an example of a mailer class let's say the mailer class contains a bunch of functions a public wide from which takes an address right here we'll call this as some kind of a function address and all I'm going to do is simply output right here from similarly I'm gonna have a few other functions let's call this - let's call this body let's call this one as you know from to body and subject let's say and then finally of course we will simply say send the sent is not going to take any arguments right now we will simply say over here sending but this one is going to say body right here which is going to be some kind of a text subject is going to take a line but that's going to be subject and two is gonna take an address and we'll say two but how do we use this particular class in our code what to use this class a traditional way of doing this is mailer is equal to new mailer and then you can say mailer dot from who is this from well this is from builder at let's say agile developer calm who is it sending - well let's say it's actually sending it to my email address mailer Dart let's say subject this is a subject I get an email every single day from my build system it politely tells PR impolitely tells me you were code sucks and then it of course tells me not just the detail about it sucks but it also tells me how it actually sucks today as well so there is a little bit more details about how my code sucks today and then of course with my finally a send method to invoke it now when you look at this code what is that called that's called the Java code isn't it because that's noisy and so fluffy but there are two problems with this code the first problem is hey what do we do about all this noise the second is should we reuse the mailer in the end or should we not reuse the mailer there is no real good answer to it and the worst answer you can give to people is go read the documentation how did that work out the last time you tried it because documentation usually says exactly what the function name says it's very frustrating well let's solve this problem what can we do well couple of things we will do first to reduce the noise the first thing is we'll go back to this code and take these functions and we will have each one of them returned a mailer back to us from those calls and as a result what we will do here is take each one of these lines and return at this at the very end of these calls so every single one of them simply return the current object back to the caller well now as a result we can go back to this code and we can simply say mailer not from but we can remove this noise from here and as a result we can remove these semicolons as well and the code still works so that's one way we can reduce the noise and this is called the composed method pattern but then we can take that to the next level and what we can do is make the constructor thriven so we can say private over here mailer and now that the constructor is private you no longer can create the kulluk object on line number 14 so what do we do mailer dot you and Whitin here will pass a mailer to this and then of course we will simply say over here mailer dot from and we will actually rather than use will call it as send and then we will simply call all that method up to here so mailer not send takes a lambda which receives a mailer but then we call the from the to the subject on the body from that function so as a result the send function became a static method and what are we going to do within this function within the send we are going to say mailer is equal to new mailer and then of course we can say block dot accept and pass the mailer to it so now that we are doing the code this way how does this help us we can then go back to this and say Java dot util dot function dart consumer and we can bring the consumer in and this becomes a consumer of mailer will call it as block so when we look at this code now the the send method right now is receiving a lambda as an argument then we are saying on line 20 mailer dart send it takes a lambda it takes the mailer and then we can do whatever operation we want to do with it but when we return on line number 24 we go back and complete the operation on line number 14 so as a result we have removed that noise in the code first of all the second thing is should we reuse the mailer or should we not reuse the mailer hey I don't need to worry about it because the designer of the class can take care of it if they don't want us to reuse the mailer they can create a mailer every single time if they do want the students the mailer they can mate in a pool and give us an article in the pool as a user of the object I no longer have to be worried about it and that's not a concern I need to carry around well they execute around method pattern is a very similar pattern I'll just mention it right here we're gonna use a very similar approach like we've what we saw just now except that in this pattern the goal is to do a pre-op and a post-op so where we have the send method we can do operations before we call the accept and operations after we called the except maybe within a try and finally block and basically that same example can be extended to the pattern called execute around let the pattern so summarize what we talked about we saw a quite a few design patterns in here some of those patterns of the patterns from the days of design patterns book well these are traditionally written using classes and interfaces and objects those can be written using lambdas your design patterns shrink in size you don't have to implement classes and interfaces and all that fluffy code as we once did we can write a lot less code and we can leverage lambdas to really achieve that particular fluency and some patterns like execute and run method pattern and the and the fluency that we saw here where things we normally didn't do in Java but now we can do thanks to have availability of lambdas so the old patterns some of them are all quite a few of them become a lot more fluent and some patterns that we once did in in other languages can now be brought over to Java as well and we can benefit if you're interested in the code examples I showed you you can download that from my website agile developer comm I hope that was useful thanks for coming thank you any questions that's one over here thank you thank you one question will be about decoration pattern so let's say that we have a lot of code a lot of passions and these compositions and did you get experience with debugging this code so the question is how do we go about debugging this code how hard how hard is it to I don't spend my day writing bugs so I don't know the answer to that question just kidding [Laughter] because everything that you have is a strict race with hands and apply and then apply and it's a lot of 100 stacktrace of these names and you don't understand in which place you need to go a deeper entity so do answers for that question the first is when I was a very young programmer I used to live within the debugger this was like being stuck into a debugger right that's the life of me once I started embracing test-driven development honestly I do a lot less debugging tenant and then I used to I'm not telling you I don't use a debugger at all but what I do today is if something is not working I put up debug in my test and I start stepping through I can't tell you how many times within seconds I'm like or done it I know what the problem is so the first is the key to debugging there are two keys to debugging first is cohesion if you make the code very small it becomes easier to understand easier to debug the second about debugging is it's all about understanding the semantics once you understand the semantics of the code the lazy evaluation and the sequence in which it is going to go from one to the other you know what to anticipate and the debugging becomes very easy so when people tell me it's hard to debug I'm not saying it's not hard for you it was hard for me also but once I got comfortable with the semantics debugging become a lot easier so the first is very comfortable the semantics and the second is embrace automated test a lot more so the debugging need becomes a lot less even though it never goes away yeah and that's good that's great better than ever yeah thank you we're running out of time so now it's taking a coffee break thank you thank you
Info
Channel: Devoxx
Views: 34,167
Rating: 4.9498749 out of 5
Keywords:
Id: WN9kgdSVhDo
Channel Id: undefined
Length: 52min 51sec (3171 seconds)
Published: Thu May 30 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.