Hacker News new | ask | show | jobs
by ChrisMarshallNY 1620 days ago
Well, this is one of those "yes and no" situations.

The biggest argument that I hear against OO, is that "someone may misuse or misunderstand it."

I feel that this reflects the tech industry's obsession with hiring armies of relatively inexperienced developers, and then cycling through them, because we don't do what it takes to retain people.

I like composition. I use it often. It is not a "one size fits all" solution to anything; just like OO isn't.

"Reduce state" is another big rallying cry. Good advice, for algorithms, multithreaded service providers, and engines. Not so good, for UI, and, in many cases, device control.

I have spent the last couple of days, working on the login screen for the app I'm developing. It's loaded with state. That can't be avoided, and negotiating the several different states that this -seemingly- innocuous screen can have, is not for the faint of heart, but it needs to be done right, because it's the first screen our users see. It also optionally implements Sign In With Apple, which brings its own baggage. The users' experience must be absolutely frictionless, while also being very secure. The work has involved the server (PHP), the SDK (Swift), and the app, itself (also Swift). I'm not done. I keep uncovering corner cases.

I'm just not a fan of "Don't use X, because X is bad, and you're a bad programmer, if you use X." The tech industry has been dealing with this, since the GOTO wars.

Most of my projects are a hideous chimera of decades-old techniques, mixed with cutting edge stuff.

If someone wants to work on it, then they need to have their stuff together. I'm not going to "dumb it down," but I need to do a lot of documentation (I write about how I document, here: https://littlegreenviper.com/miscellany/leaving-a-legacy/).

Here's an interesting thing that happened to me, some time ago, and I decided to write about it: https://littlegreenviper.com/miscellany/swiftwater/the-curio...

2 comments

> I feel that this reflects the tech industry's obsession with hiring armies of relatively inexperienced developers, and then cycling through them, because we don't do what it takes to retain people.

That is true (and it won't change, so we need to behave like it won't...), but that is not the only reason.

An inheritance hierarchy in a large program that makes sense today might not make sense in a year or two. Refactoring it is hard. Refactoring a composition-based solution is easier.

Composition-based solutions are also easier to test: inject mocks. It's a lot easier to mock a compositional dependency than it is to mock behavior that's inherited from a parent class.

Given that composition is easier to maintain and test, and that it can achieve the same functionality as inheritance, I've pretty much stopped using inheritance. And I write Java 99% of the time.

I write Apple UIKit apps. I am looking forward to using SwiftUI, which is designed to afford use of Protocol-Oriented Programming, reactive/observer stuff, and a lot of lower-state stuff. I think it would have made the work I've been doing in the last few days, much easier.

But if you use UIKit, then it's fairly important to use classic MVC (not MVVM), as that is what the SDK was specifically designed for. Trying to coerce it into other models just causes a lot of extra pain and complexity.

Also, there are models that have been specifically designed (I won't talk about which), to introduce extra complexity. These are made to allow a design to be "broken up," so that parts can be assigned to different developers.

> and it won't change, so we need to behave like it won't...

I sincerely hope that you're wrong. It's been an unmitigated disaster.

It’s possible (and IMO enjoyable) to write UIKit apps with ComposableArchitecture, a purely value-typed approach. I’ve also mostly used MVVM with UIKit since 2015, and found my apps to be stabler and easier to maintain than standard MVC apps.

In projects I lead I’ve been discouraging inheritance because I’ve found it highly detrimental to maintainability. “Base” classes invite bloat and overgeneralization, especially with inexperienced devs.

Isn't TCA a dependency framework?

I haven't found much joy in MVVM. I haven't found that it provides enough benefits to spend the time switching over.

I am looking forward to SwiftUI. I really hope that the documentation improves, though.

> Isn't TCA a dependency framework?

It is but it's quite straightforward to build your own simpler version using only Combine - that's what we're doing at the moment and it tends to work very well, interacting with Core Data has been kind of clunky though.

> I am looking forward to SwiftUI. I really hope that the documentation improves, though.

I've been on a project using it for the last 8 months both for macOS and iOS, I would honestly not rush into using it anytime soon. It's improved significantly since release, especially if you can target the newest iOS but requiring that is a hard-sell for most. On the Mac it's a different story and is much more neglected, macOS versions also tend to have far longer tails than iOS so it's a non-starter to try and sell a Monterey-only Mac app.

Edit: rereading my comment it sounds like I'm really down on SwiftUI - which I'm not, I think it's great when it works but there's a lot of rough edges at the moment and also quite a lot of hype.

If you are using TCA only for dependency management, I’d suggest to reconsider and put all business logic in it. In my experience, most serious efforts of wrangling SwiftUI into a complex app wind up with a solution that’s similar to TCA.
TCA is a Redux/Elm-style data and state management lib that aspires to handle an app’s complete business logic, preventing devs from mixing the logic into the UI layer via SwiftUI’s @State and @StateObject. And contrary to Redux, it’s completely type safe and aware of deep component nesting (sub reducer states and actions are “pulled back” into their parent reducer pendants), so it allows truly composable components.

If you haven’t checked out PointFree’s content (authors of TCA among many other things), it’s one of the best resources on Swift and algorithms for sure.

Thanks, both of you, for the explanations.
While inheritance can certainly work, especially in terms of UI development, the issue is when you are talking more abstract concepts. At that point, it can become really hard to figure out the right lines for what should be inherited vs composed.

In my experience, poorly composed code is simply easier to understand than code which poorly applies inheritance.

For me, inheritance is best used lightly. The obvious smell is when you end up with methods that don't apply to all the base classes. Or, said another way, when a super class it has a superset of capabilities for a base class.

A good example of this is Java's collections, which, for the most part, are quite good with their inheritance. However, because the base classes have mutable methods, it makes it a pain to deal with unmodifiable collections. Java's mistake is they should have had the default collection be unmodifiable and had sub classes which added mutation capabilities. List and MutableList, for example.