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

Designing abstractions to be as general as possible, with interfaces as simple and clean as possible, and minimizing coupling, makes it much easier to think about how the major components of the system interact.

I think this is a false statement. In fact I think you're confusing modularity with abstraction.

Abstraction hides complexity, and abstractions are leaky; how the whole behaves can be strongly influenced by behaviours that leak from the abstractions. It took a couple of goes, but eventually we realized that DCOM and CORBA were poor ways to design distributed applications.

Abstractions should be as general as necessary, where necessity is subject to judgement.

Make code too abstract, and people may not understand it because it's not concrete enough, full of indirections and compositions and factory-factories; make it too concrete, and people may not understand it because it's too complex.

Creating an abstraction to share some code may pay off if there's sufficient clients for the code and they all have a similar usage profile, but it may be a false economy if the clients are few or the usage varied.

Modularity isn't an unalloyed good either. Too many modules and you may write code that acts optimally in a local way, but suboptimally globally because it has no access or awareness of other modules' behaviour. Modules designed around an abstraction may be substituted, but designing for module replacement is more often than not over-engineering. It's strongly encouraged by modern OO testing approaches, but IMO it puts the cart before the horse.

I'd like more people to realize that abstractions represent unknowns, and that any given implementation needs to be tested in an engineering materials sense, to find out what its force limits are, how it reacts under scale and pressure, so people using the abstraction are not just thinking about the abstraction, they are considering the real thing they're dealing with as well. It saves a lot of time going down dead ends.



That we're not all programming in machine code is evidence that some abstractions are useful.

The most vital abstraction is that most software is blithely unaware of the physical construct embodying it.

Abstraction isn't the enemy. I think much of what we call good "software engineering" is identifying, designing, and implementing the "right" abstraction.


I'm not sure I understand what you're saying, but it's also not clear to me that we really disagree.

Abstractions are often leaky, yes; sometimes unavoidably so, and then those leakages have to be taken into account in the design of the system; but when leakage is avoidable, do you not agree that it's important to avoid it?

I do agree that there's such a thing as over-abstraction, and over-engineering in general. I recall a discussion here on HN, oh, probably 2 or 3 years ago if not more, where somebody said they had written an app and then hired a programmer to maintain it, and the programmer started by "enterprisifying" it, adding lots of dependency injection and factory-factories and suchlike, rendering the code almost unrecognizable to the initial developer. Without having seen the code in both "before" and "after" states, I can't form a firm opinion about whether this was really an improvement, but I could easily believe that it was not. Certainly if I were the initial developer, I would want to know specifically what the benefit of each of these changes was expected to be.




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

Search: