3 ms·
Conspicuously absent from this entire article is the word "abstraction". Oh, sorry, I just said a bad word, didn't I? We're not allowed to use the a-word aroun
by feoren 4y ago
Conspicuously absent from this entire article is the word "abstraction".
Oh, sorry, I just said a bad word, didn't I? We're not allowed to use the a-word around these parts, or people will think we're being enterprisey and chase use away with pitchforks. What am I, some kinda enterprise programmer?
I can see why doing an "extract to interface" IDE command in the messy situation TFA describes would (rightly!) get this reaction. Of course that's just adding more needless complexity to an already needlessly complex situation. But that's not what good abstraction looks like. For some reason, everyone seems to get it in their head that abstraction is supposed to be some sort of list of features you support. So you take each public class Foo and extract them to an interface IFoo and you have your list of features. Abstraction!
No. Good abstraction describes your needs. That's it! If your module needs to do something, but doesn't want to be responsible for the exact implementation of that thing, then you define an abstraction which describes that need. It will be implemented by whoever needs your module.
> You can choose between having modules A and B using a module C doing something, or have them do it themselves. What's your call?
A defines abstractions describing what it needs to do its job, and so does B. Since A and B have different responsibilities, these are two separate pieces of code, even if they look basically the same right now.
Now you have lots of options, and you can vary between them easily depending on what makes sense:
- A and B can implement the abstractions C needs, and then use C. So A -> C and B -> C. ("->" meaning "depends on"). The code exists in isolated corners of A and B so it can be moved easily later.
- C can implement A's and B's abstractions, so C -> A and C -> B. The code exists in isolated corners of C, so it can be moved easily later.
- Leave A, B, and C completely independent of one another. Write a small module ac, which provides implementations for A in terms of C, and a small module ad, which provides implementations for B in terms of C. Now you have no dependencies whatsoever between your major modules, and you've introduced small adapter modules that you can throw away later.
- Leave A, B, and C completely independent of one another. Your end application handles stitching them together (like above, but ab and ac are just sitting inside your end application).
> Rumors tell that [XParam's] original host project uses <5% of its features.
Let the marketing people think in terms of "features". You should be thinking in terms of needs. You can spend months implementing features that you don't need. It's much harder to implement a need you don't need. An that's what abstractions are: a description of what you need to do your job.
- Xeoncross 4y ago"The bigger the interface, the weaker the abstraction." - https://www.youtube.com/watch?v=PAAkCSZUG1c&t=5m17s https://www.youtube.com/watch?v=PAAkCSZUG1c&t=5m17s Abstractions are good if 1) they can't be any smaller and are 2) covering well understood processes warranting them.
- feoren 4y agoThat's basically right, but not really for the right reasons. What exactly does "smaller" mean? Rob Pike is saying they have few methods. We're kinda getting to the right ideas without understanding why. It still sounds like you (and Rob Pike, from the bit I listened to) are still thinking of abstractions as a feature list, and you're saying: instead of having one list of lots of features, have lots of lists of one feature. Okay, but ... we're still missing the point. It's not about features. It's about needs. How do you know whether an abstraction can be "smaller"? What does "smaller" mean? Smaller means: more generic and/or easier to implement. That is not the same as having fewer methods, even if that is often the result. An abstraction can be smaller if you can make it more generic, and/or easier to implement, and have it still do everything you need it to do.
- Xeoncross 4y agoAn interface must be a small as possible to fulfill it's purpose, no smaller and no larger. It's not about implementation, it's about the mental model of what is expected and why. Another way to say this is that an interface must be perfectly sized, but perhaps that is to abstract to be useful. Rob Pike mentioned few methods because that is the only thing that interfaces mean in Go - he might have used different terminology in another context or speaking about abstraction of systems instead of interfaces alone as abstractions.
- macintux 4y ago> Oh, sorry, I just said a bad word, didn't I? We're not allowed to use the a-word around these parts, or people will think we're being enterprisey and chase use away with pitchforks. What am I, some kinda enterprise programmer? What HN discussions have you been reading? I nearly stopped at this preemptive snark.