Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Example of abstraction vs indirection:

If I said 'User', we both know exactly what that means. It's so semantically simple that laypeople know what it means. But our implementations could vary wildly. Someone who's just taken Java 101 will be thinking of a class with getName() and setName(). But someone who's just taken SQL 101 will think of a User as an INT or UUID, where features are added by referencing that user's id from different tables. User is abstract because it's understandable and not locked into any particular implementation.

I love Kafka. But it's a PITA to program against, at least in Java. I cannot code directly against it and always need to make my own wrapper classes to construct and poll it. I'll make ResumingKafkaReader and RewindingKafkaConsumerFactory, etc. These are not abstract, because they are very specific about what and how they do things. They are concrete behaviours wrapped with 1-2 levels of concrete indirection.

However, I might inject one of my Kafka indirections into a business logic class, interfaced as a Supplier<User>, which makes it abstract. I can then unit test my class, safe in the knowledge that my class cannot know if a User came from Kafka or just a test stub.

So I push back on the thesis of the article, and double-down on doing things abstractly first and foremost. This is closely related to the dependency inversion principle. Write (and test) your business classes around Users and other abstract things. Once you've done it wrong a few times and eventually gotten it right, then you can start writing the indirections (e.g. AbstractKafkaFactory) which the article rightly claims slow you down in the beginning.



Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: