I am Tim Corey. I teach coding online and my inbox is full of questions from current and future developers. I wish I could sit down with each of you and share the answers I know will help you go further, faster in the world of development. This podcast is the next best thing. On this podcast, I will answer the biggest questions people are asking! Send us to your suggestion for a future Dev Questions at https://suggestions.iamtimcorey.com/ To keep the podcast coming, like, subscribe, rate, and share it with your friends and colleagues. See why thousands of students have chosen to learn to think and code like a professional developer at www.DevForge.com.
Use Left/Right to seek, Home/End to jump to start or end. Hold shift to jump forward or backward.
0:00
|
12:43
What is the right way to structure my application? What layout is best for applications? Are there specific best practices to be aware of? How do I architect my project correctly? We will answer these questions in today's Dev Questions episode.
Welcome to the Dev Questions Podcast with Tim Corey. Join us each episode as we tackle the questions you are asking about a career in software development, understanding the industry, and new technology. If you're just starting out or you want to grow stronger as a developer, this is the place to get your questions answered. Now, here's your host, expert developer and online educator, Tim Corey.
SPEAKER_02
How do I structure my application? What are the best practices for how to create that perfect structure? This is a question from a suggestion site, and it's one we're going to tackle in today's episode of DevQuestions. Now, if you have a question, go to suggestions.imtimcorey.com and ask your suggestion there or ask your question there, or look at somebody else's question and upvote it to hopefully see it in a future episode of DevQuestions. So, what's the perfect structure for your application? How do you lay things out so that they're designed really well? And you probably know what I'm going to say right now, but it depends. And yes, it depends is almost always the right answer. May not be the one that explains everything fully, but it's the right answer because it does depend. It depends a lot on a lot of different things besides just what you asked. But let's talk about the ways to structure an application. Because let's start there. There's lots of different ways to structure an application. If there's one perfect one, we'd only have one, right? So you can have domain-driven design, or you can have the onion architecture, or three-layer design, or CQRS, or everything in the code behind of your forms. You know who you are. So what's the right way? Well, the right way depends on the size and complexity of your application. So a key point here, it's one we have to understand before moving forward. And we'll talk about the five things to work through when it comes to uh figuring out the right architecture, right layout for you. But the key point to understand first is that architectural design patterns have a cost. The thing they fix needs to be more expensive than the cost of the pattern. It's really important to understand that. Anytime you add in a design pattern or add in this structure or this layout, there's a cost to it. And it needs to be less than the cost of not doing it. So you have to have this balance because you know there's a there's a really easy way to see this. Is I have a video on YouTube that is on the perfect console application. And we build out the, and it's yes, tongue-in-cheek, it's a little bit facetious, but we build out this really complex uh console application, which by the way, is also really good at teaching you things like how to put dependency injection in a console application, how to talk to your app settings and other things that you kind of do need for some console applications. But at the end of the day, we build a hello world application. Did it need all those different files and that dependency injection and structure and all the rest to say hello world? Well, no, we just need one line that said console.write line, hello world. Done. Okay, so we didn't need all that complexity. But on the other side, I see enterprise applications that have Windows Forms, let's say, as their user interface. And when you open the code behind for Windows Forms, you see all their UI logic, all their business logic, all their data access logic. It's all in the code behind. That's also not a great design. Okay. So how do you figure out that middle ground? How do you figure out when to apply patterns or when to create certain structures or when to break things apart, when to separate things in different ways? So let's talk through that. I think there's really five keys here. The first key is to start simple. One user interface, one class library. Start there. And yes, I do want to see some of that broken apart. Now, okay, a very small application might not need a class library. For creating a microservice, you might not even need that class library. But if we're talking about some type of monolith, and monolith is not a bad word. Monolith is probably the right way to go in most circumstances. But start with one UI and one class library and try and keep it just there. Start there. And then as you go through your design process, as you go through your building process, if you say, you know what? No, we need some more complexity. Maybe we need a folder structure in here. Maybe we need some more separation or grouping things a certain way. Only refactor, only bring in those patterns when complexity is significant. There's a principle called dry, don't repeat yourself. And this is one of the most abused principles out there because everyone knows it. And so everyone also applies it in the wrong spots, too, accidentally. And one of the ways I see it applied poorly is when you see yourself repeating something once. So you have two copies of something and you say, ah, dry, don't repeat yourself. And so you create a class for that and you create a method in that, you put it into pants and injection, and you sell this up so you have one place, one method call for where you would otherwise have two methods or two bits of logic. That's probably an abuse of dry. Because really, for dry, you want to say, hey, you know what? I've done this three times, I've done this four times. I started to see a significant repetition because a little repetition is okay. And in fact, it's better than bringing the complexity in of trying to refactor that out into a separate method and calling that in a lot of circumstances. So that refactoring needs to happen only when complexity is significant. Number three, don't separate related things. Too often I see people looking to create separation everywhere. Where they say, okay, every bit of code has to be in a library somewhere. It cannot be connected to anything else. We're gonna have five different libraries. The user interface is gonna have zero code in it. It's all gonna go right to a library. Okay, that's a problem. Because what you're doing is you're separating things that probably go together. I've had people ask me, they say, okay, Tim, I know that there's a one-way relationship with a library where the library doesn't know about the caller. So say user interface can call the library, but the library can't call the user interface. That's a problem because my code needs to know about the user interface. And the user interface needs to know about my code. What you just described is user interface code. It needs to be in the user interface, not in a separate library. Because those two shouldn't be separated because they're really one entity. So that separation, all it did was add complexity. It didn't add value. So don't separate things that are related. Okay? Put things together that go together. Number four, your goal here is to keep it simple. That may sound obvious, but really it's not once you get into the heat of battle. Once you start writing code, you start thinking about, okay, I can implement this design pattern, I can implement that design pattern. I have 18 more in my back pocket that I know about, so I know I need to put those in there somewhere. That's adding complexity. That's not the goal. The goal isn't to get design pattern bingo. Okay? You're not looking for how many of these things can I cram into my application. The goal of writing code is to keep it simple. I said this before, but as a junior developer, typically, you write simple code to solve simple problems. As a mid-level developer, you write complex code to solve complex issues. And as a senior developer, you write simple code to solve complex issues. That's what you want to achieve. You want to achieve the ability to write simple code to solve complex problems. Create simple applications that solve your goal rather than complex applications because you have to maintain it. Or more likely the person coming after you has to maintain it. And when it's too complicated, it's just not worth it. It causes too many problems. And I've had I've paid for applications to them completely built. And I look at the code, and you know what? I didn't spend enough time working with the developers. And so that's super complex to do a simple job. I'm gonna throw it out. I'm gonna start over. Because the goal is to write simple code. Write simple code. Don't write complex code. Don't try to bring in design patterns because you've heard about them or you think they'd solve these problems. Wait until you have a problem that is going to be made better, easier, less complex if you add that pattern. Okay? When you start adding things and realize they become more complex, that's a problem. All right. And number five, it kind of ties into all the previous. Let the situation dictate the structure. Don't start with a structure. Too often people say, what kind of architecture should I have? Should it be domain-driven design? Should it be CQRS? Should it be ion architecture? Should it be the three-layer stop? Let the situation define the structure. Because today it might be this, tomorrow it might be that for a different application. If you try to come in with preconceived notions, with preconceived layouts, then what's going to happen is you're going to introduce a lot of complexity where it's not needed. So I know it doesn't give you an exact create these folders, create, you know, put these things here, but that's because it comes back to it depends. And if you hear someone say, no, this is the way of doing things, always that's a problem. That's not good advice. Because that doesn't take into account your situation or your code or what you're trying to accomplish. So you need to figure out based upon what works for you. And you know what? The same application might be built and structured differently in two different companies because they have two different teams in two different ways that seem simplest to them. So that's okay. Pick what works for you, figure out how to make things as simple as possible, and move forward from there. I hope they answered your question. Thanks for asking it. Thanks for listening. And as always, I am Tim Corey.
SPEAKER_00
Thank you for joining us for this episode of Dev Questions. Tim is committed to making it easier for you to become a developer. If you would like to help make more content like this possible, please like, subscribe, rate, and share Dev Questions. You can also send your questions to questions at IamTimcore.com. Until next time, remember, you are too smart and your time too valuable to waste it making all the mistakes Tim did. When you're ready to learn to think and code like a professional developer, head over to imtimcore.com and enroll in a course.