Vertical Slice Architecture, not Layers!

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
nobody wants to introduce a system that's hard to change or easy to introduce bugs because it's a spaghetti code mess of various technical concerns things like clean architecture are popular because these separate these concerns into layers but why are we organizing our code by layers you can feel the effects of this organization when you need to make what seemingly should be a trivial change requires you to open many different files across potentially many different projects so what's the solution to this vertical slice architecture I'm going to explain what it is and how you'll think differently and then organize your code differently hey everybody it's Derek Martin from codopinion.com if you're new to my channel I post videos on software architecture and design so if you're into those topics make sure to subscribe this video is brought to you by event store DB the stream database built from the ground up for event sourcing cqrs and event driven microservices for more on events.db check out the link in the description so first I want to give some context about the ideas that I'm bringing forward here and where I find the replicable because then you can better relate to your own system so you can think about where it actually can apply so the first thing is I'm talking about large systems here systems that need to be decomposed into smaller pieces because they have different responsibilities and that a lot of it is what I'm talking about here so I'm not talking about kind of small little apps potentially that may take you weeks or a month to build that you could if you had to rewrite it would take that length of time no I'm talking about large systems that could take a team of developers years to potentially build that are going to be used hopefully for many many years so with that when we talk about different concerns different technical concerns and kind of getting into that spaghetti code mess there's all kinds of concerns that we always have is things like authorization data access which is always usually a big culprit mixing that with validation and with validation I'm not talking about business logic I'm actually talking about kind of That's What I Call superficial kind of logic things like string lengths or is something a valid email address kind of that trivial stuff that really isn't at the heart of what we're doing really it's that business logic that complex domain logic that we have that Tangled with that validation some data access authorization logging all these different things we know that if we mix all these various concerns we're going to end up in what I call a turd pile this is the system that's really large that's really hard to change people generally fear making changes because you don't know potentially what you're going to break or when you're looking at a set of a piece of code it's has so many of these responsibilities that's kind of hard to understand or decipher what it's actually doing now if anybody's worked in a large system a legacy system or even if you built a new system unfortunately this way you know over time how it can become a turtle pile and how it can become ultimately really hard to change easy to introduce bugs hard to test we've been there we've done that so what's the alternative well one example is clean architecture but this could be onion architecture hexagonal ports and adapters layered architecture but the general idea here I'm using this image because it's probably the well most well-known and the key thing to focus on here are these arrows going towards the middle but on that outer ring on the outside that's kind of where our i o is so we have things like our database maybe our web framework if we're creating a web app or an HTTP API or we have a UI or Etc that's kind of that outer ring inwards from that is we have things like controllers presenters gateways there's really just interfaces to how we want to interact potentially with those things on the outside then a ring in from that we have things like use cases which are really are our features is what's the capabilities that we actually provide in our system and at the very core there we have our energies which are actually is our domain logic and where our business rules really lie now the thing with clean architecture or layers a layered architecture all these types of things the real key to them isn't necessarily that you have to abide by these particular layers they can really be whatever you see fit within your application it could be these particular four it could be five it could be two again it's not set in stone that this is it what really is the idea the concept behind this is as I mentioned is those arrows pointing inward because this is our direction of dependencies that outer layer depends going Inward and then you can see at the inside it doesn't have any dependencies so the key part about this with any types of these types of systems is controlling the direction of dependencies so here's an example of the clean architecture template in.net that you can find on GitHub it is likely I'd assume the most popular and it's kind of going around this structure it has four projects it has application domain infrastructure and web UI so what I want to do is I want to illustrate in in that particular project how each project references each other so the first thing is that the web UI is referencing the infrastructure project then the infrastructure project is referencing the application project and then the application is referencing the domain but it's not to say that web UI can't reference something else it actually does it actually references the application project that's fine so as long as they're always going from top to bottom or in that other graphic kind of inwards but again where we have nothing in the other direction all our dependencies are going to go in One Singular Direction now the reason why I think this is popular with net projects is to set them out as projects is because it forces you to make these references from Project to project and in forces that you can't have a circular dependency but the reality of it is it has nothing to do with actual projects it has everything to do with coupling which I'm going to talk about we could take all these projects smash them into one project and we would be left with the exact same result it's not about project dependencies it's more about type on type dependencies and that's probably the biggest misconception or the idea that you need to use these physical layers as.net projects to actually create the separation you don't it's really about one thing that direction of dependencies coupling so what is coupling well coupling is the interdependence between software modules projects types classes insert your a other name there that you wanted to find but it's that interdependence between these things so there's different ways that we can actually think of coupling I'm going to talk about specifically about two of them and why they matter if we look at kind of the big ball of mud here diagram you can think of any one of these little circular things as maybe a class as a type and we can see how there's just a Rat's Nest it's like everything can reference everything and there really is a high degree of coupling this is what leads us to that big ball of mud to that turd pile is just managing that we're not managing coupling and that it's just a free-for-all of types referencing types so that's kind of the benefit of something like lean architecture or a layered architecture Etc is well establishing this direction of dependencies so there's two forms of coupling that I want to talk about there are many other forms of coupling but it's specifically for this I want to talk about two the first is Afrin coupling the way I like to think about this or the way I describe it is who depends on you so who depends on you if you're thinking about in the context of the web UI who depends on the web UI nobody who depends on infrastructure the web UI because the web UI is the one referencing it so who defends on the application well it's the web UI in the infrastructure and then who depends on the domain it's the application so that's important to understand because who depends on you also has a flip side to this it is efferent coupling which is kind of the reverse now which is who do you depend on so again in the same context of thinking about the web UI project is who do you depend on well the web UI project references and depends on the infrastructure and application infrastructure depends on the application and the application depends on the domain the key part about this is that the dopamine depends on who nobody it has no Effron coupling and this is really important because both of these ideas have afferent effort coupling mean one thing stability and this is actually what we care about and why the domain is at the very bottom of that list or at the center because it doesn't depend on anything so when we're talking about stability that means that if there's a change to anything above domain it doesn't matter it doesn't affect the domain this means that we could have swapped out web UI let's say it was using asp.core MVC and now we're using minimal apis and endpoint routing we could do that and it affects nothing we're not having to change anything within our domain we want stability there now as we go outwards the exact opposite is true is that if we may change to the application or infrastructure or domain that may affect height things higher up so that may affect the the web UI so it's less stable to the changes that we're making so this direction of dependencies while incredibly important why are we doing this it's for stability and understanding that that complex business logic that we have that we're writing we don't want it affected by anything else now I'm all for the idea of sample code templates you need to be able to illustrate these things I'm 100 guilty of what I'm about to say which is when you're creating sample code or templates for people you're often illustrating concept or ideas but you're simplifying everything around it even though it might not necessarily necessarily justify the use case of a pattern or a concept and the problem with this with any types of samples is looking at them or templates looking at them as they're a prescription and you should follow it 100 that's not really the case just as explaining what the clean architecture template is it's dividing them into projects but you don't need to if you understand the idea be between coupling these Direction and dependencies it's one way of achieving it but it doesn't need to be the only way so when I look at that template these are two of the projects there's infrastructure and web UI that I've kind of highlighted here that have expanded and let's just look at some of the folders involved here so infrastructure has a common folder okay no idea what that is it has a folder called files no I I mean we're writing files we're creating c-sharp files so I don't know what would be in there per se identity I could guess that has something to do with auth persistence likely something to do with our database and I know in this it's using Entity framework and of course the magical Services folder because anything that we don't need we don't know what to call is just immediately a class that's a service the web UI we have Client app which I'm assuming is kind of a JavaScript front-end we have controllers we know what those are because we're doing NBC we have filters because we're doing NBC we have Pages which I believe are razor pages and of course every project needs that Services folder because everything is a service So based looking at this what does this sample do well it does some technical stuff clearly but we don't really know what this actually does so at the very beginning I think this is actually a very common response that I get in comments on YouTube I've heard this many different times and this is a comment left saying I'm new to a code base and it's just really hard in order to understand one piece of functionality that I need to have 10 different files open at the same time and jump back and forth to understand what's actually being done so we have a lot of different files a lot of indirection obviously and it's very difficult seemingly for something that could probably be pretty simple but this is kind of a common thing that I hear all the time so let me jump through this to do app that's this clean architecture again it's illustrating clean architecture using a very simple sample but if you're following this kind of as a prescription this is where you'd land if you are looking at say changing something with the to do item creating a to-do item so we have the controller and this exists in the web UI project you have the create to do item command which lives in the application folder and this is using mediator we have a create to create to do item command validator this is kind of that superficial validation that I was talking about that lives in the application project we have an i application DB context that interface also lives in the application project the implementation for that which is the application DB context lives in infrastructure so this is implementing EF core or DB context there now we have the to do item which really is just a data model but it's in the domain project again let's try and just illustrate using something like simple like to do and then we also have this to do item created event which also lives in the domain so I have several different files let's say about seven of them and I'm not including any UI like the JavaScript or the Razer page or razor view whatever else was happening but you can see if you had to make a property change you're adding something to the to do item all the various places you'd be going just to make what could be a relatively trivial change especially for something that's crud so the question is why do we organize code by technical concern why do we have these files scattered across these projects that are using this for dependency management so for that direction of dependencies when now you as I mentioned it doesn't need to be by project that's just a way to facilitate that physical separation which is fine but why do we organize code by technical concern there's kind of two parts to this equation the first is because we're solely thinking about coupling we're talking about effort and effort coupling that's what we're concerned about that's why when a segregate their domain we're talking about stability but we're talking about coupling we're not talking at all about cohesion which we should be cohesion and kind of coupling to me are the yin yang a software design they're both go hand in hand if you're thinking about coupling you have to be thinking about cohesion the reason is is they kind of push and pull against each other you want to land with loose or low coupling and you want to end up with high cohesion but that's easier said than done the kind of push and pull against each other when you try to get to low coupling you end up usually sliding down the scale of low cohesion and if you want High cohesion you usually end up with a higher degree of coupling so it's kind of playing off these two for you to try to find the balance within your system so why are we not talking about cohesion so what is cohesion well cohesion is the degree in which the elements inside of module project class Etc belong um together and this is a really important aspect that's left out everything and why I mentioned earlier why in a large system this this matters so there's two ways to think about cohesion there's grouping them related to data and kind of being more data Centric which I think is probably the way most people think of cohesion inherently I'll get to that in a second the second is more relating to behaviors tasks and capabilities that are more related together related to each other so these are the two ways informational and functional cohesion like I said I think informational is probably the most popular but either way what we're talking about is if we think of that cake as our entire system it's one big system what we're saying with cohesion is no no no it's not all one big thing really what you need to be doing is taking slices of cake out that are grouped in some way cohesively either by data or functionally by different behaviors that's not to say that you're ignoring coupling not at all coupling is a separate con idea that we're thinking of so just like this piece of cake has different layers in it that may be dealing with coupling it's dealing it with the confines of that piece of cake that piece of cake is also important or all these different pieces of cake because they're not all created equally if you have a large system each different kind of logical boundary piece of cake is going to have different value to your system there's a core part to what you're doing but there's also many different parts of your system that have just less value they're kind of more in a supporting role so for not only thinking about coupling and we are thinking about cohesion this can drastically change the way we think about our system and how we organize the code around that so as an example this is still the clean architecture sample application and this is kind of out of the box still is if we look at that application folder it's kind of getting there a little bit we have common again who knows what that is but to do items okay well now we have commands we have event handlers we have queries we can see that now like okay it's starting to resemble something but it's still not quite there I say that is because we're still organizing things by commands queries event handlers and ultimately these things do relate to each other get to do items with pagination also goes hand in hand with creating a to-do item they're both related to doing something with to-do items oftentimes you may have a query that's directly related to a command so we're not exactly there we're still organizing by technical concern because we're thinking of commands being one thing which they are it's changing State and queries returning state but they actually have a lot more related than thinking about them in that separation so rather if we're thinking about actual behaviors of what we care about we have something like now to do items it has its list of different things that it can do different capabilities again this is a sample app so it's pretty crud but if we look at to-do lists we have creating a to-do list deleting it exporting it getting the to-do's updating a to-do list and then we have below that we have infrastructure models where did those come from well I actually deleted those projects and physically moved those files there we still have the exact same degree of coupling even though I removed those projects nothing's changed I haven't changed any code at all at this point I'm just moving files around so I have the application project which you could call that something different web UI which is still kind of that asp.net core top I O Level layer but when I start moving things around a little bit more they start looking like this is that same create to-do item the list of files involved now are potentially three because I've moved everything into a single file so we have something like that controller instead of that controller having a bunch of different actions for different routes rather have a controller that has one method in it for this particular route so I've just extracted that here I have that command which is the create a to-do item command I have the valid validator for it right alongside I have the command Handler here and I have the created uh item event or to do item created event so all of them I've put within the exact same file these aren't spread across different files across different projects they are all here if you do notice this as well is that this actually is kind of top down in terms of how it actually executes the controller is calling the command the command gets invoked to the validator which then goes to the command Handler and then it also creates that event yes that event will be consumed potentially different places but this is the owner of it because this is where it's actually published so everything is put within a single file if you hate the verbosity of all these um prefixes of the create to do item a simple alternative to this is just create a static class with the name and then Nest all these classes below it so for example when you actually do need to create the create to do item outside of this kind of scope you'd literally be typing create to do item dot command to new that up but again I understand some people having more than one type in a file is blasphemy I'm not that way but if you are at least put all these files within the same folder so they're all next to each other but personally I prefer them all within the exact same file so the next part of this when I was mentioning cohesion is there's kind of different ways of thinking of this and I think primarily we're usually thinking about data which I think is secondary to actual behaviors and capabilities and thinking about kind of workflow so this was a post on Reddit many years ago now but I still think it's very relevant and it could be posted yesterday and I think it would still be accurate of way kind of the industry is thinking which is I have a simple data model as below I'm creating microservices for these tables what's the best approach to create microservices do I need to create one microservice per table the answer is no absolutely not one it doesn't even probably need microservices depending on your contacts and we care about physical boundaries that's the thing but before we even get to physical boundaries a physically Deployable units we need to be thinking about what is this what does the system actually do I just see data here I have no idea what this thing actually does it's clearly something to do with keeping track of rentals of maybe movies thinking kind of old school Blockbuster style I'm not really sure exactly what this does other than it has rentals films payments staff actors customers okay there's a bunch of data but what is it actually do so when we're talking about a large system not everything is what you think it is and not everybody thinks about things the exact same way so what I'm going to be illustrating here is the idea of a distribution domain where you are basically buying product from a vendor or from a manufacturer they're shipping to that to you you receive that within your Warehouse you store that within your warehouse and then you go ahead and then sell those same products to customers those could be consumers or businesses and B2B but either way you're basically buying receiving into your warehouse and then selling and shipping that product out so when I say that I have to talk about a product and what is a product because a product isn't a product meaning that it has kind of a different idea behind it and what people think about it within your system there isn't in a warehousing system like this distribution there isn't just one idea of a product there's not just one entity service that we have that is responsible for a product now I'm simplifying this a lot but this will illustrate the idea there would be a lot more data points on a product if you had a singular concept of a product but this will get the gist across so this tweet was from melcon way a couple years few years now which I think is dead on the money which is when a politician greets you with how are you and a nurse greets you with how are you they are totally different questions even though they sound and are spelled the same and this is because context matters when I'm talking about a product that means many different things to many different people using a system in distribution if I'm talking to somebody in sales they care about the price if we're talking about the product price that's what they're selling it to our customers they're defining price structures Etc and they care about whether we have that available that we're selling it still if I'm talking to somebody in purchasing that's buying our product from vendors I may say product price but that means something completely different to them they're actually thinking about the cost they're talking about the vendor price well we actually have to buy the product from our vendor so if you say product price well that's two different things to two different people really what they're referring to we may think of it as our actual costs and whether we can still buy from our vendors Etc if we're talking to the warehousing manager or somebody in shipping or receiving the price costs whatever they're thinking about the location of that product within the warehouse they care about what the quantity on hand is or the quantity on hand that we think we have now you may think that sales cares about the quantity on hand but they do not and I'll get to that in a second because that's a little misleading if you're thinking about marketing or the catalog the for our website for these products it's the name the description the images etc those are the types of things that they care about this means that there's not a singular idea of a product in a large system likely of this same thing goes in any type of large domain with many different subdomains is that how the language works is indicative of kind of the behaviors and things that we care about it's not just the data what people in these subdomains actually think about are the tasks business processes and these various workflows that they need to perform as an example the catalog I was mentioning that not everything is created with the same value maybe the catalog that's really not the core of what we're doing it's really just kind of a catalog of products so what the behaviors are well it's just crud create read update delete maybe it's very minimalistic we just allow you to kind of update product info set the name the description the images it's pretty simplistic in our sales however we have different things that we can actually do it's not just changing the price like what are we doing with the price are we providing some type of discount some type of sale that we're doing for a limited period of time are we on back order are we marking as unavailable or now is available because we want to sell it there's different things in sales that we actually care about behaviors all those capabilities that we have have data ownership behind them but we're first thing about what are the things that we actually provide the functionality in our system in purchasing they care about vendors they care about the vendor ID associating vendors to it maybe there's many different vendors that we can purchase product from maybe the item now is discontinued and we can't even do we can't even purchase it anymore purchasing has a creating receipts um there's different things that purchasing cares about same thing goes with the warehouse they care about shipping and receiving product they do things like inventory adjustments which is like a stock count where they physically go on the shelf and count the physical numbers a product on a Shelf and why I mentioned this is because sales doesn't care about the quantity on hand they care about something called available to promise and available to promise ATP is a business function and it's a combination of different values like what the quantity on hand is that we think we have what have we purchased that we haven't received yet it's a way to provide information to sales on what they could potentially sell given a period far out potentially in the future if we know products coming in that we've already purchased we just haven't received it yet the reason why this is a business function and why we don't use quantity on hand when we're talking about physical Goods in the warehouse the warehouse is the point of Truth for a particular product what's quantity on hand says in our warehousing part of the system isn't reality product is damaged project product could be stolen that's why we're doing stock counts those particular actions those behaviors so we can do inventory Tory Justin so we can adjust the inventory to say actually no you need to reduce two of these quantities because they're broken so the singular idea of a product actually doesn't exist it's really the idea of a product exists within many different parts of our domain so when we're thinking about cohesion what we're doing with these layers is we're deciding to slice out these pieces of cake we're doing these slicings based off the functionality around them grouping by functionality we have Warehouse concerns we have sales concerns purchasing concerns and our catalog concerns potentially these are all related to it sales and selling something has nothing to do with an inventory adjustment they're completely unrelated to each other even though they're thinking about the same thing a product so that means that splitting it up our system into these logical boundaries basically the idea is having functional cohesion this means that once you have defined boundaries you can decide per boundary what actual use case in terms of coupling does it care about if I was talking about the catalog boundary let's say that was the first one there maybe there isn't any actual domain model that we have there it's really just interacting with a pure data model we don't have any domain logic it's just pre straight create read update delete crud that's it but it goes further than this where we can decide maybe one particular boundary doesn't its i o really is about messaging and and being consuming messages off a queue or topics maybe we have some boundary that is even more crud we don't care about separating out in any meaningful way it just interacts with the database directly maybe that middle HP API with infrastructure app domain we still have these layered concerns for direction of dependencies there because we require it there's a lot of complexity in our domain that we don't want to affect with various other concerns when you've defined boundaries If This Then allows you to decide what you want to do where so when you start thinking about features well what are features features are groups of things that you can do look when we're talking about our simple in our warehouse doing an inventory adjustment that's a feature just returning the actual doing a query of returning what the quantity on hand is or showing something about our where our location of particular products is a feature just because features are segregated into their logical boundaries doesn't mean that they don't share anything I think this is the biggest misconception about vertical slices is thinking that they're share nothing it's not that way a bunch of features can share the underlying domain model that they may have if we have complexity and we need a domain model there maybe we have different we use a repository pattern for commands where we can return an aggregate route which is a consistency boundary maybe in another domain another particular sub domain it's logical boundary it's just using a data model because it's just crud this allows you per logical boundary to find how those features work the simplest way to think about a feature at its kind of most granular level is to be thinking about cqrs a command or a query is a request can be an individual feature or a combination of them could kind of make a feature set it's not about multiple databases it's just a separation kind of these two paths between are you performing some type of right some type of State change it's a command if you're just returning State it's a query that's it that means that we can Define these things about what an actual commander query is as an individual feature and this is important because we can then Define per individual Commander query how we want that coupling to work so this means that we're still thinking about coupling we're still thinking about the various technical concerns that we have not intermingling them you can still be using layers and there's different ways to accomplish this but the key part being now like I mentioned is you're defining this direction dependencies coupling Etc potentially per an individual request one way of thinking about this or an example of how to kind of think about it a little bit is if you're familiar with asp.net core middleware this is in your startup or your minimal API I guess it could be simpler than this in your program CS is you're defining ultimately the middleware specifically in order of how a requests an HTTP request is going to go through each individual middleware each individual middle layer can manage that response do something to the response they can pass it off to the next piece of middleware or it could end that request there then return all the way up the difference here is that you're defining this request pipeline for every request in the system is going to do this however in different libraries and net there's ways to do this where you can have a specific Commander query so you are receiving your request from HTTP say like as an example most people are familiar with mediator if you're creating a command at that point you can have that command go through more than just one Handler so what that looks like is you build your request let's say you have a part of that pipeline request for that command let's say it's doing an inventory adjustment go some through some type of authorization then it could go be passed off to some validation then we could be doing some data access here and because it's a command at this point maybe we're utilizing a repository we're getting out an aggregate root which is a consistency boundary and then we're passing that aggregate route off to our Handler that's invoking something within that aggregate route and then everything just goes all the way back up the call stack to wherever data was saving it all the way back out to our web response saying okay 204 or 200 or whatever the case may be that we want to return back to our client but you can Define what these pipelines are for an individual command or query you could be sharing the same authorization with a couple different commands or queries which represents the same similar feature set maybe related to doing stock counts or inventory adjustments or something related to a product so when you're thinking about this it means that you still kind of think of that direction of what you want to execute so you got web authorization validation execution all these different things it could be a different set of pipeline than this doesn't really matter it's a kind of the same direction of dependencies is that there's no set in stone of what these layers are or what these uh parts of your pipeline are that means that maybe you have a new feature that you're creating that's using minimal apis and it has some role based off that it goes through some custom validation and then maybe it's using Martin maybe it's event sourcing with postgres maybe you have an existing feature even within that same logical boundary that was developed years ago maybe when asp.net core just started there weren't minimal apis yet and you were using MVC that can still coexist maybe you did things differently there where maybe it's a different model and you're doing fluent validation maybe you have Entity framework with some data model there's really not anything Aggregates or anything here but it's still using that same postgres database with different data or a different schema this allows you to Define per feature how you want to be doing things again they can be sharing that underlying model they could be sharing the exact same validation logic that's not to say they can't share it just allows you to find the specific scope about an individual of a request so lastly why I mentioned things aren't created equal and why you can do this is an example from the eShop on web sample application and this is the get my orders Handler for this particular query now at the very top here there is a specification being created and then that specification is being used in an order repository to get out your list of orders if I look at the specification what it does is it's doing the filtering for the buyer ID great because we don't want to be accidentally showing people the wrong orders and then we're including eager loading our order items so if I jump back now we can see that we are taking all these orders we're building up an order view model and kind of creating some little projection of that and then this is ultimately used in a view now the thing is is that this or uh so the specification that's being used is used in one place right here this is the only place that it's being used second to that is that this order view model is kind of repurposed for this particular query as well as when we're looking at an individual order kind of like an order detail page so the thing is where you look where this actual view is get my orders it's just a listing of orders it doesn't use the items at all there's no use of the items here at all so the equivalent to be to this would be back in the day if you're used to writing manual SQL this would be the equivalent of writing a select star you're just selecting everything even though you don't need it you're just over fetching data now the reason this is happening again it's a sample application but if you did everything the same way and you force the use of repositories everywhere or Force the use of a specification everywhere you could potentially be going down this road of just doing it kind of as a prescription when this place doesn't this spot actually doesn't serve this value at all I've done videos this on the past is that repositories for me are about returning Aggregates Aggregates are consistency boundaries if you have queries they likely have very different intents they do not usually need all that data usually need a subsetter data and it's transforming in a particular way so the difference here is this really could be this we don't have that specification we are injecting it could be that DB context directly you could be using the interface if you are so inclined we're creating an order summary view model which is specifically for the view that we need to create and we're just selecting the data that we need again buy requests now we can specifically Define what we want to do specifications maybe are used for when we're using that repository and when we're returning Aggregates queries we may choose to execute differently and be a little bit more pragmatic about the data that we're being or getting rather than being just using the same consistent patterns everywhere so what are the takeaways to be thinking about cohesion alongside coupling I prefer to be thinking about it first and I say that defining logical boundaries kind of defining what that cohesion is is probably the most difficult thing to do but it's also one of the most important things to do why I think about it before coupling is because I need to know what we're actually coupling with I don't not everything's created with the same value I don't need to be creating domain models and using repositories in areas of crud that can be just really simplistic and doesn't have really those mixture of concerns defining what those features are within a logical boundary it's not just updating a product within the warehouse you're doing your behaviors there's capabilities that you that you want to be providing to your end users end users these people within the domain they talk this way it's not that you're updating the quantity why are you updating quantity no rather is there some type of action there's do the individ inventory adjustment or a stock count the shipped product they receive product there's different things that they're actually doing not everything is just crud it's not that we're ignoring coupling not at all it's still very relevant and Incredibly important but now coupling is focused on one within a logical boundary and then two within the feature slices within that logical boundary so it's not that you're disregarding coupling at all we really still care about this it's just that we're thinking about it and we're minimizing the degree of coupling because it's kind of forced within that feature slice or a logical boundary organize code by feature not by layers merging all this code that I did together earlier that did not change anything related to coupling it did not change anything with the direction of dependencies at all everything was still the same if I were to run um kind of an analysis on it everything is exactly the same in terms of what was coupled to what separating in a project forces the issue because you have this physical constraint but it doesn't magically make it any different if it's all within the same file or project what this allows you to do is decide what your dependencies are coupling by an individual feature should you choose to go that granular some kind of trade-offs and things I want to mention is that this requires a little bit of pragmatism over consistency my example when I was using that specification and the repository for that query that's consistency it's we just do this everywhere we follow the exact same patterns that's how we do things that may not be ideal that may not be very pragmatic I understand that situation in context isn't involving and everybody is different so that's kind of up to you I'd rather be a little bit more pragmatic one of the biggest benefits is the infrequent very very infrequent merge conflicts that you'll have if I was changing something to do with inventory adjustments it's not very likely that you are within the same part of the system especially if that's 80 of it with this within the same file now you may also be wondering well can't these files get enormous no generally not if you're breaking them down into small units especially with a request pipeline they really aren't that big Dev experience trying to find where you need to make a change isn't a matter of control clicking or going to definition from this type to this type to this type and looking at all the indirection and trying to jump back and forth as that comment suggested oftentimes it's a really looking top down to a file to see the order of execution especially if you have kind of that web framework and then you have a request pipeline for an individual Commander query I think this is the true with everything is it kind of requires continuous evaluation constant evaluation about the patterns you're applying and whether it's actually applicable what your boundaries are what your models look like are things to find kind of in the realm in the wrong boundary and things should be moved it kind of requires constant attention because don't assume that the initial idea of what you think it should be is really what it will be when you get different insights it may kind of change your mind about how things are defined in terms of logical boundaries hopefully this video provides some insight but what vertical slice architecture is and the idea of pushing at the Forefront thinking about cohesion not just thinking about coupling and it's not about ignoring coupling it just gives you options about how you deal with coupling within a logical boundary and within individual features that could be a single command or query if you enjoy these topics and it's a big topic if you want to talk to other developers about these in a private Discord server you can join my channel Channel get access to that private Discord server the links in the description on how to join if you found this video helpful please give it a thumbs up if you have any thoughts or questions make sure to leave a comment and please subscribe for more videos on software architecture and design thanks
Info
Channel: CodeOpinion
Views: 104,151
Rating: undefined out of 5
Keywords: Vertical Slice Architecture, software architecture, software design, cqrs, event sourcing, design patterns, software architect, programming, .net, soa, microservices, kafka, event driven architecture, messaging patterns, service oriented architecture, microservice architecture, domain-driven design, enterprise service bus, vertical slice archetecture, onion architecture, layered architecture, clean architecture, ports and adapters
Id: L2Wnq0ChAIA
Channel Id: undefined
Length: 46min 24sec (2784 seconds)
Published: Thu Jan 19 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.