DEV Community

loading...

Please explain why I need software architecture

patarapolw profile image Pacharapol Withayasakpunt ・1 min read

Like MVC, MVVM, MVP.

How does it apply to

  • Server-side only?
  • Frontend only?
  • Fullstack?
  • Desktop app development?
  • Mobile development?
  • Starting a project from scratch?
  • Continuing someone-else's project? Or forking a project?
  • Working with a team?

Discussion (24)

pic
Editor guide
Collapse
mpodlasin profile image
Mateusz Podlasin

The answer is simple.

When you begin coding, you shouldn't worry about those. At all.

And then, when you write sufficiently complex projects, your code will become a horrible mess... and then you will understand. :)

Collapse
vladned profile image
Vlad Nedelcu

on point :))

Collapse
luqman10 profile image
Abdul Qadir Luqman

lol. That's the most efficient answer.

Collapse
robcthegeek profile image
Rob Cooper • Edited

There's a few things - but first I'd say this:

When you're starting out - worry a LOT less about such things. Simple-to-understand, working code should always win over complex designs. Architectures are opinionated, have inherent pros/cons/trade-offs and you can really paint yourself into a corner.

That out of the way - here's why they are useful/important:

  1. They have pros (and cons). This needs to be said up-front. There can be unfounded/unfair hate for some patterns. Classic is the monolith. Each pattern has pros/cons and they should be evaluated. Example: Monoliths are great for a single engineer hacking like crazy on fast-moving project. Don't be a hater - be an engineer and pick what's appropriate for the task 😉
  2. They give the team a common language. If I say "MVC" to an engineer - they already have a visualisation forming in their mind about what-goes-where. The same with software [design] patterns.
  3. They define what-goes-where in both code and hardware. This can make it a lot easier to organise the source code, but also the team, responsibilities, cost allocation etc.
  4. They help with convention over configuration. Configuration is bad (generally) it means someone needs to do something. Conventions (that are well-understood - like those in patterns) are good. People expect X and it just happens. Magic! ✨ Examples are auto-routing and resolution of views in MVC. Gone are the days of mapping - most frameworks do it all automagically.
  5. They're tried-and-tested. They work! People have refined them over time, improved them, optimised infrastructure set-ups for them - this means you can have a bit of trust in them - without the foundation/backing knowledge.
Collapse
patarapolw profile image
Pacharapol Withayasakpunt Author

You are actually quite clear. Thank you.

Collapse
revskill10 profile image
Truong Hoang Dung

Software architecture is nothing without correct algorithms and data structure to solve business problem.

What you need first is not software architecture, it's your algorithm.
Then comes your data structure.
Then you might need a SQL database to keep your data consistent.

The last one you need "might" be a simple software architecture, like MVC. Most of framework out there can help you with that.

To me, principle is more important than software architecture. Use what best to your use case.

Collapse
alainvanhout profile image
Alain Van Hout

The problem with that approach lies is what is often seen as the succinct definition of architecture: that which is hard to change afterwards. That doesn't mean that you need to think about architecture from the very beginning, but as soon as you have a serious project, that project will need an architecture.

Collapse
slavius profile image
Slavius • Edited

MVC, MVVM, MVP are just a very small part of software architecture that applies to web applications with integrated backend/frontend, where Controller is the isolated backend task (like GetAllCustomers), Model is representation of data (coming probably from some sort of database) and View is the presentation layer.

In general software architecture is trying to make the code logically structured, isolated, easy to extend and maintain.
This results in code that does not repeat (you don't have to write and maintain the same logic in multiple places, where forgetting to update function that does something important in all places all over the project results in inconsistent or erratic behavior of the application).
It also tries to isolate and structure your code into domains where e.g. class CustomerRepository in a file CustomerRepository.java does only Customer related tasks so it is easy to identify within your project what goes where and where to search for it. This becomes more important once you start using Inversion of Control of some sort, like Dependency Injection where the dependencies are loose (they might be figured out at runtime not at compile time).
It also tries to form some sort of abstractions (for the same reasons mentioned above, where your isolated domain responsible pieces of code does not need to hardly depend on specific implementations). This becomes very useful during testing or running different environments (test, staging, production). You probably don't want your developers to upload files to your production storage from their development machines every time they run the code the same way you don't want to test some features together, like calling an API that deletes data from the database. For this reasons you'll impement Interfaces that just define how your object should look like and behave but you develop multiple implementations - one for production that does what it should in production, one for unit tests that deletes data from local SQLite database and returns the success result or just mock/fake that just returns true because your test is focused on running the API call, validate credentials, authorization, input parameters and produce valid response, but not focused on whether you can delete data from a database which you'd need to prepopulate before each test as response from the database trying to delete data from empty table would mess your test results.
Another goal is to make code extensible. Here again Interfaces really help as you can define an interface called IVehicle that implements typical vehicle features (length, weight, person capacity, etc.) and has typical properties. This can be used in places where you don't care what vehicle it is, like implementing a Highway class where any vehicle can ride on it. Then you can extend the IVehicle with IPersonalVehicle, IBus, ILorry which are based on IVehicle but extend it with different properties and functions (e.g. bool isLongVehicle, uint TrailerCount etc.) which you can use while implementing e.g. a highway toll gate where you have specific gates for specific vehicles and you cannot pass ILorry object type into PersonalVehicleTollGate() function because the parameter type does not match but still you did not have to implement basic functions of the ILorry object implementation over again because they are inherited from generic IVehicle interface. As you now have an PersonalVehicleTollGate() function and LorryTollGate() you don't have to write a big switch case or if (vehicle.type == Lorry) within your function. It also helps your unit tests to not depend on specific implementations but rather generic ones or to provide fakes/mocks as mentioned before.
Interfaces also allow you to swap implementations, e.g. you develop an app that stores files in Google Drive by implementing Google's REST API calls in appropriate places in your application. However you soon realize that there is a limitation of some sort and you need to swap for S3 storage. Ideally you'd implement an IRemoteStorage interface at the beginning with methods like Save(), Read(), Delete(), Search() etc. and implement class GoogleDriveStorage extends IRemoteStorage that abstracts the implementation. Then when you need to change from Google to S3 provider you need to develop another implementation based on the interface and just swap them in the application initialization where you register your new AmazonS3Storage as an implementation of IRemoteStorage interface in Dependency Injection container instead of GoogleDriveStorage.
The rest makes sure the application can be easily developed and maintained by multiple people at the same time.

Collapse
karandpr profile image
Karan Gandhi

Ehh. It just makes your life easier.
Think of it as a shelf or wardrobe.
You can dump everything inside it. Nothing wrong with that, but only you can find a particular item, and it's taxing.
If, however, things are neatly ordered, then you can find an item easily, and others can do the same.

Collapse
tdx profile image
Thien DX

By following standard pattern/architecture, you're sacrificing short-term dev time for the long-term.
Usually you create more classes or code to solve what seems to be simple at first. For junior, trick/hacked solutions always look better if they don't see the long-term benefit.
If design pattern is used efficiently, future you or your teammate can easily understand the code / identify issue, from a higher level rather than go through the code details.

Collapse
patarapolw profile image
Pacharapol Withayasakpunt Author • Edited

Actually, I'd look for benefit of

  • Make sense of my own code.
  • The code can grow
  • Well-tested for edge cases (and common cases)
  • Handling the code more than a few months, where I have forgotten some of the internals
Collapse
joaomcteixeira profile image
João M.C. Teixeira

You will naturally feel the need for soft arch as your projects start to grow and you become unable to control and maintain them unless you structure them properly 😄

Start studying arch calmly now, and don't rush. The need and frustration will point you in the right direction 😉

You will naturally go through many processes of learning... functions, oop, back to functions, back to oop, test-driven, test forgetting, back to testing, circular imports, CI, 'omg what was that pattern again?', over-kill implementations, etc.

enjoy the road, it's beautiful, I definitively love it ❤️

Collapse
copsbehindme profile image
Rohit Gupta

I know why, It applies to various reasons and some of them that you asked in your question. These are my two cents.

  • Its a good practice to split your code so that you can isolate the problem if it arises exhibit MVC :
  • When you have domain classes and services separately, you can easily test and diagnose them out if the need arises. Rather than reading the whole chunk of code, you could just simply enter the service file and debug some functions to save time.

  • As the code grows, a situation may arise that you need to deploy multiple systems dedicated to one and only one thing.
    For example background jobs that take a long time to run can be deployed separately and APIs Project can be deployed separately so that both do not eat up resources of each other.

  • While working in teams, Its a good practice to use VCS and the team will be happier if they have to work less on resolve conflicts on others code.

I hope others add their bit too.

Collapse
jaiminajmeri profile image
jaiminajmeri • Edited

Over time, when you learn to code by writing smaller scripts, programs, tools...etc you would realize how the operating system manages to run your program. You simply cannot write a program that does what you wish for unless you think like a computing resource. It pushes you to dig more about what you just discover. For example, it could be about the limitations associated with Memory, OS, I/O Buffers, or other physical resource limitations that you never thought existed. As a computer programmer, you are always bounded by such limitations.

Dealing with limitations is not an easy task, it takes time to think, implement, and validate the solution. Simple or Complex projects, both are bound to face limitations that we have seen in the example mentioned. When a system reaches it's limit the performance takes a severe hit.

Over the years, people (software engineers, computer scientists...etc) in the industry have identified methods to utilize these limited computing resources in an efficient way and solve problems that surface very often today. Be it in Operating Systems, Web, Device Drivers...etc the underlying principle or patterns are proven to work gracefully with such sorts of limitations.

When you understand the principle and apply it to the problem at hand you would realize that it easily solves some of the use cases that were not possible or hard to accomplish with your nascent naive approach. Of course, your solution will mature from a naive approach but it will happen overtime.

Collapse
rezaamini profile image
Reza Amini • Edited

If you don't have an architecture in your project, you won't be able to improve your code or refactor that easily and nobody can contribute to the project easily.

Collapse
patarapolw profile image
Pacharapol Withayasakpunt Author

That maybe a point; but how do I get started?

For example, Express.js (although I love Fastify much more, and couples of microframeworks in other languages); or Vue / Nuxt for the frontend (I never get accustomed to React / Next / Preact).

Furthermore, can I even expect contributors in the first place? I feel that fame / usefulness-to-others is hard to come by...

Collapse
jenbutondevto profile image
Jen

If you're learning to code at school/university etc, you will eventually have to do a group project. If you are starting a job, you will definitely either have to work with another developer, or work on an existing codebase..!

Thread Thread
patarapolw profile image
Pacharapol Withayasakpunt Author

Apparently, my course is Informatics, not really computer science. And there are a lot of other topics to focus on, anyway.

Collapse
zoedreams profile image
Collapse
patarapolw profile image
Pacharapol Withayasakpunt Author

Is the said "anti design" an absolute indicator, that the project will fail, or just in some ways?

Collapse
reyadussalahin profile image
Reyad Salahin • Edited

@patarapolw

Mostly, in software design you'd hear about anti-patterns(I haven't seen anyone using the term anti-design). The things you've described(MVC, MVVM etc..) are actually software architectural patterns, simply design patterns. Design patterns have been invented to solve common software problems, but of course, they are not universal solutions(they have pros/cons and trade-off). And anti-pattern means such design pattern, that creates much more of a problem rather being a solution, though at first it seems to be a great solution. Such an example is singleton pattern. Actually, it's still encouraged in many cases, but single pattern causes a lot of problem in terms of code maintenance and testing.

Of course, you'd hear about software architectures too, such as monolithic architecture, microservices, service oriented achitecture i.e. soa(actually microservices is a kind of soa) etc...

It's always good to learn design patterns and software architectures...but take your time to understand and apply those :)...

Collapse
zoedreams profile image
☮️✝️☪️🕉☸️✡️☯️

Not necessarily. But it will make a project look amateur verses AAA.

When I interview I specially test others foe their ability to understand identity anx mitigate anti design. Anti design patterns are what causes bugs and technical debt.

This is. One of my favorites

en.m.wikipedia.org/wiki/Big_ball_o...

I high suggest learning and knowing to avoid these. They will make you a much better programmer.

Collapse
sandordargo profile image
Sandor Dargo

Because of the same reasons why you don't start building a house just by putting straws on each other randomly.

Collapse
phlash909 profile image
Phil Ashby

..which assumes one is building a house ;) If it's a temporary shelter for a night, a tent will do, or on a pleasant evening just a sleeping bag... I guess my point here is that it really helps to know where a piece of software is going to use the right tools & technologies (including appropriate architecture!). Day #1 - attempt to understand the problem it will solve or new idea it will express; day#2+ - iterate to find out if that guess was right, guess again, re-select tools & technology (yep, these evolve along with the snowball of code); day#N+ - nuke from orbit (failed idea!) or keep evolving, just ahead of the point of collapse (welcome to just-good-enough commercial code)...