Also, "doing it right" is an illusionary dream when your software interacts with the real world. In my opinion, it is not true that most code complexity comes from being lazy about code structure and simply not caring whether "models know about my views or not". This might happen sometimes but is usually easy to fix. It makes up a small percentage of code complexity.
There is an impedance mismatch between the way computers work and the way the real world works.
Software works in clear conditionals, numbers without any uncertainties, events that flow deterministically based on relatively simple rules.
The real world works in probabilities, half truths, imprecise numbers, special cases, partial information, irrational actors and deliberate rule breakers.
When you start writing a new piece of software, at first you tackle the most common cases of the real world. At this point it is possible to write clean code and well defined abstractions. However, eventually you are going to get users that will find that your software is too simplistic and doesn't take into account common sense exceptions, doesn't give them enough flexibility to deal with partial information and doesn't allow them to act according to unwritten exceptions to the rules. You have two choices. Either refuse to bend your software to the real world to keep code simplicity or start coding in the exceptions that your users desperately want.
Computers don't understand common sense so you have to translate all these exceptions into well defined rules and heuristics even though this does not reflect how things work in reality. Because computers don't think probabilistically, these heuristic tend to be numerous and complexe and difficult to deal with.
The main jobs of programmers in my opinion, is to manage this complexity so that their programs don't become too unpredictable when the thousands of exceptions interact together in unexpected ways. It's quite the balancing act but I think the best developers are those that don't back down and are able to face these types of problems. Sometimes this means refactoring some exceptions out of the system, or moving it somewhere where it doesn't cause unwanted interactions but sometimes it means leaving it in and managing it as best as you can so that your software can deal with the world as ambiguous and fuzzy as it is. A developer that ignores the fuzziness of the world in order to write clean code, is naïve and ineffective in my opinion.
There is an impedance mismatch between the way computers work and the way the real world works.
Software works in clear conditionals, numbers without any uncertainties, events that flow deterministically based on relatively simple rules.
The real world works in probabilities, half truths, imprecise numbers, special cases, partial information, irrational actors and deliberate rule breakers.
When you start writing a new piece of software, at first you tackle the most common cases of the real world. At this point it is possible to write clean code and well defined abstractions. However, eventually you are going to get users that will find that your software is too simplistic and doesn't take into account common sense exceptions, doesn't give them enough flexibility to deal with partial information and doesn't allow them to act according to unwritten exceptions to the rules. You have two choices. Either refuse to bend your software to the real world to keep code simplicity or start coding in the exceptions that your users desperately want.
Computers don't understand common sense so you have to translate all these exceptions into well defined rules and heuristics even though this does not reflect how things work in reality. Because computers don't think probabilistically, these heuristic tend to be numerous and complexe and difficult to deal with.
The main jobs of programmers in my opinion, is to manage this complexity so that their programs don't become too unpredictable when the thousands of exceptions interact together in unexpected ways. It's quite the balancing act but I think the best developers are those that don't back down and are able to face these types of problems. Sometimes this means refactoring some exceptions out of the system, or moving it somewhere where it doesn't cause unwanted interactions but sometimes it means leaving it in and managing it as best as you can so that your software can deal with the world as ambiguous and fuzzy as it is. A developer that ignores the fuzziness of the world in order to write clean code, is naïve and ineffective in my opinion.