No, ease of testing is one of the reasons for OO adoption, and probably the primary reason software is much more stable than it was in the mid 90s.
> Many of those higher-level classes are “polluted” with methods and properties that are only relevant to a small number of subclasses.
Well, then it's broken and needs to be refactored.
> During my last couple years working at Google, I created a new user interface toolkit called “Quantum Wiz”
Of course, in true Google style, you wrote something from scratch instead of refactoring the old.
> composition > inheritance
Not a new finding. I learned this in 2000, at the peak of OO craze.
> Because object oriented inheritance is about organizing things into classes, it doesn’t model the real world very well; what it does model well is the way humans think about the real world.
That's the idea. Good software is written for the simplicity of those poor slobs charged with maintaining it -- often ourselves a year later.
> A physical object has many uses other than the specific purpose for which it was built. I can use a coffee cup as a paperweight or a doorstop;
The whole idea of modeling is to remove certain details! Otherwise the model would be identical to the genuine article, and would provide no benefit.
Refactoring means the original design didn't handle change well. Refactoring is badge of disgrace, and should not be considered a standard practice any more than putting out kitchen fires should be considered a standard practice of cooking. One of the key points of abstraction is to make the code change-friendly. If you have to refactor, the code failed that job. Minor rework is expected upon new requirements, but complete structural overhauls should be avoided, in part because it can create cascading side-effects.
Re: The whole idea of modeling is to remove certain details! Otherwise the model would be identical to the genuine article, and would provide no benefit.
But in some cases OO-based modelling becomes awkward or forced. Does the action of "gluing" belong with the glue or with the object being glued (fixed)? We can force it to be with one or the other to satisfy "OO rules", but that doesn't necessarily mean it's a good model. It's a forced model.
Re: [article] it doesn’t model the real world very well; what it does model well is the way humans think about the real world.
It doesn't model all thinking well. For smaller sub-systems it's fine. But OOP seems to get messy and tangled on a larger scale.
You are taking the idea of refactoring to an extreme and then attacking it. Refactoring != complete structural overhaul (at least not always), and it certainly shouldn't be a badge of disgrace. It's a perfectly reasonable and acceptable practice to write code to make something work that might be kludgy or not so clearly written with the intention of refactoring once the overall solution is in mind. Programmers don't always have the luxury of designing it perfectly before implementation. That's just unrealistic in today's market.
Being bad at refactoring will only make the experience more painful. Same with unit tests. Same with deployment. Same with pretty much everything.
> Refactoring means the original design didn't handle change well. Refactoring is badge of disgrace
I'm not sure how you intended this, but this reeks of shame-based project management, which is a bane and a scourge of the industry. Get out of here with your failure talk. You're spooking the natives.
I can only grant you the benefit of the doubt and assume you aren't quite using the word the way the rest of the industry does.
Replacing two similar code fragments with two calls to a single method is an example of refactoring. In no universe would that ever be considered any sort of kitchen fire.
For instance, working with language like Kotlin or C# it's fairly straightforward to get the best of both worlds: Use inheritance where appropriate, favor composition in all other cases.
IMO being dogmatic about not wanting inheritance altogether will result in friction as well: The fact that Rust eschews inheritance altogether will increase boilerplate whenever you want to do something that is 'inheritance-like'. Sure, people will argue that in 90% of the cases this is bad design, but for the cases where it IS the best approach it's a shame it's not part of your toolbox.
If the tide is turning against ORMs, it probably has a lot to do with the rising love for fp that this author covers. Languages like SQL are declarative, as is fp, so that approach feels more natural to people these days.
As an alternative, use stored procedures with Dapper, or use smaller sub-helpers that prepare most of the SQL statements or sub-statements for you but don't outright hide it. They assist in creating SQL (and prepared statement parameter mapping), but only assist, and are kept to less than a few hundreds of lines of code.
Other dark-grey-boxes include URL route mappers, seen in MVC stacks, and HTML formatters, such as Razor. When they don't work right you'll waste many many hour fudging with them. I'd often rather replace the URL router with Case/switch statements: it would be easier to debug; so what if it's a bit more typing. It's a white box.
I understand using Dapper. It is exactly what I want in an ORM. But I've yet to see anyone make a convincing argument for using stored procedures over using parameterized SQL.
ORM or not, there's going to be a clear spot in the code where any mismatches between the backend and the frontend will be found. Or you're going to play whack-a-mole forever, and ramping up new employees will be a strain.
Luckily, the rising popularity of Swift, Kotlin, and Go, will push for a more reasonable use of OO in combination with FP.
I agree. Events typically have to "belong" to something in OOP, but how they are best grouped or managed may not fit a single-item belonging-ness.
I'd like to see languages which are flexible in how events are organized in file systems. Their file grouping wouldn't have to reflect some object hierarchy or odd code structure, it would be organized how a team wants. Conway's law. A "header" would define the criteria for triggering. You could have wild-card based triggering and expression based triggering. wild-card triggering would be more efficient and orderly, but one needs expression-based triggering for certain circumstances.
Perhaps manage all those event handlers in an RDBMS. But our existing tools and IDE's are file-centric when they should be looking to be RDBMS-friendly. When you are dealing with thousands of fairly-similar things, such as event handlers, it's time to think about databases, not files and folders. OOP and files/folders don't scale very well.
Windows management systems. Everywhere. OOP works like a charm.
Also, all that stuff you are saying about "expression-based" triggering, it exists and working fine...
Also you are mixing OOP with files and folders and I can't understand why...
The rest of it it's completely mistaken. The writer has no clue about OOP.
Let me tell you the problem with OOP. Everybody said "use objects" you will re-use them over and over, not only for this project but projects in the future as well.
But we already have libraries and I still yet to find someone (or enterprise) reusing its own code.
Every respectable programmer knows he must refactor his old code again because it's not so good anymore.
When you consider that UML tends towards object-oriented modelling of systems, it is practical to consider the methods as the action semantics of the model.
For many people, that kingdom of nouns lives in their brains. I'm not saying I agree with this entirely. I don't even think I'm saying we shouldn't fight it - I certainly have felt the pain of people wanting to pigeonhole me at work by noun instead of looking at what verbs I'm capable of.
But it's out there, and you don't have to look very hard to find it.