>> The future is pretty irrelevant, so asking to design based on future requirements is uncanny.
The future is irrelevant? That's exactly what design is for -- to protect you from the future. If you didn't care about the future there would be no need to design at all.
A good way to evaluate various candidate designs is to imagine future use cases and ask which design holds up better. A good design will respond really well (ie., require fewer modifications) to novel use cases. Many people think this means design starting with future use cases. But you really just need to design with good principles. Future use cases are useful however at objectively evaluating designs and resolving arguments, such as Which design is better for futures that we care about?
>> Stating that "binding business rules to persistence is asking for trouble" is flatly wrong. Au contraire, It's the simplest thing to do, and in most cases any other solution is just adding complexity without justification.
Everything is a tradeoff. It doesn't make sense for many cases (hacking, etc) to avoid the simplest thing. But if you are building a project that's longed-lived, I can give you countless examples of how coupling business rules to model objects resulted in pain and copious paper cuts.
For me, I'll always decouple them. Why? Because it costs me nothing extra to do it and I have internalized the value in this principle from experience.
>>> Not all applications are big enterprise-y behemoths that benefit from Perfect 100% Decoupling™
You're right. It depends on how much you care about your future. Do you want your codebase to respond with agility to the future. Or are you okay with increasing your technical debt?
>>> Therefore, classes should be:
>> small enough to lower coupling, but
>> large enough to maximize cohesion.
Not sure I understand. Author seems to suggest these two are in contention with each other.
>>> Coding is hard and principles should not take the place of thinking.
Absolutely. There are many cases where the rules are to be broken. Systems with too much flexibility are just as bad as monolithic ones. It's an art what we do.
I think that putting cohesion and coupling on a 1 dimensional axis is kind of disingenuous. There are an infinite number of design changes that could be made and some of them increase coupling, some of them increase cohesion and all number of variations between the two variables. The best designs will find cohesion and coupling at local maximums.
I'm not saying you are wrong, but most of the literature indicates that high cohesion is correlated with loose coupling. The entire industry treats them as an axis so I don't think it is disingenuous for the author to do so.
I was a bit unclear: my general point is just that you can decouple code in ways that doesn't necessarily increase cohesion and you can decrease cohesion in ways that doesn't necessarily increase coupling. If you are designing a system with some rational interfaces and layers of abstraction, then most of the time you will find these two variables have a very direct relationship.
The most important rule about the future is that You Aren't Gonna Need It. If the future is known then it is called "requirements". Design is for protecting you from the unknown future: allowing code to be changed in arbitrary, unforeseen ways.
As for coupling and cohesion: if modules are too small, they usually lack cohesion ; if module are too big, they usually have high internal coupling. The sweet spot is in the middle. And you can create low-cohesion, high-coupling modules if you want :-)
The future is irrelevant? That's exactly what design is for -- to protect you from the future. If you didn't care about the future there would be no need to design at all.
A good way to evaluate various candidate designs is to imagine future use cases and ask which design holds up better. A good design will respond really well (ie., require fewer modifications) to novel use cases. Many people think this means design starting with future use cases. But you really just need to design with good principles. Future use cases are useful however at objectively evaluating designs and resolving arguments, such as Which design is better for futures that we care about?
>> Stating that "binding business rules to persistence is asking for trouble" is flatly wrong. Au contraire, It's the simplest thing to do, and in most cases any other solution is just adding complexity without justification.
Everything is a tradeoff. It doesn't make sense for many cases (hacking, etc) to avoid the simplest thing. But if you are building a project that's longed-lived, I can give you countless examples of how coupling business rules to model objects resulted in pain and copious paper cuts.
For me, I'll always decouple them. Why? Because it costs me nothing extra to do it and I have internalized the value in this principle from experience.
>>> Not all applications are big enterprise-y behemoths that benefit from Perfect 100% Decoupling™
You're right. It depends on how much you care about your future. Do you want your codebase to respond with agility to the future. Or are you okay with increasing your technical debt?
>>> Therefore, classes should be: >> small enough to lower coupling, but >> large enough to maximize cohesion.
Not sure I understand. Author seems to suggest these two are in contention with each other.
>>> Coding is hard and principles should not take the place of thinking.
Absolutely. There are many cases where the rules are to be broken. Systems with too much flexibility are just as bad as monolithic ones. It's an art what we do.