abc-1
9 months ago
Contagion is exactly why interfaces are one of the most important pieces of design and should be given significant thought. A beautiful interface with a suboptimal implementation can be easily cleaned up when time is allotted. The reverse is rarely true.
majormajor
9 months ago
I don't disagree but I think commonly you are missing one of two things that are necessary for a proper design:
1) time to design it 2) knowledge of exactly what it needs to do today and in a year
Sometimes you're missing both.
In which case I think you can prevent contagion from being too terrible by enforcing smaller modules and single responsibility in a compositional way. That doesn't require as much knowledge of the future or time, but just requires you to avoid high-surface-area interfaces that end up with lots of behavioral variants controlled via parameters in a nesting-doll style. Instead, move your config/parsing/behavioral decisions to the edges of your logic instead of letting them seep into all your underlying models too.
BobbyJo
9 months ago
> In which case I think you can prevent contagion from being too terrible by enforcing smaller modules and single responsibility in a compositional way.
I would classify that as thoughtful interface design.
njtransit
9 months ago
> 1) time to design it
Do good interfaces take more time than bad interfaces to write? Does adding more time really make interfaces better? I find that engineering quality (of which interface design is one facet) is largely a function of talent and experience. Time doesn't usually play a factor. Writing good code takes the same amount of time as writing good code, for the most part.
appplication
9 months ago
Agree, but I’ve found designing robust, future proof interfaces to be one of the hardest problems in developing software. Even intentionally setting out to avoid tech debt at all costs, it’s just hard to do correctly. It requires more than technical bravado and architectural vision. It really does get into the realm of predicting the future.
grues-dinner
9 months ago
> 15. (Shea's Law) The ability to improve a design occurs primarily at the interfaces. This is also the prime location for screwing it up.
mumblemumble
9 months ago
It's important to accept that you will screw it up. Repeatedly. Interfaces have to be designed before you can start using them, which means that you will never have less information about how a module will be used than you do when you design its interface.
The best defense against this that I've found is to ensure, as much as possible, that interfaces can be replaced. The single responsibility and interface segregation principles can help here. Using small, focused interfaces and letting modules implement more than one of them makes it easier to use the strangler pattern to replace interfaces that no longer work well with new and improved ones.
Also avoid temporal coupling as much as is feasible. Unnecessary statefulness is the easiest way to make this sort of thing harder than it needs to be.
grues-dinner
9 months ago
Mr Akin's gotchu, fam:
> 2. . To design a spacecraft right takes an infinite amount of effort. This is why it's a good idea to design them to operate when some things are wrong .
> 3. Design is an iterative process. The necessary number of iterations is one more than the number you have currently done. This is true at any point in time.
> 4. Your best design efforts will inevitably wind up being useless in the final design. Learn to live with the disappointment.
Also 9 10, 11, 12, 13, 14 and a bunch of the others apply too.
intelVISA
9 months ago
A good middle ground is modularize everything into stateless funcs where possible so it can be reassembled in different configurations without much stress.
An excellent interface will eventually be deformed beyond recognition chasing the architectural dragon; a well-crafted library will outlive the project.
abc-1
9 months ago
Look at how mathematicians build minimal yet complete definitions for inspiration. An algebraic system can be created with a set of operations such as multiplication and addition, and existing concepts can be mapped to this system, such as money, but the underlying algebraic system will never change. It is complete.
Much of the system can be complete like this with forethought. The pieces that cannot can be factored out to the edges.
appplication
9 months ago
You’re not wrong in a theoretical sense, but building useful interfaces that your average dev can grok enough to build on top of requires higher level abstractions, approximations, and “reasonable defaults”. My experience is that only a small number of devs actually well understand the codebases they work in (and care enough to be thoughtful in interfacing with it).
The majority of devs generally are happy to tack on their features and PRs to whatever random scaffolding they can, without regard or awareness for how their individual component fits into the larger system, or how it may be extended. And to be honest it’s not necessarily a bad thing, because they do need to get work done, and merging PRs shouldn’t be reserved for the enlightened.
I guess I’m just pessimistic. The reason we don’t see perfect software is because we are not capable of producing it. At a certain point it all becomes spaghetti. If you work with software that isn’t spaghetti, it’s only because the people who care about it not becoming spaghetti haven’t left yet. This is good, but eventually they will leave, standards will decline, and you will become one with the pasta.
hnthrow289570
9 months ago
You're not too pessimistic yet. Projects that devolved into spaghetti paid their engineers roughly the same as they will pay new ones. Looking at the incentives, it's hard to take on the burden of undoing technical debt if your salary isn't going to change much. Businesses take advantage of passions to fix things like technical debt because they know they don't have to pay too much extra for it.
abc-1
9 months ago
Keep fighting the good fight. It’s more satisfying, even if entropy inevitably wins ;)
pjc50
9 months ago
> forethought
Forethought is only possible if people tell you the requirements precisely correctly upfront. Real systems design is you get 90% built and someone drops a hard requirement that's also a layering violation on you.
AtlasBarfed
9 months ago
That is incredibly naive.
Math arises from first principles, human behavior does not.
abc-1
9 months ago
Consider how often SQL, a hash implementation, a data compression algorithm, or a standard library changes. Not often, because they are complete systems. If you don’t like them, you don’t change them- you switch to another system. But they can support an infinite variety of use cases. Hopefully that clears it up for you.
TexanFeller
9 months ago
One must understand what a good underlying implementation looks like to expose a good interface, it's easy to implicitly bake stupid implementations into an interface that cannot be fixed by just changing the implementation. The example that comes to mind is sorting and paging behavior. Junior devs, and many seniors that should know better by now, OFTEN start with requests that use some variant of limit/offset parameters for paging which leads to terrible performance issues and anomalous behavior. How paging works efficiently and what sorting options can be supported with good performance is inherently coupled to the shape of your data and your choice of datastore. People that haven't been through this exercise at a lower layer have little chance of shaping the higher level interface appropriately unless they put work into the implementation up front.
immibis
9 months ago
Another example is synchronous vs asynchronous I/O.
yodsanklai
9 months ago
Which is why I like languages that make interfaces very explicit, like OCaml or Ada. Most of the time, I don't want to see the implementation, just a properly documented interface. If people can't describe in simple terms the behavior of an interface, something is wrong.
taeric
9 months ago
History seems somewhat full of counterexamples, though? QWERTY is rather famous for not being an optimal physical interface. Steering wheels would probably be up there?
In computers, you have x86 being the poster child of ostensibly suboptimal interfaces.
TremendousJudge
9 months ago
QWERTY proves GPs point, it's a suboptimal interface and basically impossible to get rid of now, even though we've moved the underlying implementation from typewriters to computer keyboards to touchscreens
shiroiushi
9 months ago
Actually, I wonder if QWERTY is actually better for touchscreens than alternative layouts. In a better layout like Dvorak, the most commonly-used keys are grouped close together, mostly on the home row. This is great for typing because you don't have to move your hands and fingers as much and can reduce wrist strain. But QWERTY does the opposite, moving all the most-used keys to the non-home rows so you have to constantly move between the top and bottom rows. On a computer keyboard, this gives you RSI, but on a small touchscreen, this means the "keys" you're tapping on are generally farther from each other, so perhaps it makes it easier since you rarely tap on two keys that are adjacent.
taeric
9 months ago
Amusingly, I switched my phone to colemak. Mainly as I am just happy with the layout. Though, I confess I hate inputting anything on my phone, as I am not a good phone typist. I can almost make the swipe thing work, but I learned how to touch type on a keyboard and it feels very very weird to try and use a phone's keyboard.
taeric
9 months ago
Ah, if the point is just that you can't get rid of bad interfaces, I suppose that works. I was taking it more as a systemic problem caused by bad interfaces. Which is to say, I'd be hesitant to cede that this has caused any actual problems.
Would be like complaining that AC is being superseded by DC and how this is proof of an early choice locking us into a bad choice. But it ignores all of the progress made in the interim. And the odd reality that enough effort can migrate anything. It just takes a lot of effort. And we are often quite willing to throw effort at things.
InDubioProRubio
9 months ago
But contagion deforms interfaces. Its that moment in discussions, were everyone goes away from how it ought to be, to how we must implement it, due to the previously existing modules, you learn about that..
dogleash
9 months ago
> A beautiful interface with a suboptimal implementation can be easily cleaned up when time is allotted.
That won't happen. Why toy around with your ticket database like that? Just close it to WONTFIX.
user
9 months ago