Code Reviews: Dependency Inversion and Injection

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey fellow developer welcome to frankly developing and our new code refu series I'm your host Frank and today I'll look into applying the dependency inversion principle I'll give you insights into my thought process and how I approach the code we will continue from the previous video so so if you haven't watched it yet but want to I'll leave your card up here don't forget to subscribe to the channel and leave a like if you enjoy this sort of content but now let's get started [Music] so welcome back to the monster collector and let's take a look at our list from last time and we said we want to refact the cohere manager into some better object oriented design make it extensible for other llms so let's take a closer look in this one what we have here we have like the get text method that's just one usage which was in the monster part where we generate this name from it oh yeah that was the part that was kind of odd so that's something we may want to improve on the way and then essentially we're just giving it a prompt some input which is kind of the prompt so what's the difference really kind of strange name and we look at what this input is it's the list of the names to ignore so maybe to avoid dlic Cates or something like that okay how is it using that input it's like it's an appended user input ah okay the other is a system prompt all right so let's say we want to stick with this interface we have a lot of options now to make this extensible for different llms basically but let's start easy and say like we leave most of this intact and and do one step after another so as we said in the beginning we want to apply the dependency inversion and that means we need to get rid of this static here first and make this a proper object so to do that we essentially need this method in a nonsteady fashion all this I think it's also a good convention to have these software with ASN because C shop doesn't really tell you about this see okay this basically redundant so this is now our instance method and we have two usages now one here one outside so to move over to the object we can change this one since we don't have any state it's good enough for now not a final solution of course and now this one basically is no longer public thing it's really just private which means we can basically remove it now and have all of this in the other one just now for the away call and there we go now it's done there's another thing with this valid so just for consistency so now it's no longer static it's proper object and commit that now let's start with the actual dependenc inversion for that we want to not depend directly on the coher manager so the dependency now is from this monster class directly to the coher manager and we want to invert that to have like an interface available well for that we need an interface so let's see in Factor uh we want to extract an interface and I'm not sure about this validity so for now let's just leave it in there and it's called ioh here manager well since it's supposed to be the extensibility for the LMS it's more like L them for us so let's extract that and we can move it file now in order to do the dependenc inv version you want this to depend on the interface but that means we need to somehow get the interface object in there the implementing object which is kind of in a strange place because this is an Entity framework class so we don't really want to mess with that and instead maybe think of a different place like some monster Factory kind of thing that creates the monsters and does all this stuff for us um for that we need to make this method here in dependent of the monster first and then move it so how do we make this independent we have to De static and now we can see from the compilers the stuff that we need that is not yet there so we see this is referring to properties of the monster so we really need a monster in there let's fix the to places and give it the monster and now it's redundant but I will change since we got move the method eventually so now let's make sure that we can make this static by so now it should be possible to make this static there we go and now we can introduce a monster Factory kind of thing we can have some kind of create one where course we need a master and then we want this method in there which means we can now copy it over and private oops oh but we still need this list of ignore names and the custom Pro and then you got back that created monster now we want to move all the old code over to use this new mon Factory so let's take a look at these two usages again this one is pretty easy and this one is kind of odd because it's looking at this validity of the coher manager first and if that is not Val that it's doing it that's kind of strange so it's not directly replaceable but we can think about introducing that to our Factory as well so we have a dependency here to the C manager I could do the same thing here now of course we changed also the controller which is something we mentioned in the previous video that it's kind of bad to have an inconsistency anyways now this is also fixed by having it in the same way in both places now we can of course create this in a different way let's take a second look again on this monster Factory and how far we are the care maner here we have it down here so basically could extract that one it in but actually already have the interface so what happens if we just use that one instead I see oh that already works so this one is the concrete usage this the interface and now the variable is really just our Strange naming here but it's just our L now doesn't even have any knowledge of cohere anymore in the rest of this code other than this initial assignment and so when we look at these two usages um the controller should be pretty easy to hook up to depend rection database Contex is a bit of a different past though because the your database context is being used all over the place see there's always a new creation of the database context and something like the initialization of this well that's kind of in a odd place here don't really want that happening here so this is something we we would like to move out and also it's not part of the database context for the singer responsibility principle reason like supposed to work on the database and support these methods like so how can we get this out of the database context then add something initially to the program build our app we can have like function here I'm copying all of this over input from Factory and now this last part here we just do directly on this database context now this is datas initialization in here and it's no longer needed done each of the contacts which means we also don't have to check for the database existence each time and also remove the initialized monster method and we have to call that once at this point it's kind of lot of stuff going on here in the programs here so we might want to remove all of this into separate database initializer now we should be almost completely finished here to replace this direct C here mat with an interface usage we use it in the database initial what we have under control we have the monster Factory under control there and there is the usage in the monster still oh that's no longer use good and since that is all gone now we have only two places for the cre meas is still being in use yeah we haven't extracted yet so let's extract it into a field just like we did for the factor for the final thing we need to go and take a look at our most factor it's still a static dependency if we want to go through dependency section this needs to be a nonstatic which basically means we need to remove the static from here and now we can actually make this the parameter in so later we can use theend injection together bring it in for us we only need to adjust the two usages move the dependency out on Stu and the same thing for the database initializer we can do the same thing here now we can complete the whole Endeavor here by finally setting up the dependent injection here okay we want like a singon want to use LM use the career manager now we need our Factory now we can retrieve them instead of getting direct access to the the manager you can now use the dependent section say we want to get this LM service which has been registered in this place just like in all the other places so we can look at the remaining usages this one here uses the factory within manager since a controller it has access to the automatically so we can directly get the monster Factory and just use it and here we have the mon Factory we have now moved to the dependency injection so we really don't want that manually created so let's also add it so now when we come back to this re manage as you can see this is now the only usage so now we're in a place where by implementing a new interface um a new class for this interface we can just replace it here and that's it you could go even further and make this Dynamic um loaded on demand depending on the API key you have set a your environment VAR stuff like that but basically all you would need to do is create a different implementation class here for the LM and it will be used everywhere that's way easier to replace there that's also using the standard dependen injection approaches to simplify all of that code because as you can see from the LM usages there's another little thing here that you could um look at and that is like the database initializer and its use of the monster Factory and the llm because it seems like you would only need it currently for the monster Factory when you generate a monster you want to call to AI so why do you have to do it separately database initializer well because of this here it's kind of getting annoyed at you so like you have to have the API key which really doesn't matter if you have a monster Factory available right so that is kind of a place that will most likely go away as well and this is valid method would pretty much be moved out of this interface as well probably let's just do the F commit so this concludes our work on the monster collector and I hope you like this series it is quite different from the other content and that it's really slow and I try to speed up some of the aspects that are really straightforward like the commit message writing and so on but in general you can see how things are progressing slowly and slowly overall like it doesn't take too much time as you can see in in this short amount of time we addressed a lot of different Problems by cleaning this up so even if you have like just one or two hours left at the end of the day you can do a huge amount of work in that respect once you start seeing these things more clearly it'll streamline your thoughts during the creation already so for example once you set this project up like this you will probably use the dependency injection a lot more already and introduce dependencies like that you would have much easier time testing things and of course in this project tests have been completely missing so something that might want to add in in more production usage kind of scenario but in general there's lots of different options to go and I hope you find interesting to see how I went on these different options how I approached them and what I think is good or not good and again this is just a personal opinion and please keep in mind that none of this is like a final say on how this project should be developed while will create a PLL request from that I'm perfectly fine with it being rejected because you have to match your goal your vision to all of these refactorings you can't just refactor just because it looks better it needs to match your ultimate goal where you want to go and I have no idea where this project is going so this um is really just a proposal things to think about and I hope you have a lot of thing uh things to think about as well now U enjoyed watching it so thank you very much for watching it and as always have fun develop in
Info
Channel: Frankly Developing
Views: 221
Rating: undefined out of 5
Keywords: FranklyDeveloping, CodeReview
Id: NgA7h-V9dWE
Channel Id: undefined
Length: 16min 59sec (1019 seconds)
Published: Fri Jun 28 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.