Pergunta

I am working on a project in which I am following clean Architecture from Google ... and for making code testable I am following an approach in which,I am creating a new

  • ViewModel Class
  • ViewModel Factory
  • Dagger Component
  • Dagger Scope

for every single screen which makes it independent from all other classes which is Good. But then it makes soo many classes and a messy Architecture which is I am not going to like, neither by someone else, if he\she see my project. SO, the question is, Is it good Approach to create everything separately? If not why ?

Here example of Architecture and every package contains multiple packages.

Foi útil?

Solução

The short answer

I expect that the predominant consensus to this issue is going to be in favor of separation as much as possible.

While I absolutely agree with the underlying intention of this consensus, I somewhat disagree on the degree to which it is (almost blindly) applied as a blanket rule. The rest of this answer focuses on the parts I disagree with, because that part of me also agrees with your question's assertion that excessive separation itself can start to feel dirty as well.

That being said, I am not arguing against separation. I am merely arguing against the blind application of any blanket rule.


Separation vs reusability

At the outset, I agree with you. I am not a fan of repeating the same thing over and over. I see many respected colleagues advocate for keeping everything separated, but I also see it happen to a degree where my job consists more of copy/pasting than anything else, which is the antithesis of reusability.
As I am typing this, I am in the middle of copy paste adding a new feature and I've literally created an entire enterprise feature (7 projects, including unit and integration tests) by copying files and replacing any mention of Foo by Bar.

But I do understand why it is generally recommended. Just because you may have two viewmodels now which happen to have the same properties/behavior, does not mean that these viewmodels will stay that way forever.
When you get to the point where you need to change one of the viewmodels, you notice the benefit of already having split everything:

  • If you had already created two separate viewmodels, you can simply adjust the one you need to adjust.
  • If you had not already created two separate viewmodels, you are now going to have to spend effort to separate them, after which you can start adjusting the viewmodel you needed to adjust.

Programmers tend to forget things over time, and if you did (or didn't) separate the viewmodels months before during setup, you may have forgotten parts of the application structure by now, which means that when you have to separate your viewmodels (now), you might struggle in making sure that you haven't forgotten anything anywhere.

The above paragraph clearly favors early separation, as it means you are performing the separation task at the time of setting everything up, which is the point in time where you have the best working knowledge (as opposed to the future where you will have forgotten things).

Gambling on future changes

It's essentially a guessing game: will these viewmodels grow apart over time or not?

In either case, if you end up being right, you put in the right amount of effort. No argument there. But when you're wrong, the consequences of being wrong are not comparable:

  • If you needed to separate the viewmodels and didn't do it; the consequence is that you have to wire and additional model, which can be a complex task.
  • If you never needed to separate the viewmodels but you did it anyway; the consequence is that you lost a fraction of development time copy/pasting two files.

The math is clear here. It's better to err on the side of separation because the consequence of being wrong is less time consuming than if you hadn't separated and were wrong.
But, and this is an important but that I feel many developers forget:

  • Separating everything means that you do this for everything (100%), as it is a blanket approach.
  • Not separating everything, and only separating them once you need to, can be done on a case-by-case basis (<100%).

If you only end up having to (late) separate 1% of your classes in the future, as opposed to having to (early) separate 100% of your classes today, that means that the math changes.
Early separation is clearly quicker than late separation. However, 100 early separations are probably not going to be quicker than 1 late separation.

The better choice here is the one with the least development time (note: do take code complexity into account here as it impacts the future development time).
There is no universally correct answer here. It very much depends on the complexity of your codebase and the odds of your expectation (needing to make future changes) being wrong.


To conclude

There are a ton of precedents for developers cutting corners and ending up with an unmaintainable mess of a codebase. It's a very common thing, and it's also the reason why good practice pressure on developers is so high. This is also the root of the "pro separation" argument: preventing unmaintainable messes and long development time on future maintenance.

However, erring too much the other way is also a problem, which isn't really given the same spotlight because it's a problem that doesn't directly affect developers (it merely increases development time, which is an issue of the product owner, not the product developer).

The answer, just like with all things in life, is to find the right balance. Don't blindly err on either side of the scales, because either side will introduce problems. Instead, look at the current situation, evaluate your options (taking past experience into account), and pick the option that has the smallest projected impact on total development time (which includes future maintenance!).

Do not blindly apply blanket rules. Always evaluate the applicability of a rule to your current context before applying it.

Licenciado em: CC-BY-SA com atribuição
scroll top