Architect Tip: Application Architecture Diagrams

Architect Tips

Welcome to architect tips. I am Jeffrey Palermo. And I am going to show you today how to use architecture diagrams in a really, really easy way. Now as we go through, there is a lot of resources, a lot of, interesting topics on the Azure DevOps podcast. You will want to make sure to check out that as a resource to you and on this show architect tips, I will answer your architect questions. All you have to do is tweet me @jeffreypalermo and I'll pick a question and, if I can put it into a short five-minute bite-sized chunk, I'm just going to make one of these out of it. Otherwise, I will just send you an email and I will answer it for you.

So, go ahead and send me a question there. And so now let us get into architect, architecture, diagrams, and I want to, I want to make it easy and show you some, diagrams that I use. So, let us take a system you want to communicate. You want to communicate what you want to either be built or what you are going to build with your teammates then you need to draw something.

If it cannot be drawn, it cannot be built. Every profession that creates something has some type of design diagram. And so, we need that here.  So, let us pretend that we are starting a work order application. We are going to build a work order application. And so, we need some diagrams that are going to communicate it, and bread and butter diagrams is going to be your diagram.

You could also think of it as a class diagram also. We are going to make ample use of sequence diagrams. Okay. Then you might have some patterns. In the case of a work order, a work order has a status, and it has a workflow. And so, we need to make use of a state machine diagram. And a lot of times, an activity diagram will be interesting or an overall dependency diagram.

So let's just take these and let's go through one at a time and see how quickly we can use these particular diagrams to describe a work order application in a fashion where you would actually understand what .NET code needs to flow from this. So, let us start with a dependency diagram, you know, I am a fan of onion architecture. If I am laying out a visual studio solution, and I say, you know what, it is going to be.net. It is going to be Blazor web assembly. We are going to use a C-sharp nine and we are going to use SQL server, we are going to pull it up, Azure. Well, one of the first things is what is my visual studio solution look like?

So, I am just going to quickly spec it out. I am not going to explain why, but I am going to have it core library. That is a, you know, dot net standard two. I am not going to go on all the rest of it. Then we are going to have a UI project. We are going to have a data access project, and I do not, I am not going to worry about my handwriting.

I am just going to do this. And then we're going to have, let's see what else, you know, I know that I need some unit tests, so we're going to have a unit test library and I'm going to have some integration tests. These are going to be projects. And so, you know to have him here and unit tests are going to be linked to core integration tests, going to be linked to data, access, and core most of the time.

And, if I put in acceptance tests, over here, most of the time they are linked to data, access core, and UI. So that is our test coverage. Now I did not put any arrows here. We need to communicate that. Well, the core needs to have no other dependencies. Then just .NET standard and whatever, most stable libraries. You are only as stable as your most stable library.

So, I am going to make sure that the UI references core, I am going to make sure that data access references, core unit just references core, ah, all incoming references. I like that. No outgoing references for core acceptance tests that let me just finish these. And I finished all of them. Alright. So that is our dependency diagram.

Now, what about our core? Object model or domain model. I love domain-driven, design the pattern, the language that it gives us. Let us just put the work order right here in the middle. And this is going to be a class diagram or just an object, an object diagram. I have a work order. A work order does need a status.

I think, you know, draft. So, you know, we need to status object and whether it's an enum or a, or an enumerated class, you know, maybe we call it work, order status, all abbreviated here. And we have things like draft, right? Maybe another one is submitted, maybe another one assigned, assigned to a technician, and maybe then it is in progress.

And maybe it is completed, and, or maybe canceled, you know, you can cancel a work order. We have a status. Okay, has a relationship and, you know, also we need, we need a submitter, somebody who is going to submit the work order. If I have an organization list this year, they say, well, there is another entity and employee is a submitter or what, and then, and then we need them.

Let us see, and then we need someone to assign the work order to so an assigned E and you know, you can assign it to a technician. Okay. Go but you know what a technician is also an employee. Let us say there's a, there is an inheritance relationship, open triangle. And, you know, maybe later on down the road, Well with approvers and whatnot, we may have a manager or a manager kind of is an employee, a technician has a manager, so we can do that. The technician is open I think we will; we will leave it for that.  A manager is an employee. A technician is an employee, and a technician has a manager. All right. So, there is our object diagram. So, taking that object diagram, into consideration next, let us try to, let us try to figure out.

How are we going to put this application together? Let us do a sequence diagram for just creating a new work order when we created it. It's going to be in draft status starting out with a sequence diagram to explain this, then I have got my actor and I'm just going to blow through if you've never heard of whatever diagrams, just follow along.

 I am not going to go into UI patterns. I'm just going to be abstract and say, okay, UI in the UI,  a person who's going to use the UI and there you going to go to a screen and they're going to draft a work order. All right. So, what happens? Well, in the most simplest sense, if we're not really using any kind of scalable patterns, we might say that the UI uses the work order object directly and the controller or the screen code or whatever component is just kind of call the constructor of the work order directly. And then, you know, a common pattern. If I have a work order repository class, you know, maybe the UI then goes directly and says, Hey, go ahead and save, this work order.

And of course, then we have SQL server. And the workload repository is just doing an insert statement. Okay. That could be a possibility, but that doesn't scale at all because now we have to do all that for, for the manager or technician employee for it's just puts too much logic and basically guarantees all of your logic except for your SQL statements are going to be right there in the user interface.

So, we do not like that. We want to do something. I am going to do something a little bit better. So, let us talk about drafting. Let us consider an alternative and come up with a pattern and let us use a little bit from CQRS let us draft some commands and let us use a bus pattern.

So, let us try this again. How would we describe if we were going to do another panel? Let us ignore the user interface for a little bit longer, but you know, the actor is still going to draft the work order. Okay. And then instead of going directly to creating our aggregate route in our domain model, which would be work order, one of our entities that serves as a route of an aggregate let's instead craft a command and where we pull away the user's intent, the intent of the user or the request of the user is to draft a work order. So, let us say draft work order command and I am abbreviating, but in C# you would not abbreviate all these become types.

So, we would create this command like a DTO, and then we would pass it to a bus, or I bus, which an abstract. So, I would not say bus dot send. And then this was, you know, look around and look for a request handler. And if we are going to specify this type of pattern, then it is going to look for the right, handler, and say, Hey, will you handle this command?

Okay, great. We need to do that one. How do we do that? Well, you know, we need a lot of classes that inherit from here would, this would be a. Draft work, order command, and yes, all your diagrams, like this can be completely flexible. You can mix and match paradigms. The open triangle is inheriting from, and so through an inversion of control, an abstract word in extend this, and it is going to implement the handle method.

Okay. You can mix and match all of these, all these diagrams, all these things. And so, we have a handle method. Well, how does it do it?  well, we are going to have a work order object, and this is the class that calls the constructor of the work order and set. So, drag status to draft. And now we need to say that let us say an OMF.

Well, let us, let us see how this, let us see how this continues. So, we have a draft work order, command over here. Or did I say command I am in the handler, as some of you are confused. We have a handler class that handles the command. Now in this handler, we can turn right back around, and we can create some type of command to send back to the bus.

So, if I were to say, save, you know, entity or save aggregate command. And then I created that command. I passed in the work order to this say baggery command. And of course, I get the object back and then I pass this back and say, bus dot sinned, passing this, save aggregate command. Well

Para escuchar episodios explícitos, inicia sesión.

Mantente al día con este programa

Inicia sesión o regístrate para seguir programas, guardar episodios y enterarte de las últimas novedades.

Elige un país o región

Africa, Oriente Medio e India

Asia-Pacífico

Europa

Latinoamérica y el Caribe

Estados Unidos y Canadá