I think that there is a middle ground to be found in this aspect of development. On the one hand, you don't want to overengineer your code. On the other hand, requirements will change.
Based on this, I personally design object models to be easily extensible. The guidelines are simply best practices (separation of concerns, methods which only do one thing, minimising side effects as much as possible). Nonetheless, I agree that the minimum should be used given that things which should be abstracted have been abstracted.
For example, I was implementing reports recently. Overengineering is coming up with a complex reporting engine which managers can use to create anything they want. Underengineering is writing each report from scratch. The golden middle, in this case, was a lightweight framework where you extend a base class, specify the query and you're done. Everything else is automagically taken care of. So one need not worry about fetching the actual results, displaying them, sorting them, adding the report to the menu, etc.
Based on this, I personally design object models to be easily extensible. The guidelines are simply best practices (separation of concerns, methods which only do one thing, minimising side effects as much as possible). Nonetheless, I agree that the minimum should be used given that things which should be abstracted have been abstracted.
For example, I was implementing reports recently. Overengineering is coming up with a complex reporting engine which managers can use to create anything they want. Underengineering is writing each report from scratch. The golden middle, in this case, was a lightweight framework where you extend a base class, specify the query and you're done. Everything else is automagically taken care of. So one need not worry about fetching the actual results, displaying them, sorting them, adding the report to the menu, etc.