5

I am aware that this might be a question with only subjective responses, but i keep coming back to this thought.
When you are designing a software's architecture, do you group components by their kind of task or their "theme"?

For the lack of a better example, if you have a lot file exports to do in your application where one is part of dealing with "billing" but you also have many other components who deal with this theme. Do you group them by the kind of work (which would be exporting here) or by their "theme" (which would be billing)?

Is there any objective way to determine when the one makes more sense than the other in certain scenarios? Not based on taste.

New contributor
Furious Gamer is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.

put on hold as primarily opinion-based by gnat, BobDalgleish, Thomas Owens 2 days ago

Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise. If this question can be reworded to fit the rules in the help center, please edit the question.

  • Define "valid." – Robert Harvey Mar 14 at 17:23
  • @RobertHarvey i changed valid to objective, is that better? – Furious Gamer Mar 14 at 17:29
  • Well... It would be better if you thought about what you want from a grouping. I personally like separating classes into similar code, but you can also study application architectures and take your lead from some of those. Application size is certainly a factor. – Robert Harvey Mar 14 at 17:32
  • Separation by "kind of task" is not a bad way to go. But it really kinda depends on what you want. – Robert Harvey Mar 14 at 17:33
  • 1
    To quote Juwal Lowy: "Separate by areas of volatility." – Nick Alexeev Mar 14 at 23:44
5

Generally, I prefer to start by grouping by "theme". A better name for "theme" is a bounded context. The idea is that code that changes together should live together.

To extend your example, say you have billing for both goods and services. You may think "oh, this is all billing, so they go together". This may not be the case, as they could have very different rules, invoice scheduled and so on. So you start with a services module and a goods module.

Later, you may discover that you're changing the billing code in both places. Then it becomes time to refactor these things into a common library. You've discovered a new theme - "billing".

5

How do you decide to group components in software architectures?

Good names.

I choose groupings of components that let me create good names.

A good name makes clear what belongs in a component and what does not. It ensures that people who look inside are not surprised.

When you are designing a software's architecture, do you group components by their kind of task or their "theme"?

For the lack of a better example, if you have a lot file exports to do in your application where one is part of dealing with "billing" but you also have many other components who deal with this theme. Do you group them by the kind of work (which would be exporting here) or by their "theme" (which would be billing)?

If you fail to separate the idea of exporting from the idea of billing what you're left with that knows about both is called a cross cutting concern. Organizing by either one is less than optimal.

The most common example is logging. If everything needs logging then logging code ends up everywhere. Ideally code that needs logging shouldn't even know it's being logged. Aspect Oriented Programming solves this problem by wrapping everything that needs logging without making you change a single line of the code that is being logged.

Now that's ideal but it's not always achievable. Sometimes you get your chocolate in my peanut butter. Sometimes that makes a mess. Sometimes it makes a nice chocolate peanut butter cup. Sometimes it makes a nice chocolate flavored peanut butter spread.

The difference is your organizing principle. As you organize think about a new programmer looking at your project structure trying to find something. What are you putting them through? How would you explain where to find it? If it's a long explanation you have a mess. Big enough and you wont be able to find it either. Which means you can do either but be consistent! Don't put peanut butter cups in a sandwich shop. Don't put spread in a candy store. Follow your organizing principle.

My own bias is for billing to be a large dominating idea while file exporting is a detail but that's cultural because I've worked in shops that had billing departments that had department heads who thought they were kinda important. I've never worked anywhere that had a "file exporting" department. But my career's not over so who knows?

I mention this because millions of people read these posts and this has to make sense to all of them. So for the people who work in places with file exporting departments rest assured I'll organize my code differently if you hire me.

The fancy term for this idea is Conway's law. Programmers are lazy so when we organize code we usually organize it to follow our corporations organization. Makes it easier to figure out who cares about what code.

Is there any objective way to determine when the one makes more sense than the other in certain scenarios? Not based on taste.

Nope. This is no more objective then choosing to speak English because everyone around you speaks English. It's smart. Not objective.

Not the answer you're looking for? Browse other questions tagged or ask your own question.