TL;DR
What are the good practices of iterative search of a better solution?
Well, if I knew everything in advance and could immediately suggest 146% correct solution for a given context, I'd probably be the richest man in the world, but definitely I am not.
Thus some space and time for experimentation is needed.
In case of approaching some new technology or framework it's quite reasonable (if you have time for that) to create small prototype project specially for the purpose of testing its capabilities and exploration of caveats.
On the other side, changing architecture is more about how code is written and refactored. It's more about the system's evolution, ease of development and augmenting the product with new functionality. So I believe that these kind of changes is somewhat difficult to verify if abstracted from the real world development use cases. I also have doubts that business allows parallel development of several versions of the product just for developers could find better solution.
I see no other way but introduce changes while developing new features.
After several iterations stabilization is achieved and solution gets polished. But then system becomes a good example for Lava antipattern: you have several slightly differt approaches (Refactoring is to the help). Not surprisingly some teammates are going mad without clear understanding HOW should they do.
I do not want to constantly think how I should do this, I just need to complete the task. We have conventions, I get used to it.
That's what I hear quite often from a teammate.
Actually even setting access modifier of a classs to internal
instead of public
, or decision to use constructor injection instead of indeed incorrectly but widespread used property injection, or using Trace.WriteLine
can cause the same reaction.
So the relationship with some of my teammates is worsening, and I don't want it to happen, but the same time I hate to do things in a way just because everyone got used to without questioning myself whether better, more correct solution exists. Yet I understand I am not perfect and inevitably make mistakes sometimes.
The claim of PM is that I do not initiate a discussion. But should I really ask for permission not to use Copy-Paste development and extract setup logic of the test?! Should I discuss whether I may use test data generator like Autofixture?
More recent example:
I finally could express what I strongly didn't like about our code. Our Get
is developed both for the needs of UI and subsequent validation while updating; thus we reuse the entity (completely anemic model) returned by the Get
when performing an Update
. So whenever we need to change what we show in UI we also 'toutch' Update
functionality. At least this requires to change unit tests.
I decided to check my guess and extracted query logic into another class and made this class not accessible by business rules where only command processing logic leaves. I also put validation logic inside the entity.
The reaction of a reviewer?
What the heck? Are we moving to CQRS? Have we discussed it? We do not use logic inside entities. Why query is merged with Db access logic (I simply return projections from EF query)?
Could I do better?
Face to face discusson showed that majority of the team considered this approach worth trying though without being completely sure it brings dividends later. And few members was strongly against it stating that reuse suffers, and get-logic is going to be somewhat duplicated if we need data from other entities (aggregates).
The best way to test the hypothesis is practice, isn't it?
The feature is isolated and still under development, and requirements for UI and functionality will change for several iterations. Al said allows to test safely the assumption about more stable codebase with this approach. Nonetheless, those who were against demand it to be refactored back to conventional solution.