3

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.

  • @gnat I wouldn't say they have lower skills. It's more about the level of satisfaction. "It just works" is not sufficient for me. If I feel much unnecessary and routine work is done I try to eliminate it. For me this is just an indication of bad solution. For others following standard algorithm adjusting it here and there for current task is fine. And to be honest they are faster. – Pavel Voronin Dec 23 '15 at 8:18
4

From the tone of your post, I'm going to guess that you lack empathy and flexibility. You're aghast at your teams' reaction, which suggests you can't imagine why they might feel the way they do. That's rough. It's going to be hard to implement change if you can't project yourself into their point of view.

Regarding flexibility, think about these statements:

  • "...setting access modifier of a classs to internal instead of public"
  • "...constructor injection instead of indeed incorrectly but widespread used property injection" (my emphasis)
  • "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?"

I would respond:

  • While internal is better than public, it's still a bit dubious since internal is simply public local to the assembly. Many languages don't even both with it. So, did you break someone's code by changing access to internal? If not and they're simply uncomfortable with it, is this really an issue you need to champion? Do you want to burn up goodwill on something so trivial?
  • It's fine to have an opinion on constructor versus property injection and I might even agree with you. But I'll let you in on a secret: no where is it writ in stone that property injection is incorrect. That's just your opinion. Again, an opinion that I happen to agree with, but still an opinion. Please treat it as such.
  • Yes.
  • Yes.

All this boils down to a couple concepts. First, from my man André Gide:

"Trust those who seek the truth but doubt those who say they have found it."

You have strong opinions, that's great. Other people have opinions too. Please recognize them for what they are. Software development is beautiful and complex and weird, but it's definitely not black and white. You don't know the best way to do things. Not because you're dumb or wrong, but because it's impossible to know the best way to do something in such a subjective practice. If there was a "best way", best practices wouldn't be such a moving target. Think about how much things have changed in your career!

That's not to say we shouldn't strive for perfection. We should. But it's precisely because it's an enterprise that's doomed to fail that makes it so beautiful. (Kinda like human beings are beautiful because they're doomed to die.) So, what's the biggest requirement for teams who are striving for perfection? It's communication. That's the second concept; be an awesome communicator before you're an awesome programmer. Because to be honest, you can't be one without the other. (Unless maybe you're developing something completely on your own like TempleOS.) Any time you change a process or tool: communicate. Any time you significantly rework someone else's code: communicate. Listen to your spider-sense. If you sense someone will get annoyed, communicate.

With humility, a hunch for what's best, and good communication, you can make the changes that are best for your team.

  • Thank you for the answer. I agree with most of you say here with one exception (a bit offtopic). I think we as developers should do our best to 'move' things from subjective to objective area. For example I won't be surprised if rigorous research reveals that there is only one really good code style for a given programming language...or may be different styles fit better for various mental models? Who knows. I like his arguments. Yes, they are still an opinion; opinion which calls for research. – Pavel Voronin Dec 23 '15 at 16:04
  • internal is simply better because it does not clutter intellisense =) That's why I (!) prefer (!) to start private members with underscore. But unfortunately this goes against our code conventions, and we don't use this style. Furthermore, it required almost 1.5 hour discussion to set the limit of the code string length to 130. Everyone has at least two wide monitors....but when you need to see a side by side diff..}:-> – Pavel Voronin Dec 23 '15 at 16:11
1

Make sure you only refactor in places of your code base where you have a reason for changing it which is comprehensible for everyone in your team (a reason like adding a new feature, fixing a bug, or improving performance). Use that occasions to improve the design, do not improve the design just for the better design's sake. That makes it much easier to justify design improvements against the rest of the team.

Refactoring is not an end in itself. When you write "And to be honest they are faster", that gives me a big warning sign. When refactoring does not help you to evolve your software faster, at least in the long run, then you are refactoring too much and your colleagues are correct.

1

You're thinking in terms of a programmer, and rightly so, but there are other aspects to take into consideration.

  1. Refactoring code is costly. It is true that you're already dedicating your time to writing to code, so why should it be a cost if it is only meant to help the project? Well for one, it isn't helping the project unless it is a calculated and deliberate effort. If you go against the flow of your project, you're not helping despite what you think to the contrary. And either an enormous effort with no immediate gain has to be made to push it forward or an enormous effort with no change has to be made to restore it to its original glory. All of this brings no external benefits to the project and thus is very hard to justify to one that doesn't program at all (aka the project manager's boss who's quite possibly paying for all of this development).
  2. Consistency is key. This somewhat falls in line with the above comment, with emphasis on what it means to have consistent code and inconsistent code. On one hand, code corrections are straightforward, at least from the perspective of where to insert it in your program, and at least nobody can say that it's not orderly. That isn't to say that it is ordered to your standards, but that is irrelevant. Consistency has its own value. An inconsistent project is a nightmare to work with. Despite having some possibly positive merits with some techniques, it is like having poo-flavored sprinkles on your ice cream. Nobody wants something that's a mix of good and bad components.
  3. Your role is advisor when it comes to technical decisions. You're right to want the technique to change, and it is, in fact, your duty as a programmer to at least present it as a possibility. That said, not everything is black and white, and other programmers will disagree with you. Take it with a grain of salt and know that it can be you every once and a while the one who is in the wrong. It would be incorrect to stay silent and even moreso to impose yourself on your colleagues.

The best way to test a technique is to practice. It isn't sufficient to hear some buzzword and try to apply it to your program. If you're not confident with that technique, then you shouldn't propose it to your colleagues at least until you're sure it fits your program, and unfortunately the only way to know this is to use it in other circumstances. Work is no place to test these techniques, but you can write projects at home and test your techniques there.

My advice is to treat your fellow programmers with respect and respect will be likewise given. If you think something is worth mentioning, mention it in earnest and they will listen. Also don't take it to heart if they decide not to adopt your approach. It is still only business afterall.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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