Vertical Slice Architecture - Jimmy Bogard

  Рет қаралды 101,764

NDC Conferences

NDC Conferences

Күн бұрын

Пікірлер: 143
@afouadr
@afouadr 5 жыл бұрын
IMO and 18 years of experience developing software the n-tier way I came to the same conclusion of moving away from traditional n-tier architecture. This the best and most productive way of developing software (i.e Vertical Slice Architecture, thanks for the name jimmy). Any negative comments are just implementation/cultural/personal trade offs we all need to make. Excellent presentation.
@Kinisson2
@Kinisson2 4 жыл бұрын
Exactly.. When I was a student, this was totally making more sense than "Handlers, controllers, Views, Models, Services, ....etc" modeling. But as a freshman of the trade, I was told that the layered architecture was the "right way" to do it. Which sucks because when you are so susceptible to manipulation you question yourself and one day you caught yourself to become the prominent supporter of the onions :(
@sk8leesk8
@sk8leesk8 4 жыл бұрын
20 plus years of developing the n-tier way. I've been been searching for another way. This is perfect!
@Feronom
@Feronom 3 жыл бұрын
how big are the slices? Are slices one use case or what?
@mattmarkus4868
@mattmarkus4868 2 жыл бұрын
@@Kinisson2 don't worry, in 3 years you'll be told of a new "best way" and the way described here will be considered old and a bad practice.
@mattmarkus4868
@mattmarkus4868 2 жыл бұрын
@@Feronom ​a slice would be a class that represents an operation that takes a request, has a handler, and returns a result. Could be something like GetCustomer, UpdateCustomer, DeleteCustomer, ListCustomer, etc. And those classes would go in a Customer folder. Something like YourSolution\ApplicationProject\Features\Customer\TheOperation class. Re- how big? I guess it depends on how big the operation is and the data structures it defines.
@edino1981
@edino1981 5 жыл бұрын
I remember when I've first started to learn programming, there was a diagram in the book "Input -> Processing -> Output", and from time to time people rediscover this and give a new name :D
@juanchavezlive
@juanchavezlive 4 жыл бұрын
You should continue learning programming. Facts shows you have not learned enought
@edino1981
@edino1981 4 жыл бұрын
@@juanchavezlive There is always something to learn, for example right now i am trying to learn spring framework and i see that framework authors have not learned much either or Java is just a bad OOP language so they could not make it any better
@gajbooks
@gajbooks 4 жыл бұрын
It's almost as if people have to take good, structured languages and concepts, run them into the ground with their incompetence, only to re-invent them under a new name with exactly the same feature set as what they started with. Take this process for example. In the video he states that his model almost exactly maps to REST APIs, which is what ASP.NET was literally designed for, because it uses well defined HTTP operations... People tend to over-abstract layers and layers of garbage onto software.
@steveroger4570
@steveroger4570 3 жыл бұрын
x -> f(x) -> y
@dupersuper1000
@dupersuper1000 4 жыл бұрын
This entire talk is basically a crash course in functional programming architecture concepts. If this talk were to be given at Lambda Conf, the entire crowd would be nodding in agreement, although they might be horrified by the idea of using Entity Framework Core, or OOP in general.
@nick2193
@nick2193 4 жыл бұрын
Can you give some links to stuff like this in FP?
@nikcimaskevic6415
@nikcimaskevic6415 Жыл бұрын
Domain Modeling Made Functional by Scott Wlaschin@@nick2193
@Bennevisie
@Bennevisie 4 жыл бұрын
Terminology FYI: * Having to make a change to a feature requiring updates across multiple layers = "Low cohesion". * Having all of your highly related stuff grouped together = "High cohesion".
@benlewies8828
@benlewies8828 4 жыл бұрын
SUMMARY (work in progress) + N-tier (horizontal layering) architectures leads to code that is low in cohesiveness, every update spread across multiple layers + 7:15 Refactor to vertical slices 1: Group closely related code to a single place (group by feature or domain object) + 9:00 Refactor to vertical slices 2: Move service methods to classes. Request (Input) -> Request handler -> Response (Output) pattern emerges + 11:30 Refactor to vertical slices 3: Use MediatR to eliminate repetitive code for Request/Handler/Response + 13:41 Refactor to vertical slices 4: There are typically 2 types of requests, either Queries or Commands. CQRS pattern. One model in, one model out. + 16:05 Complete encapsulation of handler logic in a single class. Don't share logic between slices (requests, responses, and handlers). Responses can be simple (1 class with dumb primitive attributes) or complex (Class with relation to inner classes, such as in parent-child relationships). + 23:05 Modeling queries. Queries with resulting commands (Create/Edit screens) + 24:20 Modeling commands. Commands Queries should contain ALL the information required to do the work. Commands Queries should be synchronous! 29:00 Command Responses. Advice to not return something is wrong: what was the result?! You could return true / false + reason; Http status and redirect URL; finalised object => complex response (CommandResults). + 33:25 Modeling Query Handlers. Model Requests (Input) and Responses (Outputs) 1st, with black-box view of handler. Then fully encapsulate all of the logic for the query in the handler itself. + 37:25 Duplicate logic. Is it accidental duplication, or literally the same shared logic? Use standard refactoring techniques for common logic (class, function, extension method, library), but beware false abstractions. + 38:15 Command handlers. Use DI with minimal abstractions. Reject unnecessary abstractions (E.g. use DbContext directly, rather than IRepository). The logic in the handler is already completely encapsulated from other handlers. Only in cases where you would like to isolate your system from changes in other systems (service wrappers) is OK. + 40:30 Red | Green | Refactor. Standard refactoring techniques. Useful patterns: Decorator; Chain-of-responsibility; Strategy (99% of pattern needs). + 43:10 Push handler behaviour down into domain model. Pass in request objects to domain model. + 44:55 Validation Scopes: Request validation; Command validation (Domain model + database + external models). + 46:15 Request validation: FluentValidation or Data annotations. Only validates request object itself + 46:55 Command validation -> Domain validation. ....
@jankinsics
@jankinsics 4 жыл бұрын
Thank you for the summary
@PaulSebastianM
@PaulSebastianM 3 жыл бұрын
Thank you!
@GG-uz8us
@GG-uz8us 2 жыл бұрын
Very helpful, thank you so much.
@andreiguzovski7774
@andreiguzovski7774 Жыл бұрын
"Reject unnecessary abstractions" Is really Application layer(business logic) depending on DbSets and DbContext a good thing? Must not Application be oblivious of what Infrastructre implementation details are? IMO having data access logic and referencing EF Core in Application is coupling my whole application to the EF Core, disabling me to switch to different technology or use several technologies while being loosely coupled. After all it is D of the SOLID.
@leakyabstraction
@leakyabstraction 3 жыл бұрын
Great talk, and more people should notice that he is not calling it "CQRS with MediatR", but vertical slicing. I think we collectively should stop equating MediatR with CQRS, especially if segregating queries and commands has no integral value or significance in our project, and all value comes from, well, vertical slicing.
@vuralmecbur9958
@vuralmecbur9958 6 жыл бұрын
I've been doing designs similar to these without giving it a name. Still, helpful to hear them from another developer. GJ.
@JonatanMachado
@JonatanMachado 2 жыл бұрын
Great talk! I've seen many projects using a layered approach that bothered me a lot. They use to create a service layer and then use it as a proxy to reach the Repository. They have classes with one-line methods, which call a Repository method only. As Jimmy showed us, if you're using EF, you should use DBcontext directly, avoiding needless abstractions. There is another aspect about repository classes. I've seen some methods in a repository that fit for one scenario only, which leads me to think whether it should stay in the general repository or not. I think it could stay in another and more specific repository. We really need to think about needless abstractions.
@justanaveragebalkan
@justanaveragebalkan 2 жыл бұрын
Agree, EF implements IRepository in the DbContext, however there are certain cases where a Repository in front of EF core can be quite useful. For example at work we use SQLite for one of desktop applications, non sensitive data for settings and caching to optimize performance and a backup in case the connection goes out. If we decided to keep everything inside the DbContext first we will all have to be extremely careful when it comes to updating models or adding new models regardless if we chose code first or database first since every change has to be added to the context itself, which makes merging branches potentially hazardous on each release, takes one bad Friday to mess everyone work and good luck rolling back 800 commits to find the culprit that caused it all. However with an abstract Repository if let say i am building a new module that allows the user to create a personal note. I can build my views, add my business logic service to manage the functionality create a new model that doesn't exist anywhere and i can just pass it as Repository.Create(data) and the repository pattern that we have implemented will automatically update the local database create the table and save my record. Also i don\t need to create a get request for my data because my Repository.Get already implements a predicate function T which allows me to write anything that i want in order to query my data back. Not saying it should be used everywhere, a lot of people tend to do so, and it's a real bummer when you see it especially on a big project. However there are still some niche use cases where it can be viable.
@vekzdran
@vekzdran 5 жыл бұрын
Remarkable presentation. Really layered out and open to precise testing. When layer to this scale, one can analyse perf. in detail on any of those layers or decide to extract into specialized services. Really good example of practical and reasonable decoupling. Thanks Jimmy.
@milosmrdovic7233
@milosmrdovic7233 2 жыл бұрын
Can you elaborate more on what specifically is decoupled in this architecture?
@banatibor83
@banatibor83 Жыл бұрын
As I see he compares two different things, like saying about an alligator that it is greener than longer. The talk is basically about, do not spread your domain model across layers. For example the database access through the orm using the auto mapper. The orm is the data access layer, kept separated from the domain layer.
@milosmrdovic7233
@milosmrdovic7233 2 жыл бұрын
This seems like an ORM-based Transaction Script with a fairly anemic domain model and everything from the view DTOs, down to the database tables tightly coupled together. You can't test the application logic without firing up the database, you can't touch the database without affecting the domain (and by extension the whole application), you are forever tied to a particular ORM library, to mention just a few issues... On top of that, there's great deal of code duplication to make the whole thing even more fragile, immobile and viscous.
@ChrisAthanas
@ChrisAthanas Жыл бұрын
The duplication of code is not as problematic as having to run tests in production
@hendi51088
@hendi51088 Жыл бұрын
This is conceptually very similar to "Functional Core, Imperative Shell", if your Handler is the imperative shell and the domain logic is the functional core. It's hard to go back to a full layered or OOP architecture after this way of thinking clicks for you.
@CesarLuisAfonsoDias
@CesarLuisAfonsoDias 5 жыл бұрын
As a team leader who had to deal with many many trainees entering one projects without knoledge on architecture's or even programing and leaving after a few months, I started to use a similar architecture sometime in 2015 on my projects. On my experience, it makes a project look uglier to expert developers, because the separation off layers is not pretty well defined, I dont use the reuse the same functionality between components and sometimes that functionality is just copy/paste from one component to the other component. But on the other, when the business needs a new functionality/or fix something, they don't know layers, they know UI interfaces and always specify things regarding the output, so it's easier to new delevopers understand the project and the components, they are not so afraid off changing something and dont have to know their impact on the project, the projects have less bugs and are easier to find and fix it. Some key layers are still separated, like database models (not view models), authentication layers, but those are very special cases. So I can say, you loose on one side but are definitely good things about this aproach and its a valid architecture as the layer architecture. Really depends on the team, on the business or on the timings. Great presentation.
@mishrababli3691
@mishrababli3691 4 жыл бұрын
This guy is so awesome, he created an open source pattern and doesn't care about it. Plus he made it free open source and never ask for money. ❤️
@m.x.
@m.x. 3 жыл бұрын
It's nothing new, it's pretty much basic Software Architecture patterns in practice.
@heshamel-khatib6621
@heshamel-khatib6621 Жыл бұрын
It's always interesting to think about different paradigms, I see all this is about two things really: 1. Don't use abstractions for the most part. 2. Divide your architecture into small chunks/features so that it will tolerate the lack of abstractions/layers. What I really disagree with here is that the main motivation around Clean/Onion architecture was ignored which is treating the Domain/Business as the first class citzen (which is violated by this architecture) and remove the noise/implementation details as much as possible from business stuff by introducing abstractions. This lecture here just ignores that and summarizes these paradigms as "Just another type of layered architecture".
@ChrisAthanas
@ChrisAthanas Жыл бұрын
Useful for small projects and total team size of max 8 If it expands beyond that the gatekeeper strategy won’t work (approving each pr to conform to the vertical architecture) You will need architectural rules and abstractions just to convey structure to all the members of the team This becomes the major issue at some point bc every developer thinks in different ways and they all think it’s the best way
@andreiguzovski7774
@andreiguzovski7774 Жыл бұрын
"Reject unnecessary abstractions" I completely agree with your disagreement. It seems to me that the reason behind that is "Repository pattern not being CQRS and vertical slice compatible" since it stores both commands and queries in one class. Though nothing stops you from slicing up the parts of the Repository into "IGetEntites" or "IUpdateEntity" and so on interfaces and store them in the same folder as your handler. Then just provide implementation in Infrastructure under the Entity folder. Enables you to switch Infrastructure without modifying Application and also use different Infrastructures with your app which is one of the conditions to a Clean/Onion architecture.
@PaulSebastianM
@PaulSebastianM 2 жыл бұрын
54:34 - Jimmy! The GDPR is not junk! 🤨 NOT having the GDPR protecting your private personal information is junk! 😤
@ChrisAthanas
@ChrisAthanas Жыл бұрын
Any thing I can see that backs any of this up? Any proof that GDPR actually protects anything? Just seems like more silly regulations that allow for monopolies to solidify GDPR makes a lot of claims but I’m not seeing any evidence
@PaulSebastianM
@PaulSebastianM Жыл бұрын
@@ChrisAthanas just because you're ignorant and just looking to validate your own wrong beliefs, and couldn't be bothered to even google for the proof you proclaim to not exist, doesn't mean it doesn't exist. GDPR has unearthed tons of privacy violations and protected millions of people's rights. If basic human rights don't matter to you, then I have nothing else to talk to you about.
@ivanmiroshnichenko4299
@ivanmiroshnichenko4299 2 жыл бұрын
When I just graduated a university and went to my very first work. My team leader said to me you had to run through abstractions and there wasn't much use of static classes except for implementing help classes. Those days I suspected that I didn't need to create tons of interfaces for everything that I've created. In other words, you can just add your service itself without registering it through an interface. If there's a 99% chance that no one won't replace your implementation with something different you can create a static class. As developers who were around me in Russian companies said that I hadn't had a point. On the other hand, as a result, I came to a pipeline-oriented architecture. I predict the next step is to get rid of synchronization using Akktor system which is gonna get turned into a pipeline.
@ChinmayaPanda1007
@ChinmayaPanda1007 4 жыл бұрын
This is, in effect, composition from functional programming done in a very roundabout way. This is primarily because functions need to be abstracted away in objects in this language. Doing this with something like Python, Ruby and so on would be straightforward; in a functional language like F#, Erlang and so on this would be the natural way to do it.
@christian.mar.garcia
@christian.mar.garcia 4 жыл бұрын
That's exactly what I thought, especially when he showed the diagram of input-handler-output.
@javiasilis
@javiasilis 4 жыл бұрын
Vertical Slice is a good name. Bounded Contexts by Eric Evans is another good one as well.
@diegoonsoftware
@diegoonsoftware 3 жыл бұрын
Bounded Context is a totally different concept.
@m.x.
@m.x. 3 жыл бұрын
@@diegoonsoftware No it's not, Bounded Contexts are a type of approach to vertical slicing.
@makahmed7130
@makahmed7130 5 жыл бұрын
Jimmy Bogard, could you please share a sample project with Vertical slice Architecture
@blabli3483
@blabli3483 5 жыл бұрын
There is a bug in your code at 32:30. FailureReason must be == null for IsSuccess to be true.
@JeanQPublique
@JeanQPublique 3 жыл бұрын
I'm happy someone else saw this!
@neilbusse7536
@neilbusse7536 3 жыл бұрын
32:33 Complicated Payload Response Object 47:42 one line controllers
@davidlester6673
@davidlester6673 2 жыл бұрын
Yes this architecture goes back to at least the 90's if not before. Its called Component Based Development.
@CalifornianViking
@CalifornianViking 2 жыл бұрын
Why do you feel sorry for people who are using SQL procedures?
@muaathasali4509
@muaathasali4509 Жыл бұрын
What exactly is the use of CQRS here? The operation for both queries and commands is the same; we have a request, response and handler. It seems to me that it is just a naming preference.
@ChrisAthanas
@ChrisAthanas Жыл бұрын
I think it’s just the idea of separating requests for info (queries) from the system versus idea of changing something in the system (commands) The data sent and received is different and can be optimized for each case
@MerrionGT6
@MerrionGT6 5 жыл бұрын
Excellent and convincing
@jimmyzimms
@jimmyzimms 3 ай бұрын
@7:05 Just to note I hate the default conventions of MVC that do this and in fact, haven't seen any real apps in my time that didn't override these inane conventions. Putting controllers all together in a namespace because they're controllers is whack (same with a views and models folder). Usually see alternative layouts that would put a controller as a class in an area's sub namespace (folder) and then the dedicated views and models at the same point as subfolders from there so everything specific to use cases are together. Seems the same as when you open a project and they put all the extension methods for a project in an Extensions namespace [eyeroll] and not by purpose or context. That's the code equivalent of a Junk drawer. Doesn't obviate any benefits of VSA or the purpose of this great presentation, just that even when you're not doing VSA, there's a good point regarding cognitive load and why the default finding conventions are bad.
@diegoonsoftware
@diegoonsoftware 3 жыл бұрын
The description says "we remove abstractions, complex structures". I completely disagree as Jimmy's proposal is doing exactly the opposite. Personally I don't like the way these architectures always end up with a result where the domain is almost hidden/suppressed by high layer abstractions (requests, responses, commands, queries, and a lot of ugly abstractions). A good example of this is at 43:55 where he is "pushing down" the command by calling instructor.Handle(). WTF does "Handle" mean? Is it handling what? There is also the problem of removing important validation from the domain model itself. As the code that defines a model's valid state is now splitted into multiple files it becomes harder to reason about our domain. I also dislike using the same class as both domain model and EF model. In most of the real world systems these entities have totally different purposes. While the domain model is meant to reflect the business processes, a EF entity should just describe a database table. Therefore if you use the same class for both you're going to have a very bad time telling EF how to map it to a table (as they have different shapes), and you will inevitably introduce ORM concerns into your domain models (like navigation properties) even tough it doesn't have any meaning to the business logic. My point is that in order to get rid of some extra layers there is the drawback of taking off the focus from the domain logic, mainly because we would be so busy struggling with Vertical Slice architectural concerns. Don't get me wrong, I find the idea very interesting, but it has the very same problem CQRS has: It is apparently simple, but in the real world the great majority of CQRS implementations are abominations. This is, IMHO, due to the complexity introduced by these pipelines, transaction behaviors, etc. On the other hand, as a "layer" naturally implies "separation", the standard n-layer-based architectures have the advantage of being easy for humans to clearly perceive the application boundaries. Then, it becomes easier to decide where each piece of code belongs to, and all our services and repos won't need that huge amount of nonsense abstractions. Concluding, this architecture does not achieve the goal of simplicity as proposed by the author.
@oleksandr.liakhevych
@oleksandr.liakhevych 3 жыл бұрын
You can avoid unnecessary navigation properties by defining the relations in separate EntityConfiguration.
@milosmrdovic7233
@milosmrdovic7233 2 жыл бұрын
Exactly. It's obvious that this is nothing more than an anemic domain model with a few helper methods for updating data tightly coupled to both the database tables and the UI DTO-s. Unless you want to build a dumb data entry/querying application, there's nothing interesting to see here.
@ChrisAthanas
@ChrisAthanas Жыл бұрын
@@oleksandr.liakhevych Can you elaborate?
@kuldeepadhikari3849
@kuldeepadhikari3849 4 жыл бұрын
damn between 3 to 5 minutes is exactly how i have been feeling recently about one of the side projects I did
@staffansjostedt1740
@staffansjostedt1740 Жыл бұрын
Hmmm, it starts with the example of user, usercontroller and userservice and points out that, as I understand, if the real logic is in the userservice, any changes there might affect behaviour of more than one request. Yes, that we want to avoid. I also like the idea of grouping relevant stuff together. But looking at the slide at about 44:00, after some basic simple stuff like validating, getting data from DB, it calls the domain layer. And in there I assume, is is still residing all (or most of) the complicated stuff that was in a service at the beginning . Why all this MediatR stuff instead of just calling the service from the controller direct? (Off course with validation etc before). Am I too simple minded here?
@timh.6872
@timh.6872 5 жыл бұрын
So taking an n-tier architecture with duplicated models at each layer and reorganizing it based on request-response pairs linked to specific business logic, insisting that the request provide all necessary information to produce the response without visible side effects made the architecture better? Where have I heard that idea before.... OH YEAH! Pure functions! Well defined and encapsulated pieces of logic with a single result type and static input types, with the return value completely defined by the parameters. Congratulations, you've discovered the wonders of pure functional design, except it's been gussied up with objects.
@jimmybogard4178
@jimmybogard4178 5 жыл бұрын
Tim H. Yes but I’m not in a functional language. It’s definitely cleaner in F#!
@nick2193
@nick2193 4 жыл бұрын
Can you give some links to architecture examples like this in FP?
@m.x.
@m.x. 3 жыл бұрын
"vertical slices" or how to reinvent the wheel. This's basically modularization/componentization from end to end (frontend and backend), that's all. I don't know why non-technical people keep re-labelling well-known concepts and pretending it's something innovative. Same with microservices, microfrontends, cloud computing, etc. old concepts relabeled with cool terms.
@ChrisAthanas
@ChrisAthanas Жыл бұрын
If you have been around long enough to see the trends cycle
@PaulSebastianM
@PaulSebastianM 2 жыл бұрын
49:50 - Oh man, 2018, right when Blazor was released... if only it came out sooner, Jimmy would probably has said just use Blazor and share your models between the frontend and backend.
@beziko
@beziko 4 жыл бұрын
Breaking news OOP guy discovers functional approach
@nick2193
@nick2193 4 жыл бұрын
Can you give some links to stuff like this in FP?
@obilykua
@obilykua 5 жыл бұрын
Jimmy Bogard does functional programming using OOP but doesn't name this.
@jiggajim
@jiggajim 5 жыл бұрын
Yes it is, I think I point this out in my SOLID talk.
@beziko
@beziko 4 жыл бұрын
exactly
@nick2193
@nick2193 4 жыл бұрын
Can you give some links to stuff like this in FP?
@tcfialho
@tcfialho 5 жыл бұрын
From the same guy of the great component for do the hard work of populate attributes from one class into another. The new revolutionary component for return values from methods. Reinventing the square wheel don't miss out on a talk near you. LOL
@martinvandrunen8810
@martinvandrunen8810 5 жыл бұрын
Are u brother of Terry and Andy?
@kokizzu
@kokizzu 3 жыл бұрын
King of Coding Fighters XD
@nnndddccc
@nnndddccc 3 жыл бұрын
Great minds think alike I guess. I saw similar approach from Steven van Deursen.
@Feronom
@Feronom 3 жыл бұрын
how big are the slices? Are slices one use case or what?
@ChrisAthanas
@ChrisAthanas Жыл бұрын
The slices are per use case it seems, possibly by feature
@adamhardy7639
@adamhardy7639 3 жыл бұрын
Don't see how this is any different to DDD with CQRS.
@PaulSebastianM
@PaulSebastianM 3 жыл бұрын
DDD is not an architectural pattern. Nor CQRS.
@m.x.
@m.x. 3 жыл бұрын
​@@PaulSebastianM DDD in practice leads to modularization and componentization based on business entities and from end to end (frontend and backend), which is basically the same as he's describing with the "vertical slicing" concept. And those are just modern terms to refer to very old practices that have been around for decades. The art of reinventing the wheel.
@jamesfoo8999
@jamesfoo8999 7 ай бұрын
29:54 I disagree with commands not being void. Void shows it's just "go do something" and not "go get something". Returning a bool to signify if something succeeded or failed is fairly useless as it carries no information. You should throw and catch exceptions. A caught exception is confirmation something went wrong. Exceptions can carry information, and be logged, and you can use different exceptions for different problems. Calling code can catch and determine the best outcome based on that caught clause. Returning bool or even error codes means you have some urcky code to determine the outcome (switch or whatever). And you can't just let the exception bubble up or rethrow it, you have to make a new one every time with bools and error codes.
@Fuel16vt
@Fuel16vt 2 жыл бұрын
@Jimmy Bogard I think you went a little bit overboard with splitting code into INPUT -> HANDLE -> RESPONSE. If you think about it, this is what a normal function does. Input are the parameters, handle is the code inside the function and response is what you return. You complained about low cohesion in the layered architecture but instead recreated it inside your vertical slice by doing things this way. Splitting the code into queries and commands is good, since commands and queries will most often have different dependencies. I think you should have kept the layered architecture and just splitted your code this way instead. There is nothing forcing you to use the same dependencies between the commands/queries. My guess is that your failure with the layered architecture comes more from the difficulty of identifying and splitting your code into separate bounded contexts.
@GavSaysPogMoThoin
@GavSaysPogMoThoin 4 жыл бұрын
Where can I get these slides?
@florinbadea4923
@florinbadea4923 5 жыл бұрын
@Jimmy Bogard how would you handle the case where you want to log at different stages during the execution of a command? The slides show only logging at the beginning and at the end. What if i want to log in the middle? Should i complement the logging decorator with an ambient context logger? Also, from what i could understand, the slides show registering the pipeline behaviors all at once. What if i want to apply only certain behaviors to a handler (not all of them)? How would i do that? Thanks!!
@jimmybogard4178
@jimmybogard4178 5 жыл бұрын
You can do this with constrained generics, for some containers. Make some requests implement an interface, then apply a generic constraint on that behavior.
@drakoumel_5
@drakoumel_5 5 жыл бұрын
SOC thrown right out of the window... It's a nice concept however essentially it removes the ServiceRepository Patterns and creates a controller for each use-case. Not greatly different. I guess it has its trade offs, on the one hand you have 1 point of truth for each use-case which actually could be achieved by having Services Per Use Case but on the other hand the duplication of code is massive :/ Great talk however.
@jimmybogard4178
@jimmybogard4178 5 жыл бұрын
Actually SOC is enforced, each concern is a class. Can’t get more separate than that!
@drakoumel_5
@drakoumel_5 5 жыл бұрын
@@jimmybogard4178 you have one end point for each action, do you bundle this together with for example Services and Repos etc? (maybe I didnt understand correctly)
@ChrisAthanas
@ChrisAthanas Жыл бұрын
Duplication of code sometimes makes sense
@brandonpearman9218
@brandonpearman9218 5 жыл бұрын
This vertical thingy is just a fancy name for doing nothing. I suggest a new architecture called "super duper architecture" where every http call has a request model and a response model then the controller calls a method which runs the business logic. Even though I don't like the architecture I think there are a few good points here. I like the emphasis on understanding when to duplicate code and when not, as well as keeping things simple until more is required. Excessive abstraction can cause unnecessary complexity but it has its place. I think most projects in recent times are suffering from over complexity but I feel like this has swung too far in the other direction.
@jimmybogard4178
@jimmybogard4178 5 жыл бұрын
Have you tried this architecture? How do you know?
@brandonpearman9218
@brandonpearman9218 5 жыл бұрын
@@jimmybogard4178 I have not tried writing a project from scratch with it but I have joined an existing system which applied most of this and it became "legacy" after 1 year and I was asked to rewrite it and in other services I had to just change the db, or client, or other tech. I find this style very confusing and hard to find what you looking for and extract/remove certain tech. What you point out with onion is definitely an issue, and but I would rather deal with the rigidity.
@Rizon1985
@Rizon1985 3 жыл бұрын
Such are extremes. Neither ends are healthy. Onion people who end up with 30 projects in their solution with hundreds of files where 95% of the files are a single line of code and you wonder what IDE they're using that makes them able to open 20 files to adjust some simple feature. You can't debug it because IDEs don't even understand the code anymore and without regression tests it is impossible to make changes without errors. Or this javascriptification of coding that's horrible for any serious project with a couple hundred pages analysis and that you need to support, maintain and update over 15-20 years. Why even have any separation at that point when it's only fake separation. Just put all your UI, business and data access in the page itself and be done with it.
@brandonpearman9218
@brandonpearman9218 3 жыл бұрын
@@Rizon1985 Yeah I do think separating code has gone way too far. The justification being SRP, "if a class has more than 1 line of code then it is doing more than one thing". But that is a non architectural detail, you don't have to do that when using a layered approach. Don't throw the baby out with the bath water. And I do agree that there is a lot of "fake separation" but I use some separation where it is useful and provides value. If I go too far, I feel the pain and back track.
@Rizon1985
@Rizon1985 3 жыл бұрын
​@@brandonpearman9218 If you're making products with business demands and that you have support (for a way too long timespan because of said business), it is very unlikely you are using either sides of the extreme. Most people don't like to torture themselves and self-regulate to a healthy balance. It's the theoretical architects that sell northwind database presentations who never make any actual products that end up spending time fighting over it. New blog post on MSDN, they write a students/course powerpoint and then go around town saying their new goose can lay golden eggs. Worst scenario when your management let them in to tell their story and now they're at your desk with a goose demanding you make it lay said promised golden egg.
@sapito169
@sapito169 5 жыл бұрын
Exelent
@jesserosenberg3032
@jesserosenberg3032 5 жыл бұрын
I agree with much of this, however, I think he has gone to far in the extreme of sharing NOTHING. Sharing code should not be a four letter word. It should be used with things, such as simple data structures, used in domain specific models that do not change often. For instance, so that you don't have to repeat FirstName, MiddleName, LastName everywhere, just include it in a shared Person object, that can be shared throughout. Later if you want to add date of birth, you can and have it available everywhere. You can also easily find all the places that the person object is used, regardless of the action being performed.
@jesserosenberg3032
@jesserosenberg3032 5 жыл бұрын
Hi, @Steve Sheldon. I'm a middle aged developer :) I totally agree with what you are saying as far as a balancing act. I was just a little concerned when he said that sharing is a 4 letter word. I think that could definitely be misconstrued by younger and more impressionable devs.
@jimmybogard4178
@jimmybogard4178 5 жыл бұрын
Jesse Rosenberg Juniors taking any advice without context is risk, no matter what. This talk is for seniors and tech leads, not for those that don’t have any experience.
@super_sigma_
@super_sigma_ 5 жыл бұрын
If you've had to cry with the Onion Architecture, you were doing it wrong.
@jiggajim
@jiggajim 5 жыл бұрын
We were doing onion architecture with the person that invented the term. I don't think we could have had a better chance to get it "right".
@super_sigma_
@super_sigma_ 5 жыл бұрын
@@jiggajim Jeffrey Palermo? And there's Robert C. Martin with Clean Architecture. So if it failed, please enlighten me why it did? We're having a blast with it, ever expanding our monorepo using it. Doesn't say it doesn't have its drawbacks or limitations, but it's definately better than classical architecture.
@super_sigma_
@super_sigma_ 5 жыл бұрын
​@@jiggajim Thank you for this clean and elaborate breakdown of your experience with Onion Architecture. While I sympathise with the YAGNI argument to a certain extent, because not every abstraction is needed to enable pluggability of other implementations, that's just a utopia, this is not the only reason for wanting to apply DI on key places (usually when you exit your system). For us having the abstractions in place for every (let's call it) IO device client, we were able to test all of our application's business logic in memory with every IO device stubbed in seconds. I don't see this being possible without DI and Onion Architecture provides a solid template to apply it in. Also we had a requirement to deploy our applications as WAR on an old application server as well as as microservices in the cloud. There were definately cases we could get away with only writing a new implementation for the cloud, without touching our core application. This would be the Open-closed principle in SOLID. So we're having three layers: Core, Integration and Delivery, no more, no less. Core contains all business logic and entities, basically most code. Integration all repository logic (JPA repositories, WS/Rest clients, etc, we just call them all repositories). Delivery contains how you want to deliver the Integration (like Spring Boot, WAR, Test etc). Also there proved to be a surprising amount of reusablity in the integration layer, because the repositories are so generic, containing no business logic at all. And a good amount of flexibility, because we could wire everything up in delivery the way we want it. All in one JVM for test or as smaller deliverables in the cloud. I wonder how all these benefits work out in vertical slices. I do have to stand by my initial point that someting must have gone wrong for this not to work. Especially for big projects it's so suitable. Endlessly scalable. I've used it now for almost 6 years successfully in different size projects. Keep it clean and don't break the architecture in a monorepo though, or there will be hell to pay.
@brandonpearman9218
@brandonpearman9218 5 жыл бұрын
@@jiggajim So did Jeffrey Palermo build this project with you, and see it fail just like you? I think you are attributing the problems to the architecture where he may have other reasons for the failure... what is his side of the story?
@jimmybogard4178
@jimmybogard4178 5 жыл бұрын
Brandon Pearman He disagreed with us ripping it out and applied it on a couple subsequent projects, which we ripped out again. He didn’t actually have to code against it, we did. We saw what it did to our code, and ditched it.
@reggiepangilinan
@reggiepangilinan 5 жыл бұрын
I created a cli tool that generates the web api following similar concepts github.com/reggieboyYEAH/dotnet-gimme/blob/master/docs/WebApiStarter.md So you dont have to create all of this classes. Just run the cli command and it will generate a command and query class for you.
@jaysinha9715
@jaysinha9715 5 жыл бұрын
Create a simple ToDo API project, that would be great help to beginners .
@JohnnBlade
@JohnnBlade 5 жыл бұрын
We just need old skool plugin architecture, keep it simple and professional/enterprise
@17plus9
@17plus9 5 жыл бұрын
Isn't this the thing ServiceStack basically uses?
@jimmybogard4178
@jimmybogard4178 5 жыл бұрын
Roman Yes.
@igo_rs
@igo_rs Жыл бұрын
We just discovered a… function 🤦‍♂️
@ShadoFXPerino
@ShadoFXPerino 3 жыл бұрын
He talks shit about stored procedures but this is architecturally identical to stored procedures, just it lives in C# land where you have refactoring tools.
@kahnfatman
@kahnfatman 2 жыл бұрын
No more classes. Go modules and FP. No more pretending to model after real world objects. Model after business processes instead.
@ChrisAthanas
@ChrisAthanas Жыл бұрын
That’s a good subject for a talk
@GreenDimka1
@GreenDimka1 14 күн бұрын
This is one of the worst architecture I've been working with. It may look like something cool in these short KZbin presentations. But it in a large real life project this architecture becomes a mess very fast: scattered logic, scattered responsibilities, lots of boilerplate and duplicated code. Benefits? Virtually no benefits: everything becomes tightly coupled. Developers loose control of the code. Stay away from this archotecture if you are starting a new project: maintenance costs will skyrocket.
@codewkarim
@codewkarim 2 жыл бұрын
Cake architecture.
@Suriprofz
@Suriprofz 4 жыл бұрын
This seems more like a anti pattern
@ChrisAthanas
@ChrisAthanas Жыл бұрын
It has a limited use case for smaller projects
@crack8160
@crack8160 5 жыл бұрын
this video is muted.
@ChrisAthanas
@ChrisAthanas Жыл бұрын
Maybe it’s the crack
@PaulSebastianM
@PaulSebastianM 3 жыл бұрын
var vsa = onion.flatten(); // warning: there might be tears
@ChrisAthanas
@ChrisAthanas Жыл бұрын
Don’t expand past 4 developers
@PaulSebastianM
@PaulSebastianM Жыл бұрын
@@ChrisAthanas the reason architecture exists, among other things, is so you CAN expand past... "4 developers". 😑
@ChrisAthanas
@ChrisAthanas Жыл бұрын
@@PaulSebastianM exactly Architecture is annoying because it imposes rules Architecture is amazing because it imposes rules “There are no solutions, only trade-offs.” - Thomas Sowell
Vertical Slice Architecture - Jimmy Bogard
1:02:50
NDC Conferences
Рет қаралды 47 М.
Vertical Slice Architecture (Jimmy Bogard)
1:35:42
Tech Excellence
Рет қаралды 10 М.
How To Get Married:   #short
00:22
Jin and Hattie
Рет қаралды 25 МЛН
Minecraft Creeper Family is back! #minecraft #funny #memes
00:26
Domain Driven Design: The Good Parts - Jimmy Bogard
58:39
NDC Conferences
Рет қаралды 220 М.
Vertical Slice Architecture, not Layers!
46:24
CodeOpinion
Рет қаралды 121 М.
Vertical Slice Architecture Project Setup From Scratch
22:43
Milan Jovanović
Рет қаралды 59 М.
40 Years Of Software Engineering Experience In 19 Minutes
19:10
Continuous Delivery
Рет қаралды 84 М.
Design Microservice Architectures the Right Way
48:30
InfoQ
Рет қаралды 713 М.
🚀 Vertical Slice Architecture (Jimmy Bogard)
54:55
DevTernity Conference
Рет қаралды 16 М.
Do I Need MediatR in Vertical Slice Architecture?
7:58
Gui Ferreira
Рет қаралды 6 М.