Implementing the Clean Architecture in .NET Core - Ian Cooper

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey everyone so you're all still filtering in there's a lot of you and you're from where I stand quite up scary hi some of you I can't really see because of the lights that I do this it just means that I'm being blinded hello at the back hello well I don't know if you guys might not know you might never been up here but this thing is kind of suspended over the actual stadium down below and when you walk upon it it kind of bounces under your feet in a way that it says to you do you trust the engineering skills of the guys that put this up look at those cables that's all that's between me and certain death yeah hence the the kind of blue M&Ms story from Van Halen okay I will just while you're finding your seats I will do kind of the boring bit where I talk about me so don't panic if you're towards to the end there people on the sides if you could all shuffle in towards the middle a little bit that would probably really help because otherwise the folks on the side are having to climb all the way up to the back some of them may be suffering altitude sickness at this point already okay for those of you don't know while sitting down my name is Ian Cooper hopefully especially those of you packed in the middle you've come to hear me talk about clean architecture and dotnet if you're in the middle and you're expecting to talk about Ruby or something I'm sorry but you may be in trouble now okay this is kind of my bio and it's really fairly dull it just says I'm old but the key point as to what I always try and mention is the one in the bottom right which is I would really encourage you not to believe there's any difference between you and me I am NOT special I'm not better than anybody here I'm just other dev I just happened to get into standing on this side of the stage because frankly when I started doing net no one was talking and I was running a user group so we had to I had to get out myself it is really good for you to do it it helps you organize your thoughts it helps you think about material how you present it to others it makes you think about how you how articulate your opinions and I would encourage all of you to have a go find a local user group there'll be people that want to help you and try and get in despairing your thoughts of people okay please do try and stand up you are just as good as me and that's why I work for you're probably uninterested in who I work for the only thing to say about it is I work for a software company not a consultancy I'm trying to sell you anything I have no books this is an open source project called bright so that I work on you'll see some code examples towards the end that use brighter it is a CQRS library it is a task you library and there's a messaging library it's similar to say mediator and mass transit and we're lucky enough to have 20% time at Huddle's so we can spend quite a bit of time supporting and working on this particular platform please do check it out I do have some stickers in my bag down here I can put them on the table anyone fancy is a brighter sticker for their laptop they're kind of cool we couldn't get Scott Hanson to pay any attention as a project and so we had stickers once we had stickers Scot cared about us so he wants a sticker come and grab one off me at the end okay we can talk about so I'll talk start off by having I sought a bit of a tiny chat about loose coupling and high cohesion because they're kind of relevant to what we're doing today then we'll go back and talk about layers right because layers are really the key to understanding what clean architecture is we'll talk about domain models because some of the interesting bits about cleaning architectures are how you deal with a domain model and what is what is in lives in entities what lives in interactors or ports whatever you're going to call the depending on your preference and then we'll talk a little bit about this idea from Bob Martin called the clean architecture explicitly and then I will probably deal a little bit with this issue of how you implement ports interactors we're going to call them because that seems to be the bit that most people struggle with when they're trying to work on this kind of project and I've got a little example piece of code will take through it goes from sort of just a MVC app that's essentially got over all the coding aligned and the controller and we'll show you basically putting that in different places to try and improve the design of that application so the term clean architecture just to really cool it out was one that came from Bob Martin and he's got a book called clean architecture the book tends to have a lot of his material about being clean so bob has this whole series of books which used to work clean to effectively mean well engineered very modifiable code and the clean architecture book takes some of his existing ideas that you all know and loud solid principles etc and talks about them in an architectural context but the core idea of the book he's also mentioned a virus blogposts is this idea that there is a architectural style which he calls the cleaner architecture which is a very useful approach to a large number of systems particularly most line of business systems now Bob's pretty clear that that's not his idea what he's doing when he calls it cleaner architecture is actually collating a number of ideas that have actually occurred to various people over the history of computing and some particular call-outs we might want to make at this point who inspired this idea of clean architecture one of the key ones is Alastair Coburn with the ports and adapters or hexagonal architecture for steps is the technical name it's often referred to as hexagonal because the diagram was essentially have hexagonal shapes in them the Jeffrey Palermo Craig in in the.net space come up with this idea called the onion architecture and a long time ago back in the 90s I become some came up with this idea called boundaries controllers and entities or BCE they are all essentially variations of the same thing they are all rediscoveries of this same ideal architecture you know we get this kind of thing that happens in computing is that we continually reinvent everything you know everything was actually invented in small talk back and lean in 1980 or whatever cetera but the reality is we just keep reinventing the same kind of ideas and what bob was calling out is there's this common theme to the set of ideas as to how we would organize our architecture that seems to have evolved quite independently amongst these individual practitioners but if you look at it are essentially saying the same thing and what we'll do in this presentation is we'll wander through a few those different kind of reach to get there because actually having a range of them helps us to really understand each one because so for example cut ports and adapters one of the questions people often have is or what is a port I get what the adaptor is what the domain is what is the port and if we look at other ideas like BCE or just simple service facades or the onion architecture actually we can get a clearer idea of some of those more confusing pieces all right let me show you first of all some code yeah where am i okay you just switched the rapper okay so this is a pretty standard don't know cool you know one seed at the back going to make a bit bigger can make it bigger bigger bigger right because you're all the way at the back that's one bigger that's good excellent this is a really standard dotnet core Web API app the kind of thing that I'm sure you build or you've built a version in you know MVC web web api for Precor or you've used I'd know Nancy or open raster but it's a fairly standard lighter thing right and all we have here is essentially a control room we have advert various methods that receive HTTP requests on here so we can say I want to basically get I can see we can say get by ID I've got post and I've essentially got to delete now what this application is actually doing I will show you by looking some tests so this application every every you know every speaker needs to have their demo application I decided to create the world's most over engineered hello world application because you have to have a domain simple enough to explain in about two minutes and then we ready cope late with the fact that simple simple domains don't help you so essentially what we can do is we can get a whole list of greetings we can post a new greeting hello world or you can see hello Mary or hello Alice right and we can delete greetings now somewhere over here I can probably spin this off and show you that actually works that's a quick look if you just don't want this one this bit is I mean if you can't read it is unexcited I just need to build this piece of software and then run docker to run it so if you can't read it don't panic there's nothing here that you really want to care about but when we flip back over here what you'll see is that all of the code is essentially inlined into the controller so when I do a get I'm simply going to get a greeting context that's basically an entity framework context just standard ng framework boilerplate code with a set of basically my greeting objects and then I can turn them into an array and then I turn those arrays into some kind of view model object my greeting ID result and then I put out my greetings all result essentially as a return and good old asp.net is going to return that into some nice piece of Jason for me that represents essentially my actual objects and when I what's post yeah ignore this these few lines we'll come back to it later I'm grabbing a context I'm creating a new item I'm saving the item essentially and then I go and retrieve the item just put in the database and I then return okay and give his representation I'd like to search it from the database and let the asp.net runtime take care for me of basically turning that object into some lovely jason that goes on the back end and we're running through that reasonably fast because i'm sure that you've all built apps like this many times okay and just so you can see it working we can run some tests against this file so I can send a request and you see back it's saying to me right well you've got an empty database is 200 okay and I can stick a request in so basically goes away and it says okay I'll put on that date entry into the database and then you can and then I'll quarry the database with the ideas got inserted I'll get the item out and I'll basically put the JSON back out onto basically the wall I for you and you can see basically I've now got the idea that item added so now if I get all the items you can see that I've got that item and I can add another one and you can see that I'm now getting multiple items right when we look at this code obviously we may wonder if this is good code given the complexity of the problem that I'm solving it's probably absolutely fine okay but if this is actually a genuine business problem we might begin to wonder whether this is the right way to do it I've got quite a lot of repetition around this idea of going and grabbing a single item by ID and turning it into a result object basically that I then put out on on the wire right I do it there and I do it there and I sort of partition between the same bit of codes just doing the same thing I've got quite a lot of ideas mashed into my controller right I've got here's my basically the abstraction over here's my my context basically for entity framework here's some link statements you know talking to the database here's this weird bit of code that's basically writing out some kind of console application so I received some data logging in something in some way maybe it's not the best idea maybe maybe actually I can think of a different way of structuring my application so that all these different ideas weren't mashed into the controller and as a thought experiment other thing to think is let's say I've built this originally in a different framework like open raster or Nancy and then I decided when net core came along you know what I'm gonna use basically Web API I've done that core be quite difficult to transfer that code around right because I have to take all this code out of the controller and to figure out basically what goes where or if I want to just use a console application to call this how would I do that so how would I swap over the interface given that it's all there any other questions how do I get this under test right how do I test that gate controller well I could potentially mate I may be able to just spin up that controller but actually it does some weird things with that return okay and tasks action results what am I going to do with those and maybe I get some test harness that lets me spin up controller instances so that I can actually test my code living in my controllers but now my tests have taken a dependency on that framework for testing MVC API controllers and if I wanted to move that code to a console window how do I know that it works I've got to repeat the tests now in the console window I can't extract them away from that testing harness so maybe there's some kind of better way of doing all this all right so that's just kind of setting the scene for you and then we'll talk a little bit about this idea who's who's heard a loose coupling in high cohesion as an idea okay most of you right so my job title says that I'm a software architect and a lot of people say well what does a Software Architect - isn't that just a highly paid developer that isn't really true software architects actually engage in a particular subjects in a software engineering course or architecture and one of the key responsibilities that software architects have is politician in a petitioning really means breaking up the system into pieces and the reason we want to break the system up into pieces was you want to improve basically the modify ability of the system we want to make it easy to change our software it turns out that writing version one of the software is usually very easy by comparison to maintaining it I sort of tweet recently by someone who'd gone to work at Starbucks and he'd pre-fit internally heading up their IT function and he previously worked at digital agency and digital agency is what you tend to do is you support a given advertising campaign I'm gonna produce the site for the Han Solo movie and I'm gonna do all the interaction for customers and it's ephemeral doesn't last very long it time to market is really important he produced his software and it dies and that was his entire experience and when he got to Starbucks he realized wow these guys have got a huge problem that they've got source code that's living for years applications that live for years if customers like to rewrite them and really a lot of the developers here they're one of their key focuses is how do I maintain software how do I keep that software alive and one of the things so far architecture and theory help us with is how do I make it easy to maintain software and partitioning is a key strategy towards doing that and a clean architecture this concept we're trying to talk about is one where we say okay the partitioning will lead to low coupling in a high cohesion what do we mean by those statements okay so coupling is this property of a system though one we make a change over here that ripples and we end up basically with all these things over here needing to change as well okay so I change the interface that I'm using by effectively changing the signature of a given method call and that has an effect that all the coolers now need to be modified so those two things are said to be coupled because the change here represent effects those things so we can have this direct dependency style coupling where one given module and you can read for that anything class you know modules in Python etc whatever your particular preference is has a direct dependency and it says if that changes I will change but you can also have coupling about knowledge okay so the algorithm for calculating your insurance premium lives in this module if I cut and paste for that and put it in another module I now have coupling between these two modules voila that duplication so the problem the duplication is really about coupling duplication that has a problem is a special case of coupling the reason why some things even though they are duplication are not something you need to worry about like I call string.format loads of times on my application should I replace every call to string format with another with another method cool there are apps on my calls to string format of course not because that's Turtles all the way down right I don't have to replace all the calls to that to something else so you might say well hang a minute isn't it you plication there and the answer is it's not duplication in terms of duplication of knowledge so you haven't coupled to things if both of these two modules contain my algorithm for how I calculate an insurance premium if I change module a and I changed the algorithm for how to code insurance premium if this module doesn't change then essentially I have a problem that I'm now calculating the insurance premium correctly on both sides so I'm coupled now you may think that's insane that would never happen I used to work on a complex risk management platform for mid tier banks and we used to calculate a whole range of statistics of traders care about basically these Greeks as they're called and we literally had on different screens different numbers because different algorithms have been used to calculate those numbers on different parts of the system and we had a problem of coupling because we had multiple representations of that piece of knowledge so we can say something is loosely coupled if a change to one item doesn't result in a ripple effect and a change to another item right and loose coupling is something that is desirable because it reduces the cost of change I can just say hey this project involves me changing our insurance algorithm I'm gonna go and change these modules but the rest of the system is fine there's no impact all of the teams don't have to worry okay and cohesion is the property that were subject to the same forces of change in a module a module at low cohesion has many reasons to change right if you just basically have one module and everything is in there right and it includes essentially my and including sound building an insurance application includes my management of brokers it includes my claims sister system for working with someone claims against their household insurance policy it includes my actuarial staff for basically figuring out what life insurance premium to charge you because you smoke if all of that is in the same module that I have lots of forces wanting to change it right and the problem with that is as soon as I change your module really I have to retest that module that's kind of my testing boundary of a kind of you a and it's also my boundary if I start continuous integration and rebuilding the software and why should it be that my management of my relationship with brokers is impacted because you need to change the algorithm deciding and how much your insurance premiums should be because you smoke okay so if I have unrelated ideas in the same module and have different forces of change we tend to say essentially that a module has a low cohesion okay and I'm Roger that has low cohesion has Timmy reasons to change and that results in basically the code smell we called divergent change okay all right let's talk a bit about layering this is a classic layering model sit diagram of system who is built a system with layers okay and everyone in the room right this is a classic three layer model at the top essentially I have my presentation logic my UI so this essentially is where effectively I have my MVC and I a layer of a pattern where effectively I figure out what I'm going to put out my web api what I'm going to put out basic HTML I'm gonna play out via MVC or maybe I'm in actually in a rich client and I want to talk about basically what happens on my windows for WPF page right down below that I have my domain model right that is the business logic that's how I figure out what I'm doing that's where I calculate your insurance premium that's where essentially I deal with your claim for your water tank having burst and down the bottom I've got the infrastructure layer quite often referred to as the data layer but it's essentially where I'm doing things like getting data talking to a third party system to look up zip codes or post codes etc right and the key idea in this layered architecture is that dependency is always downwards okay so I depend down and that means I don't end up with these notions of circle dependencies which are bad right if module a depends on module C and module C depends on module a I have trouble building any one of them because to build you always building the other side and then building the other side involves building you and what happens if you both have changes all right that's going to be a problem so we want to basically remove those cycles from our modules but the value of layers it's not just in that dependency it's in the abstraction they provide essentially layers help us partition the system we could take what are you while I can punch them put them in a liar and that is what we reason about UI ok and I could SWAT that a layer for something else right my NBC my web api layer could be replaced with a console layer so I can actually come my lan interface everything you know because I've realized that the come Milan interface is best that's really what we should be forcing our customers to do again not in this JavaScript HTML nonsense they were better off when they just typed it'll two little codes into the console right or effectively I can actually have it so it's basically wynant's talking for web api ones talking to my MVC layer that's from presentation layers that I want okay so I can swap out basically my infrastructure layer right I can decide a sexy to have an in-memory database for testing I can decide n to use a real database obviously essentially for actual production code or maybe I don't maybe a siding maybe a face is good enough and the in name structural layer I may have for example third party services that I'm calling let's say I'm calling payment systems or maybe calling lookups for ZIP codes and it's quite possible there commercial providers who I have a falling-out with because they're their service quality is rubbish and I don't want to replace them with somebody else by putting it in a layer down below and partitioning off I only have to replace that portion of the software the domain is not impacted by me wanting to swap out the payment provider okay so layering is a very useful partitioning of the system because it helps us to understand the system more ease we can reason about what's happening in one layer without having to about with something the other layers and we can swap out pieces that we basically have decided up we want to change so it's a sports change and so we get some cuts of cohesion and reduced coupling by using layering stupid okay one thing to note on this basically is the quite common approach here that says actually I'm gonna split my domain into two kind of legal sub layers and a partition my domain lot layer further I'm gonna start thinking about that as having a service layer and an entity layer and the service layer is going to contain my application logic and we'll talk more about what that is during the this conversation together and my entity layer is essentially going to retain basically my state and behavior around that state okay so we can distinguish two types of business logic domain logic has something to do purely with the domain right it's basically saying this is basically how I calculate your insurance premium depending upon the variable so you have given me whether you smoke whether you're single whether you have kids whether you drive a fast car whether you're a journalist apparently that's a big no-no and that information tends to be basically what we can we consider logic belonging to the actual objects in the domain an application logic which is really to do with coordinating those pieces in order to fill some requests I may actually need to talk to two or three objects I might want to create a transaction to make sure that I have transactional integrity in the system I might want to raise events to downstream systems to let them know that something happened and this is not a responsibility of the domain but it is a responsibility we need to fulfill if we are to basically provide these services that someone is expecting from our application so the service layer provides application logic right so we talk about it between services to the service line the entity layer the service that's provided in their application logic right the coordination in control logic fraud the workflow for it one of this key responsibilities quite often is simply to load the domain model alright but the main model essentially it doesn't exist until you load it from the database you can think their main the domain the entities set your system is kind of like a rules engine right way rules engines work is you declare a whole series of facts and rules and then essentially what you have to do is to populate those facts and rules with data and then exercise the rules and say what happens and really you're doing the same thing your application logic layer is saying I'm going to load these objects into the domain model populate them in with these facts and then exercise of the main model load this customer look at their details now calculate their insurance premium you don't always want to do that right this is a bit of a caveat here sometimes actually your domain is very anemic and you should justly accept that don't people talk about anemic domain model as that some bad anti-pattern that essentially you must never have you shouldn't have it anemic domain model if you do have a rich domain but sometimes actually your domain consists of storing stuff right and that's fine in writing a customer contact database probably there's not a lot of actual detail and you may be okay with a data structure and application logic to control it don't panic if that happens to you that's absolutely fine okay that's where we can put things like transaction control security there's all thorgan all aspects of our application and we service a request there are many things we think of as orthogonal you know transaction control or availability retry logic all those kind of things and we can put those in our application logic okay two basic implementation variate variations the service layer says basically I have a very thin facade to have a class or a procedure that essentially says I just really directly call entity level objects to do all the work I'm not doing very much at all and there's really no business logic crept into my basically upper layer okay and the operation script approach says actually I have some more responsibilities here okay I'm actually going to basically have some kind of business logic because this business operation is fulfilled by a number of entities which we care about cooperating so actually it's okay there is actually some business logic here and there are two variations on basically the same idea okay classically what we get most of you have probably seen this pattern in the few still to any historic netcode you'll get a class it ends in service is equal to my orders service it has a lot of methods on it and those methods that present operations on orders we cloak them all together and put them in one big class quite often it's static we just said we don't create the instances of it and that pattern has been around in things like dotnet and Java for quite some time okay I'm tend to call it the minute order service all right so maybe such a port was in then when I when I switch do you probably going okay to pause to me it's like I said the cat Erna T okay that's what I can do is I can say well maybe we could rewrite this controller so we're going to use this notion of a service flower I'm just calling a facade here a facade is a name ready for a class that acts essentially as a coarse-grained interface to the more granular classes below it and so that's a typical service layer pattern so now I'm just saying how I'll call my facade and get all of my tasks call my facade and get that one task right and you can see once again the things about post that's starting to pay off because that common notion I had of getting one task is now one bit of code that essentially I can repeat okay and operations like a degree these things look much simpler now in my controller I get a little bit click I look some more clarity about what I'm doing in response to an HTTP request I build this one and show you it still works but I won't do it for every single variation because we're running out of time but I'll do that when I'm talking about it when I go and look at this facade what does he look like well so what it turns out is I've mostly done he's just taken that code that was in the controller I moved it down one layer and provide some kind of abstraction okay and that may seem well that's not very much in but I have removed some duplication repetition right I've now got one guy AC method so that may be a help to me and so every time I basically want to fix problem mr. do with basically getting a single request to getting multiple requests then actually buddy got one placing to fix it or if I wanted to modify my strategy because it was unperformed I got one place to go and fix that but in addition because I've actually taken it out of the controller I've actually improved a number of other things I could do I could test now at this layer right throughout my tests directly against my facade which means even though I'm testing the important logic I've removed the need to instantiate that popped that troublesome controller so my tests are no longer dependent on that framework my tests are now depending on my code and that's always good because it means that essentially my tests are continue to exercise the work that I'm doing that everybody else is this just a little bit of a strange one and we'll come back to that later but we've managed to push this code which to place you push them into the console out as well and that's actually giving us a bit of cleanness and clarity okay so that's kind of a typical first step that people will use when they're building stuff let me just run that through and I can show you it still works I say that I mean it probably just fell on me and would feel like all this time we spent watching a build hasn't really helped us so we're just using docker because it's simple to run up some infrastructure if we come over here again and we find our test HTTP file so case then we get asked the question and what is this so this is basically a plugin for code called restclient which lets you essentially exercise curl statements and get feedback from them so you can see basically I already had a couple of entries in database Allison Mary from last time I can add new entries into the database and I can retrieve them so functionally I'm the same and actually these tests which work against the API continue to function normally even though I've moved things down a liar right so turns out there's an interesting idea in layered architecture called ports and adapters and we referred to that earlier right this is one of the ideas that Bob Malin began to look at when he decided to get to waters idea of clean architecture what a ports adapters architectural style basically this is a variation of the layered architecture which has three key layers it has the application layer which essentially the business logic lives right and you can think of that essentially in the previous as being roughly equivalent to our domain that's where essentially our business logic is gonna live and it's got the adapter layer which represents all the things that essentially are talking something outside the system so all of the i/o is a beauty we're thinking about it right so the adapter layer is basically a layer that says well here is how we talk to the user of our interface right here is where my MVC code lives here is where my windows form with code lives here is where my WPF code lives here is where my console lives okay but in addition to that it also includes which we tend to think of basically as primary adapters right because I talk to a primary actor which is basically a user usually interacting with the system it also actually adaptil there includes my database my third party service that I call to look up postal zip codes or to look up essentially the weather today right so it has what we call secondary adapters or secondary actors which talk to secondary actors which are things outside the system that I need to use depend on for the service off and then this model interestingly enough where especially when we look to previous models let me get back we had this notion of a separation between the domain of the infrastructure here we don't have that anymore we have this one adapter layer and we've got this funny notion which confuses everyone a port and a port is what lives between the adapter and the domain layer right and it's referred to by Arthur Coburn as a purposeful conversation so it's a conversation that occurred between their adapter and the domain so it's more than just simply the interfaces to the limit of the entity types living the application there's something else going on just notion of personal application and he refers to effectively as the API of our application and by that word application he means what's at the core what's at the center ok and the goal here is to utterly decouple or application from any technology concerns so if you look at this diagram which is a classic diagram of a hexagonal architecture what you will see is in the center for to represent with those circles a whole load of entities they're basically our domain classes to represent how we provide the functionality of our application in the outs outer layers they see feeds user side notifications database these essentially is the adapter layer that's how we talk to the outside world so on the user side for example we have an adapter for HTTP for basically providing an API via HTTP we have a GUI adapter so we can provide and the an MVC layer so we can actually see stuff right over here on the photo database side basically we have a database adapter I can they're taught for database I can get information in or out right I've got notifications layer so maybe I want to raise our two vacations via message queue some gunnies am keep eve base to raise messages or I've got WebSockets or I'm sending emails right so this adapter layers how I talk to those external concerns a deficit separate process my message queues a separate process my emails an SMTP server my WebSockets were sexy our HTTP over the wire I've got HTTP I've got going to be CI users browse on the right so the adapters manage the interaction with the outside world and the port is essentially what lives in between the adapter and the application so that's the adapter that's the application and that's support so when Colvin says effectively the port is the purpose or conversation effectively between the outside world and the application he's referring to that application layer there okay one of the interesting properties of this model is that all dependencies are in words okay so the adapter layer is allowed to depend on the port and the poor is got to depend on the app on the application but the application is not allowed to depend upwards so my application can not cool my database directly so if we look at our layering model we can see that essentially the adapter layer has both our infrastructure and our UI and our domain our application layer has basically has our port our application inside in our domain layer so the question might be what hang on a minute if I need to talk to database to get my data effectively in my hydrate my model how do I do that okay from my domain model and the answer is you have to use dependency inversion so within my port if I want to basically talk to it and adapt to some piece of infrastructure or UI so if I'm talking to the database I define an interface and that's basically something like my repository pattern my repository on my Dao pad my ID I oh right or my gateway for a messaging system it's my high messaging gateway and that says at the port level what I want to do is understand and I'm talking to the outside world but I can't depend on anything concrete above me so what I must do essentially is say you have to basically depend on the interface and then as a concrete implementation of the interface provided when I spend the application up what happens in my mane at the beginning of my application which is what's called the composition route the place essentially where I hook everything together then essentially I register an implementation of that interface with a container which I can later then essentially use an ioc container or poor-man's a poor-man's di to essentially inject into the application okay and by doing that I preserve the clean that the cleanliness of my application okay it's not about domains a little bit well just took another run at the same idea some clarity right so back in about 1992 I think I live a jakob sin wrote a book called object-oriented software engineering didn't read it Wow almost nobody I see a few hands but yeah so this used to be like one of the texts photo oh right if you were a pro gamer back in the 90s this was kind of the texts that you read and what this text is most famous for probably is introducing the idea of use cases who's heard of use cases yay okay nowadays gee honest with you you can think of the user story as it's a very lightweight use case and that's essentially would be co-pastor Coburn's definition of a user story this is a lightweight informal use case it does what a use case does but essentially it says it doesn't have a reformer syntax this is a more form wallet presentation I pulled off the internet somewhere of someone doing a use case those circles essentially represent use cases and someone's going to look at what a business processes in a restaurant and said what are the key use cases that we have to do so let's say I wanted to basically you know automate and give the server a handheld so they could essentially do all the interaction with the customer and a handheld these were the kind of use cases I'd start to look at and the use case essentially says what are the steps that I have to complete inside your application in order to provide some kind of useful functionality to the user you can think of it as kind of a scenario if you like right in order to essentially order food the following things will have to happen you know I have to basically send a ticket back to the system that basically has a list of food orders etc and the second thing though that is in that book that yeah Kirsten came up with a thing called boundary controller entity or BCE who said it BCE a couple people right that's actually quite unusual so BC EU is quite a popular model at that period of time and essentially it's a model of how you slice up the software okay so a boundary that symbol is it's your mouth symbol so this is part of the UML standard the boundary is that object basically that interfaces with system actors user interfaces gateways and proxies right so essentially the boundary is an object on the outside of your system and it says the actor which essentially is a human being pressing buttons on your system or something it was system talks to write the interface with that is handled by a boundary object sound a bit familiar here's a diagram from epson's book showing essentially actors right so I've basically got looking at my customer panel someone's got a receipt I've got basically an operator who's looking at an operator pan or alarm devices okay so this boundary object is how I interact with the system and there are entities in your system and the entities of the objects that store system data and they also contain the business rules about that data if we think about IO which is really where this model comes from we really want to have or their databases have kind of killed their model for us implementation hiding okay and so implementation hiding is the idea that we're basically hiding our state so the rules affecting that state you have to live in the entity and then finally controller objects some people have renamed interactors to avoid confusion with things like controllers in the MVC Pan which mediate which with the boundary between the between boundaries and entities so they orchestrate the execution of commands coming from basically the boundary and if the use case is a description of the way the system is being used then a control or interactor is the implementation of that use case so our use cases live in this control or interact tool and this is a typical diagram I have an actor he basically interact to the boundary some sort of UI the UI in turn calls some kind of control objects essentially to do some work which has said to the other use cases and should be named after the use case for something I order food or ever etc which in turn orchestrate the entities there are some rules actors can act the talk to boundaries balance can talk to controllers controllers can talk to controllers controls talk to entities but actors should never talk to controllers directly or to entities directly and boundaries should not talk basically to entities or to other boundaries that only may have to relax I suspect and entities should not tortured entities the idea originally was that essentially a boundary and an entity are noun and nouns can't talk to nouns now it's going to talk to verbs and the controller is a verb all right but we can see this model has some parallels to the models we've been building up so far right we have this idea essentially or a boundary object to control object essentially and they are really are very much close to the adapter in the port and the application model okay and indeed Coburn says a port is the use-case boundary right this is where we define our steps so we can relook at this hexagonal architecture and say ah well that's basically our boundary objects they're our entity objects and in between our control objects so it's problematic thing the port people get concerned about when building these architectures is really just essentially their control objects all right there's a correlation between the use case Brown during the test boundary so what are the advantages of a hexagonal architecture is we can begin to write our tests cleanly against this control boundary because those are the used cases in the system we want to test and so you write your unit tests against that control layer not against the boundary layer and if you need to then essentially you can write some integration test to confirm you've hooked up your boundary layer correctly otherwise you rely on system tests to prove everything works end to end because I just proved when I switched between my different layers then essentially that still works my it's my test still worked even though I began to move stuff down the layering okay so this is Bob's model of the clean architecture and essentially used to ride from all those other earlier architectures right so you can think of the blue layer is basically your boundary or adapter layer the controller green layer is your ports layer where other blue layer effects we saw the outside world the green areas are adapters the blue could be frameworks like MVC for you the green layer is your adapters your controllers the things that plug in to the outer layer usually all your repositories your gateways your messaging system the pinky-orange layer the salmon layer is essentially the use cases that's your ports layer that's where effectively these cases the system are exposed and there you have your entities right this is how kind of well it looks you essentially have a boundary layer which talks to some interactors which talks to the entities okay and you may have a request in a response model which essentially are when the boundary comes in it delivers a request so your HTTP request comes in we take all the things in the header we take all the body when we give it over to the interactor and say deal with this for me it goes and calls the entities and deals with the requests and it generates basically a response model what's the result of that happening the response model then gets pushed out by the adapter and goes back to the user okay if you have an MVC layer then essentially as part of that controller right so your controller is an implementation of the presenter and essentially your response model is a view model that you are the pin putting out onto the view graph and the view is hidden from user at Web API right the view is I just returned my object and it puts as Jason for me my entity gateway is essentially how my interactor talks to the adapter layer so interface we thought we looked at earlier for basically dependency Injection that says i'm going to be basically how you talk to the database and the implementation of it is something like a repository pattern or RDA oh okay so let's be to this bit quite fast what I might do actually just say some code here at the time right so given I start with this facade then what can I do well the first thing I might want to do with my facade is essentially say well when I look at my facade there's a slight problem with it and the problem is that the facade has too many concerns together okay and so because it has all those same concerns in my one facade it's too many forces of change so I could break my facade up and have a whole set of facades instead an hour greeting service that just handles the proportion of the words is that a de greeting a greeting is all service that gets me all the greetings back a greeting is by our ID service that gets me all those individual greetings right so take that big service model and I break it up I say actually that's too much I don't want to do that because all the forces I don't have suffered two interfaces for different customers and some clients and it's hard to reuse I have to reuse the whole facade even if I only want one operation but it turns out that model is really just commands so the command pattern essentially says I want to encapsulate the idea of calling the domain part of in some kind of transactional boundary and there's a strong alignment then between this idea of a command model and a use case so I can turn those individual Fusaro items into commands so I'm just implementing an interface on command which is basically a standard interface essentially we're idea whoops I'm not gonna navigate to that there anyone it's somewhere around I will find a bit later so we're saying I can execute right and here I'm basically just doing the add or I'm gonna delete something okay when I get to my controller now I've got this nice idea of a command I'm going to add a greeting right that's some kind of use case that I'm implementing here right it add my greeting and my queries are similarly really just a variation of the same idea I'm gonna encapsulate the idea of queer doing this query for you where's my query and so there I'm just going to execute that same code I had at the beginning as a query object and these are my interactors these are my ports right representation of my use cases in the system so what I'm doing here for example as I'm saying when I get in the request model create an interactive the a greeting command pass in the data from that request model execute it in other words exercise the underlying entities my greeting model and then essentially I'm gonna raise in the vent out as well we'll come back to that bit later and then essentially call a query object to build my response model right so my so I'm basically using interactors which are present use cases to handle the request and response model by exercising the entities and the volunteers are basically using some kind of command model is what I can actually do is use a framework and this is using brighter but mediator etc have similar ideas and I can say I'm going to separate creating the command from executing it why might I do that or if we go and look at add command handler rather the kamati the receiver for that a greeting command okay we can see I have some attributes on there and those attributes are handling orthogonal items such as retry logic try and talk to database it fail just retry maybe it's a temporary error maybe it's a deadlock you are trying to basically it felt a lot that way seems to be down break the circuit don't make calls on here anymore give the user a too many requests and get them to slow down okay I want to log this so that port layer that interactive layer is also a very useful layer for us to intercept and provide not just basically workflow logic but control logic for our application and we can insert that into the pipeline without really having to have any awareness of it when we look at the application logic is cleanly separated so I can read my application logic I can understand what's going on but I'm able to add that on top and my controller looks fairly clean right I'm quoting my interactor the algorithm command said she well I've got two parameters my interactor I'm exercising my interacting indirectly through this dispatcher so that I can essentially have a pipeline of operations that it calls until I get to the entity model right so both letters for immediately does this for you they're all basically variations the same thing okay so let's go through these reasonably fast so what I was doing there since she was saying well I had some service facade I was woried essentially that that I had a problem with effectively too many concerns grouped together so I broke it up into series of separate interfaces of my service certain intuitive parts I then essentially said well effectively they can all be individual services individually interact as rather than one big interactive that's everything I said well okay those individual interactors that are broken up with just a command pan and the command pan is very useful to me because the command pan semantically is a transaction it a use case and therefore it Maps really nicely to this idea within the clean architecture of an interactive this controller from the BCE model of the port from a hexagonal architecture model okay and it simply separates the caller from the entity model that's its job is to separate basically the caller from the entity model it's exactly what a controller does it separates the boundary from the entity model okay standard Facebook commands and so I can see essentially my interactive model is effectively my command interface query objects which are essentially just affecting this idea of assembler that goes away look operates over my domain and produces basically some kind of data transfer object a view model so I can create those as well the idea basically of saying but to build my response model what I want to do is have some kind of object it's an interactive that reads my domain generates basically an output response and of course I don't get to detail in this slide but that leads to the idea of CQRS this separation between the query side objects and the command side objects okay this talk is not about CTRs so that's the details slide I understand that but the goal is reached to hint to you little to go down that route and then we also took a command dispatcher which is this an idea or effectively that I can separate the parameters of the command from the execution body so that I can insert operations between essentially the point I call in the boundary and the point effectively they're each the entity so essentially I can chain controllers together to separate the responsibilities of those controllers so that some of my controllers do logging some of my controllers do retry logic some of my controllers do transactional control some of them do authorization control and when the ones at the end just do workflow so I can separate all those responsibilities so that the only change because I'm changing that type of thing I'm gonna change ID logging I want to replace the login framework I'm using I'm gonna change how I do retry logic I'm gonna I'm gonna only knock the use poly I'm gonna implant something myself that's the time I just showed you all right so I think we are about on time so I got time for any questions a lot to take in the book to go and read is Bob Martin's book she showed you the beginning clean architecture and also his blog post you should you can go under the hexagonal architecture online there's a good discussion basically you're Alistair Coburn site hexagonal architectures and BCE is hard to define information about nowadays because it's a kind of that use case that everything else is older but there are various sources on the web talking about how BCE works and there's some blog posts relating to Bob minds clean architecture where people actually talk a little bit about how BC model used to work people fix it up from but it's a very the BC model is really mainly useful because people like Coburn at the time he was writing here taking our attention you all about BCE and the it's kind of implied you understand use cases in BCE you wouldn't talk about that now supports become very confusing all right if you have questions because we're out of time I said you come down the front and I'll take them in the break police remember to tradition of putting green tickets in the box it's a local tradition which you should all honor as you leave and thanks very much [Applause]
Info
Channel: NDC Conferences
Views: 50,675
Rating: undefined out of 5
Keywords: NDC, NDC Oslo, 2018, Ian Cooper, Architecture, .NET Core, .NET, Hexagonal Architecture, Onion Architecture, Screaming Architecture, Clean Architecture, TDD, OSS Libraries
Id: IAcxetnsiCQ
Channel Id: undefined
Length: 61min 34sec (3694 seconds)
Published: Tue Jul 31 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.