🚀 DevTernity 2019: Ian Cooper – The Clean Architecture

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] hello hello I think I think it's time to start I hope you had a good lunch and you really welcome on stage John Cooper we'll talk about clean architecture yeah [Applause] so usual stuff from from organizers boring stuff ask your questions in slack use Twitter to expose your love and yeah enjoy thank you very much everybody who's heard of it the clean architecture before architectures boundaries controllers and entities phew okay so the goal of this talk really is to kind of get into what the clean architecture is where it came from a bit and why you might want to use one it's kind of properties and towards the end we'll show you a wrap oh where we have a kind of example of a transition to a clean architecture from a more well quite degraded kind of basic architecture so I mean coopered that's my twitter handle my DMS are open people want to ask questions on Twitter rather than slack et cetera during the conference so that they get some privacy feel free that's my bio I only ever really draw attention to the last point which is you know it's very easy to feel that you're there and I'm here and that there's some kind of implicit I'm smarter than you and that's just not true I'm no smarter than anybody here just confident enough to be on this stage please do consider yourself speaking at local user groups and conferences it's a great way to see the world it's a great way to improve your knowledge make sure you can articulate ideas which really helps when you're explaining things to your colleagues and once you get over the fear factor and I certainly had fear when I first started speaking it's a very very positive thing to do and all of you could be here promise you obligatory sort of mention I work or an open-source project called brighter it's a command dispatching library that effectively a bit like mediator but also does messaging a bit like saying service bus and mass transit we're always looking for new contributors if you ever fancied working on an open-source project were pretty welcoming so please do you think about coming along and checking out the project and us and we will the code we're gonna look at right at the end does use brighter but that's not really the focus of this talk at all we're going to talk about we're going to talk about the layering layering this got a bit of a bad press some people say you know layer systems are bad so talk a little bit about what layering is in isn't everything about domain models about how domain models get represented in domains in layered architectures why there is some significance the way we do that we then get on to kind of the clean architecture itself and how that represents basically those ideas and then we'll have towards the end some ideas about implementing it in code so but mine who's over here was the guy that really defined the term clean architecture and he has a book actually you can get most of the information you need in terms of what the clean architecture he's discussing is on his blog post about it but he himself admits that what he's talking about is not a particularly new idea or concept it's a synthesis of a number of ideas that have been occurred repeatedly so Alistair Coburn famously created this idea the ports and adapters architecture quite often called the hexagonal architecture because the diagram used to represent it is a hexagon Geoffrey paloma christen we called the onion architecture and either yak of sin created something called the boundaries controllers and entities architecture and there are other various examples use case controller DCI they're all variations on a theme a certain way of architecting your system and they all have common properties and so Bob really synthesized those ideas into the clean architecture so we'll talk through a couple of those ideas to show the commonality of the patterns before we actually get into discussing Bob synthesis towards the end but the first thing I want to talk a bit about layering who here thinks they have a layered system today few of you who thinks the layers are bad monitor view all right you're wrong but we'll move on from that okay so what is it what is layering layering is one of the most basic architectural styles there is right and if you go back to pollen ass and people like that effect attention that era layering is one of the first architectural styles people created and it's this idea that we could view our software as a layer cake or a wedding cake right where the layers at the top stand upon and use the services of the layers below so in this very simplistic model at the top I have a UI layer where essentially all my presentation kind of code widgets live below that I have some kind of domain layer that's where my business logic lives that the stuff that my application is actually doing and down below that it has some kind of infrastructure layer some people call this the data layer because they only think about this is accessing the database but really this is doing any kind of external IO including talking to a payment system or talking to the file system so it's sometimes call it the infrastructure layer and with each in each one of these layers your code is usually organized such that you have a facade over your majority of your code a buffer so what we mean is you have like a little narrow API a surface area of some you know some public classes and methods or some exports from a module file depending upon your your language implements and that facade effectively says he I provide some services to the lair above you don't have to understand the detail you only have to understand the services that I provide so classically my UI calls to some kind of class that says something like orders service in my domain layer which then controls exorcism orders objects which in turn talks some kind of repository or something in the infrastructure layer right and we'll get into more detail on that in a second but one of the other things to bear to see you in these arrows is that I can only depend downwards so my UI layer essentially depends on my domain layer which in turn depends on my infrastructure layer but nothing in my infrastructure layer can depend upwards to my domain layer and nothing in my domain layer can depend upwards to my UI layer this prevents cyclic graphs right I can't have a socket dependency where things depend in order to build this this layer I have to basically build a layer above but I can't build that lesson but a layer below and you can see me also show relaxed version a relaxed version allows you to skip a layer in between alright the other thing to bear in mind is this sorry um although we show these kind of three very conventional layers that is just a convention you can have any layers you want and you can call them whatever you want you could have 30 layers here if you felt that was necessary to represent what you wanted in your system and this kind of infrastructure domain and you I sort of Trinity it's just a convention and a lot of people assume that is what layering is you divide it into those three groups that's just a convention you can pick any layers you want and so for example in DDD there quite often talk about layering inside the domain itself okay so why might I want to do that the first thing is that I said well I think you're trying to do in software all the time is making easy for yourself to reason about the system that's one of the key goals of architecture and so what I'd like to do is be able to say when I'm working inside the UI layer I just want to deal with this concept of a domain layer down below without having to know all the details or more commonly when I'm inside there say domain layer I don't want to have to understand all the details of how I'm doing persistence I'd like an abstraction that just says persist my objects retrieve my objects so I can just in that layer think about I'm dealing with business logic and the notion of how I'm talking to the database is cleanly abstracted away from me I don't have database code peppering my domain objects inside their implementation I separate that out so I just think about base making a call to some data access object instead which hides the complexity from me of that lower layer so it makes it much easier for me because I'm only reasoning about problems at that layer not problems that relate to other layers I can substitute layers with alternative implementations given the idea that my layer has some kind of facade which says here is the kind of public API you talk to don't talk to all the details inside so I've got a data access object which just has you know create read delete update rows for the database which I don't have to worry about how that works right I could substitute one for another I can substitute one way of doing persistence for another now some folks say that never happens no one ever replaces their data layer and I'd say to you I've always replaced data layers everywhere I've been generally it's not necessarily placing a database quite often it's replacing a framework that happens to you that you move from one framework for doing abstraction to another you decide that and hibernates no longer the the best cheese and you decide to move your cheese to dapper instead and if you have a facade you can probably reimplemented oving too much of your other code if you think about something like a payment provider that you might use in order to basically take transactions can customers you might decide to implement multiple payment providers in case one is not working or you may seem decide to switch payment providers because you decide that you're you don't like whoever you're using to do that having a facade helps you switch people always say oh well systems don't really change things right so imagine once upon a time I decided that I was going to use web forms on web performance was basically the best way of doing you know dotnet applications and at some point in the future I think that's not the way I want to do it I want to do MVC if all of my code lived in the web forms pages not basically in a domain layer that gets very hard but it's much easier if my code lives in a domain layer for my actual domain operations and I can simply put a new UI on top and reuse the existing domain that sets and these things change this all the time people who've built applications using WCF and now faced with the prospect of replacing WCF or something like G RPC so change is really quite constant at any long-lived system so this notion that oh you'll never change it is really quite fulsome experience so layers are very valuable to give you that option you can defer decisions about their implementations what does that mean well sometimes in software it's is useful to defer decisions until the last responsible moment and so for example when you're working at say figuring out how your domain works you don't always necessarily have to understand exactly how you will do persistence at that point you can do your TDD against essentially your domain model and then later on and figure out how I'm going to persist stuff once you've got some of the more basic mechanics working and you're minimizing dependencies because you're using basically a facade the number of places that one layer interacts with the other layer is lower right why is that important well there's this notion and software essentially of coupling like coupling says my component understands how your component works if you change your component that change comes back to me and coupling is what kills you in most software architectures the big ball of mud which is this you know very bad software architecture example is just coupling gone crazy everything is coupled to everything else you disentangle anything what we want to do is reduce the amount of coupling so if we have a layers we only have a narrower amount of coupling between an upper layer and a lower layer that facade which means that it's much easier for us to change and cohesion is the other property we care about that's the extent to which things that change together live together and things that don't change together or apart and having base layers it's a way of us introducing cohesion because if they're dated there or the info other payment provider changes its implementation details that shouldn't affect the domain model and I've worked on you know systems where people had no layers and inside what you thought was a domain object it would just do persistence at random during effectively some business operation it would say let's flush the state here let's read from the disk here and the problem with that is it becomes incredibly hard to make changes because if you need to change how transactions work in the system you have huge numbers of places to change the code it's incredibly hard to reason about right I don't really sure when a database transaction might occur so you really want to try and focus on getting low coupling and high cohesion and in a good software system and layering is your most basic tool to do that we talked about our domain layer we can generally think about it as having two different types of logic we can think about it as having domain logic and domain logic here tends to be the rules of our business so if I was writing an insurance application it would be the rules that decide whether I'm going to insure your car and how much I'm going to charge you for it whether I'm going to insure your house and how much we're going to charge you for it and it has things like you know are you a smoker for life insurance right and those are the rules basically of our domain and they are things that the business talks about understands and you can go and ask a demain expert and you can say what are the rules we are encoding into our system and then there's application logic and the application logic says in order to actually make this software work there are probably a number of things we need to do in the sequence we may need to go to the database and get some data out once you've got that data out we can use that to kind of hydrate our domain model and make it happen and then we can basically after you've cooled it we'll need to save the results away somewhere in a database or we'll need to cool externally to this system that gives us geolocation data etc and those steps in the processing of a given piece of work or a task or the application logic in the system and so quite common modification to that very simple three layer diagram is to split our domain layer into two layers a service layer and an entity layer there are two basic ways of doing this the first way we say we call domain facade and there's a main facade in our service layer that for that layer has very little in it apart from the actual application logic all of the real power of our application comes from the entities that live basically in the domain layer and these entities are things that essentially say we have staked and we have behavior that is dependent on that state so for example I have an entity that represents an insurance submission and it has some states which would be things like you know where is your house located do you have locks on the windows do you have a large open fireplace you know do your children regularly throw flaming coals around for entertainment those kind of things are the state and the rules that go with them other things that are right on that state and most of our service nursing the application logic that runs over that that's a very thin service layer that simply coordinates access to those domain objects the other of approach is called an operation script an operation script actually we say we don't have much of a domain we really are some kind of crud based service where our since you all were doing pretty much is storing some data in response to users putting it in retrieving it updating it and deleting it and we don't really want to go to all the trouble of creating some kind of foe domain model there won't actually have anything in it so we kind of accept at that point that most of the smarts or application actually lives in what's called an operational transaction script the works are some very dumb data structures that actually do persistence of data back and forth I just have to figure out which one of your applications you have do you have something that has genuine rules they need to focus on or are you doing persistence and you don't have to make that decision we'll see later the same for the entirety of your whole application parts of it you can use operation script and the other parts you can use the main facade depending upon what you're dealing with so let's talk about this idea of ports and adapters so this idea comes from basically Alistair Coburn and important adapters is really just a variation of layered architectures it's led I'll touch you with a slightly different set of rules and when Alistair Coburn came up with basically the ports an adapter star identified three layers the first layer is the application layer and that contains the rules of our application we can think of it otherwise as the domain layer it's a bit of a bad naming choice because lots of people think of the application as being the whole piece of software that I'm writing and that's caused a lot of confusion for some people about how you interpret ports and adapters architectures because we talk about ports traffic in the application but the application layer in Porton adapters refers to domain more right at the heart so it's what we talk well the business entities live and where that goes on the adapters the adaptors are essentially the concern that deals with the outside world really so it deals with with input and output it's how essentially we store data from the system it's how we get data into the system and it's generally how we act on it and in between the two other ports and the ports essentially how this adapter layer uses and communicates with the domain so a diagram makes this a bit easier this is conventionally how we kind of show a hexagonal architecture so the reason for hexagons because he wants to give the idea of surfaces so over here for example we have a user solid right so conventionally we split this into a kind of left and right on the Left we have things that kind of inputs primaries that drive a given operation and over here we have things that generally are used by that operation so you can imagine here we have this idea in this outer box of an adapters we've got HTTP or GUI so an HTTP with something like at API or even basically Surfside rendered web code that effectively is where we're getting input in someone's filling out the insurance application and they're adding in all the data to the fields or a GUI we might be some kind of like you know WPF thing running on someone's desktop or even on a phone that's essentially talking to us and that basically brings in the actors that basically use those adapters to give us basically requested information and in the center these circles that present effectively the idea of this application so these are domain objects which actually provide all the rules that we want to run and the kind of line in between if you like the adapter layer and the central application layer either ports that's a cut so the aligner he wanted to represent we think I did a report on our computer where something you can plug something in right so the idea is these ports to the domain layer where you can plug in these adapters and the other is you can have things as well like mqp or WebSockets as we're getting things in or getting things out for notifications a database this is another adapter that plugs in to let you retrieve or write data and all these things plug into port so wait into the application so that's the adapter that's the application in between there is the port right and the port essentially mediates this conversation and you may have a given port used by a number of different adapters so different types of you while I could plug into the same port and we'll see later one of the things is tests tests can replace you I am just plug into the port and drive the application and so we can kind of revisit our layering diagram a bit like this we can say well the layers now basically rather than having just infrastructure and you are domain what we've already how much this adapter port and application and because all of the i/o is now represented by the adapter infrastructure and you I essentially all live in that less at that same layer right you have an adapter layer and below it this kind of application this domain low consists the port in the application and the rule is that we depend inwards or down again right but if you think of it in this model we depend in towards the center so here effectively everything goes down from the adapter through the ports to the application so you can see ABC we're going all the way down and that raises the question that pops up for us right given that everything depends in words how do I ever save anything right how do I had always because if my if my domain model effectively is at the center previously I had a model which said well I have infrastructure so the model would be I call one of my domain objects and it in turn saves mistake to the database and back and this model looks very different though right because I call essentially my port of access as my domain layer and then effectively I have to at some point call out via port to the adapter layer so what happens how does my port essentially e call an adapter layer because it can't depend upwards and this is where the repository pattern idea comes from and where we effectively do what's called dependency inversion in order for a lower layer to cool a higher layer because it can't direct your reference it what the lower layer does it creates an interface it says I'm going to create an interface to represent something I want to cool so the port says at some point I'm going to want to call a database I don't have access to the adapter layer it's above me so I need to implement an interface that says I represent me calling the data and then essentially when we build alright when we run our application at runtime the composition root and though it's the first thing we we hit there's dependency injection and it says wherever you need one of these interfaces actually substitute in a concrete type from the adapter layer so if I want to essentially have a way of accessing all of my customers orders in the port's layer I may have something like I order a repository and then essentially what happens is at runtime I use dependency injection ported by an inversion of control container to inject an actual concrete order apposite tree in whenever I create instances of say my order service class and people often say I don't they're posit Ori pattern is useless because it's just an abstraction over your data access and you don't need that right but the reality is you can't do something like essentially a portal that does architecture if you are directly accessing your data because your data lives in the adapters layer and you're breaking the rules because you're not depending in words anymore and what I want to achieve is that this layer in the middle this application layer is just plain old c-sharp plain old Java or a plain ol Python objects that are completely divorced from i/o concerns and makes them very easy to use with TDD because I don't have to worry about my TDD encountering IO and having to mock that out that doesn't exist at that layer my ayah really only happens while my port Slayer mediating a conversation with the adapter it's neither an incoming conversation were essentially something like a web request has come in on my API and essentially that that in turn calls my port and I exercised a domain or it's a kind of outgoing conversation when my port says I'm going to need some data it's in order to get hold of that from the adapter I'm going to talk to my interface and then at run time the composition route you know my main method will inject in a concrete version whenever I need one and still be magically calling out to the correct thing and that's where essentially dependency injection and inversion of control came from what while we doing ioc containers why are we doing di it's a support layered architectures such that you you can remove from your domain model that need to worry about concerns like IO ok let's move back a little bit so it's got ivy åkesson anyone know who Ivy åkesson is you had a Miyabi aqua said anyone yeah ok so he wrote this book growing object audio 20 software engineering back in the 90s I think he's the father of basically a methodology for kind of proto agile called rational unified process but he's also really wrote a vert this is a very good book on object orientation and all just trying to design but mostly he's famous for this anyone know what this is it's a use case diagram so use cases are kind of a proto user stories idea right and the Madeira is essentially is what I want to demo in my use case is what are the set of interactions that kind of make up this software requirement so here you can see the idea of somebody writing a use case for being served in a restaurant right so I've got a client that client basically goes into a restaurant as a waiter he'll order my food with him essentially they received the order and then they send the order over to the chef who cooks the food maybe essentially always to order some wine and then the red waiter when he signaled that the food is ready basically serves the food and the wine and then I eat the food and drink the wine and that I pay for the food and the wine and this represents very crudely a set of interactions notice that we don't drop down to the detail and essentially what serve wine or serve food kind of means the idea is were saying what is the kind of flow of work that we need to build here to represent something that gives an outcome to an actor and yeah consider came up with this idea also came up with a bit of a challenge for himself he said I really want to represent this in software I want my software to be capable of showing you that it's dealing with the use cases I don't want my software to focus on the frameworks used to build it when I look at my code I don't want what mime drawn to to be oh this is a MVC application or this is a rails application what I want to be drawn to is what are the use cases that my software is implementing how does he implement those so he came up with this model called boundaries controllers and entities so boundary objects he said well that's the thing essentially the outside that's what interfaces with the actual actor the person driving the system or or the partner application driving your system right that's the external part of it this is basically what bye-bye UML notation it still exists the entity the entity said well that's the thing actually that has the state and has the operations that have some dependency upon that state it's the business logic right we discuss this idea earlier and they said then there's a controller some that we've been renamed sometimes an interactive but people get this confused with the MVC pattern so there's the interactor and that mediates the communication between boundaries and ends to entities and his rule was effectively a boundary can't talk directly to an entity it must do so through the notion of essentially an interact or controller and that creates this kind of model for software right so my actor talks to some boundary objects which effectively these the control objects these controllers talk to the entities so we can see that that's very similar to what we're talking about when we talk about adapter as ports and applications our adapter is really our boundary object our port is really a control object in our application there are entity objects well why is that interesting well one of the other things that Jakob sim then says is essentially the controllers are were effectively you find the use cases the implementation of your controller is essentially your use case and those of you have seen my TDD talk one of things I talk about is that the objective of TDD is really about testing your use cases so what we're trying to test really then is against probably our controllers and you can also find that the other person who got really interested in the use cases and wrote a book about agile use cases was Alistair Coburn who went long to write hexagonal architectures and Alistair Coburn points out that the ports in a hexagonal architecture or where you represent the use cases and so a key idea with this kind of system is that what we're representing at this boundary layer in between boundaries and it's loading that parent objects that can align are the use cases on what I is a software developer or octet want to be able to do there's a benefit of this layering is say I can kind of ignore the MVC framework I can kind of ignore the repository during my persistence I can focus on what is the use case what is the business requirement and how is it implemented and it's cleanly separated from those technology concerns and easy to test and so our tests are to another adapter driving the port's driving the interactor to actually exercise our code and so rather than essentially driving it through a UI we drive it through a unit test and the poor is this unit test boundary okay we may have some integration tests around if it should be the adapter interacting with the port we don't tend to test the adapter directly so we don't tend to basically write code that's been our power controller directly in test stuff we actually test what the controller is calling because the system tests on the outside will check everything's hooked together as we're monitoring so don't write tests that essentially spin up your underlying dotnet SP Donette MVC framework controllers because then you've coupled your tests to a technology framework and if you change it to an audio frame what you have to throw the tests away but more importantly you've clouded the picture on what you're doing your focus is intended to be on those use cases so what is what is this kind of clean architecture idea Bob's come up with so this essentially is a clean architecture and it's very similar to the actor model we're talking about at the center is entities and we are using the same definition we're talking about earlier from Jackson it is essentially classes that contains state which they are encapsulating and operations on that state and the dependencies essentially the business rules for that basically apply to some state should be contained in the class that manages that state right the state doesn't leak out those classes therefore essentially that's where my my state for those belongs outside that I have essentially whoops the use cases right this interactor layer effectively essentially has my use cases and the use cases are what drive the flow of operations for using those particular entities so that's where effectively I have my check out use case for my online store which drives the entities underneath like the basket entity or the account entity etc that they're using right and that's one of the key up the key the key benefit you should gain from using this architecture is that all of this is just plain cold without i/o concerns that's easy to get under test you've driven all that stuff that deals with essentially computing away just dealt with the actual underlying entities outside that than our controllers gateways and presenters and essentially what we mean by this at this layer is that's the kind of stuff that you're forced to right by your frameworks or your friend market interact with you this is where your ass being on an MVC controller goes right this is where effectively the code that you write that the framework calls that's where that lives and then outside that you have the framework the device is the HTTP itself and this diagram in the corner represents the fact that the flow of control requires some dependency injection because my controller effectively calls my you kiss case input port I do some kind of work but I may want to output the results and to do that fact if you say to a database what I would need to do is essentially dependency inject that into my application so you can see a model here that essentially shows you that bit more detail I've got my delivery mechanism essentially uhp for example it comes into a boundary layer which might be my controller that I'm writing for my and my MVC framework I've got the in gracyk aliy these data objects because I don't want to pass my entities directly back and forth across the boundary as I cross interface layers I should essentially try and respect the fact that I can't pass entities up right I depend inwards so we've got a request model in a response model and a request model is coming in from the HTTP it's all my form variables my query string components and I've got a response bottle come back out and my interface will interact that's when my use case is being written is essentially a thing that's controlling my entities it's not like an entity gateway interface which is at the same color coding is boundary is my adaptor for talking to a database for example right so here on this version you can see that kind of spoke about well more concretely an API framework calling a web controller it passes in a request model by looking at particularly the parameters on HTTP and the form variables turns them into a call to my web controller using the URI as well etcetera cause might interact so which then basically calls my miss my entities and talks my entity gateway and produces a responsible in return if I have essentially an NVC framework it lives here right it's part of what the web controller is doing to essentially say what I want to do is put the Outlands effectively a view model this idea of actually of the data that I'm writing in a testable fashion because I can't really interact very well in unit tests with the view so if I want to really test the presentation of my model I'm going to use this kind of presenter view model pattern but all that kind of code is that the same layer as the web controller all right it's not part of my interactor or entity layer and in the same way this is how I talk to the database I've got some kind of gateway some data access object some repository that's effectively abstracting my way to the database because again I can't pass effectively you know that directly in to my interactor so I have to basically use dependency injection to do it I find it's very useful when I try and implement this to understand the command pattern so the command pattern as I'm sure you all know is this idea of saying I can encapsulate a call to my domain it has some parameters which you basically go into the constructor of the command and typically the come one has an execute method and the execute method actually calls a domain and if you think about that you think the command doing something basically on my domain it contains some application logic it's often a transactional boundary right you can see that the commands are natural fit for an interactive it's something that essentially my adapter layer can use to interact with my domain layer it encapsulates the interaction and it encapsulates the application flow the transactional boundary is some of the i/o so commands are a very good way of building that interact to that port right or surface layer and then they align nicely for me with the idea of ports here is a command I can call from multiple places in order to make something happen that is effectively my port over the application commands are very easy to implement right so you have some kind of interface saying execute with it and he just do all the work in this keep method so here are essentially my boundaries effectively dealing with a command as the interactor weight and I have a concrete instance of the command over effectively there the other variation of this which you'll see quite commonly it's what things that brighter immediate and help you do is effectively to have a command dispatcher model although the spatula does is it separates those parameters from that execution and it says in order to make this truly effective decoupled you will fill out a command with just the state that you need your pass it to a dispatcher and the dispatcher will find a handler and that gives us the ability for us to say well you don't even need to know the level of the web controller what Paul implements this I will find the port that understands how to receive these requests so your routing effectively to a port an aside had to do those requests and that can be useful because you can set up basically a pipeline and it lets you do orthogonal concerns like logging et cetera in that pipeline right okay so we've got 10 minutes or so to run through so have a look at some code I'll have to remember to mirror screens in a second no doubt that's alright I see ah how readable is there at the back thumbs up for good cool right you can this code is on github under CA tutorial it is the world's most over-engineered hello world application it has a basically web controller here that takes essentially requests for greetings well you can post greetings into it essentially whereas my post ignore the console write lines have come back that a bit later but I can posting greetings I've got some entity framework going on there where essentially I'm saying save my greeting and then get the greeting back and return back as the response to the post equation was created and I can go and find you know all the greetings that I've so stored so far or I can essentially go and get specific greeting finites identify if the application you all need I know you're thinking to yourself how wow I could build a business on Ian's application um okay and you can see so basically we have a number of branches this down here in the bottom and if you can see that that's essentially a visual code giving you an idea that the branch github you're on and you can see what we've done here has pretty much gone for the non layered version of our architecture everything is pretty much done inside the adapter layers controller and the problem is I've got a lot of repetition here right a lot of places doing this going get essentially a specific greeting by doing essentially a bit of link for entity framework to go and get results out I've got all this stuff which is pretty meaningless to me located in there and even though I don't actually have much in the way of domain logic it's a bit of a spray of kind of concerns inside my controller so the first thing I might think I'm going to do is well I think well maybe I'll introduce essentially a liar I went to IANS talk analyze it good all right so maybe what I'll do is I say let's have a nice little layer in here so here what I'm doing now is I basically create a greeting facade and rather than essentially putting all that implementation code directly in my controller I've now got some separation all the facade needs to do is say although the control needs to do is say there's an operation that's dealing with this right and so here I can actually understand what this whole thing about all those console.writeline statements were doing it's something about putting my greeting out right this retreat operation controller looks a lot cleaner okay and actually if I look at basically how this is working I have this I don't think you know that I think sorry sometimes miss your to do code needs to be persuaded a little bit hard to change its opinion about where we are what what things it can see so don't believe you actually have that you have something else where's my facade okay that's interesting okay right so the north stuff in green that doesn't really exist in this project the greeting facade here says well I call these methods are they saying or you know will they sink to the a sink etcetera right and in a sense why I know I can reason about that more easily I can deal with individual parts of it maybe it's easy to get under test I still whatnot not a clean separation between the alejo and the actual everything else but then this is a knotty application so it's really only got a oh but I've also got all of the concerns around greeting in one big class that could in a real world scenario where actually got some application logic in there it's gonna grow quite large it could turn into one of those 600 lines service classes that some of you may have seen and let's a look at that I think also the other troubling tends to be with these things is though there's not much in this case you can get big constructors that pull in loads of dependencies that relate to different kind of files so what I might want to do instead is break that one up a bit right and I can say listen well if you want to look at this code yourself just moving through the branches is the way to do it and if you if you use something that isn't quite as hostile to that you know as if it's your studio code rather you don't have to keep changing this stuff so I could break it up and so rather than having one facade I can have many facades right and so now I've got basically just broken it up so every single operation on the facade is actually now a separate item so I've got something for doing grip fur doing greetings all got indignities got ID and the advantage of that when I go up here to my greetings controller it's a good a certain amount of reuse now all right I've got this notion of retrieving a greeting by ID so I can reuse that in my post to pull that operation of getting something back and I'm already starting to get a little bit cleaner now I've got things broken up and I look at them and I think well hang on a minute if I've got these facades that essentially are single operation surely I can just abstract that out and really that gets me into a command right so now I've got this notion commands which say basically well I've got a quit while queries in commands I got a query I've got a command and those just a simple objects that I can then go and deal with and my ports are essentially these commands and these queries so my use case layer gets the certs commands now I haven't got much logic but imagine I have some complicates business logic the application logic will be happening here and in the actual greeting itself will be when my entity logic existed so I've got the lead greeting and greeting I've got this notion of regreat vent which basically is putting stuff out to the console quite separately and my control is quite neat and finally I can say well hang on a minute what happens if I say Daisy I don't care do that anyway [Music] okay you know get to check out clean architecture with commands let me just do this the hard way oh I'm gonna run play CD though I had this opened oh geez come on just let me do that sometimes I have to delete something I think that's usually happens to me please move them and uncheck files really well it's anyone only just want an update that change and we commit that mmm sounds control I'll figure out what that is later so they'll clean it up when you guys want to split stuff around but that should hopefully fix it now right sorry about that so in this model we separate the command itself she only has essentially its parameters from the handler what you're doing here this especially using bright ran cyclical framework because you're saying I'm gonna implement this handle method which is effectively the commands execute method I'll pass the command in the dispatcher gets hold of that right and do the operation but because I have essentially a pipeline because I'm using a dispatcher I can move off some orthogonal concerns this is way the brighter it presents that essentially it puts attributes on to your handler where you can say things like I want to love this request and I want to use poly to effectively provide me with retrial circuit breaker operations that's just a typical example of why you might use a dispatcher all right and over in my controller it all looks very similar to the web app before which is essentially to have this kind of model write preprocessor to read executing all right so let's get back to the presentation we're almost done it gets the demo all right so it's only just a little box to remind you devoted the Emma's actual text on any of the slides okay so just a kind of final recap I swear I've run slightly the the clean architecture is used to cleanly separate your application domain code and use cases around that from the infrastructure concerns and it does that by making you obey the rule of always depending inwards towards essentially code that has less infrastructure and more just plain old plain old Java or C sharp or Python that you easy to get under test and easy to manipulate easy to reason about and there were advantage of that is that by divorcing yourself from these concerns it gets easy to test and easier to replace stuff and easier to focus on the thought your code that really matters which is the use cases driving your actual business behavior not the frameworks and the trouble with the more traditional models is my focus is really taken by the framework of a rails app I'm a national MVC app I'm really you want to think you're an app that deals with these use cases of handles this business logic and that's what clean art it's all about thank you very much [Applause] [Music]
Info
Channel: DevTernity Conference
Views: 38,228
Rating: undefined out of 5
Keywords:
Id: SxJPQ5qXisw
Channel Id: undefined
Length: 53min 5sec (3185 seconds)
Published: Fri Dec 20 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.