5 ms·
I've never been bitten by an interface that is too simple. I've never had a bug in code that I didn't need to write. Don't try to solve future problems. You'l
by cbanek 2y ago
I've never been bitten by an interface that is too simple.
I've never had a bug in code that I didn't need to write.
Don't try to solve future problems. You'll have the problem that the problem you solved isn't the problem that needs solving, and then the problem that needs solving.
If anything, overly simplistic solutions sometimes make me feel like I'm repeating myself, but really since the code is so easy it always feels possible to refactor it. That's a good place to be, much better than afraid to change something because it's too generic to know if you'll break something.
Everyone has an opinion on an interface that is easy to understand, and not over-engineered (bikeshedding).
- prudentpomelo 2y agoTake therefore no thought for the morrow: for the morrow shall take thought for the things of itself. Sufficient unto the day is the evil thereof. - Matthew 6:34, KJV
- nerdponx 2y agoI've definitely been bitten by designs that were too simple in critical areas. Interfaces can always be added to and code can always be deduplicated later. But an accretion of kludges around an insufficient set of core functionality is absolutely worse than having a little extra functionality that you end up deleting later. Don't try to solve speculative future problems. But if you are pretty sure you're going to need something in the future, you should probably take it into consideration in your design.
- cbanek 2y ago> But an accretion of kludges around an insufficient set of core functionality is absolutely worse than having a little extra functionality that you end up deleting later. I agree that an accretion of kludges is bad. The problem here comes down to usually the skill of the programmer when the new work comes up. To people who don't understand the code, they are more likely to make what they think is a simple kludge than actually refactor to solve the problem "correctly", which usually involves more thought and creativity. Whereas extra functionality usually increases the code surface area, and once published as a public interface to a library, is very costly and painful to delete. Then it festers as complications to new code that is added have to assume this extra functionality is used rather than not.
- nerdponx 2y agoThe skill of the programmer is subordinate to getting stuff done at a reasonable velocity. Given unlimited time, a sufficiently skilled programmer can always refactor as needed, when needed, and not a moment before. Data formats can be migrated, domain primitives can be reconsidered, names can be changed, interface boundaries can be moved. But there is never unlimited time, Unless you are simply programming for the joy of programming, and not particularly concerned about finishing some thing, or being able to make changes without taking on a large project each time. YAGNI is a mantra that we use to keep ourselves away from designing too much too early, introducing inappropriate abstractions and complexity that we will come to regret. But we are not religious fundamentalists either. YAGNI is a reminder, not a commandment. Just like DRY has its opposing WET, YAGNI has its opposing principle, even if we don't have a pithy name for it.
- djtango 2y agoYes, during a rewrite of a product I had a (new) team member scream YAGNI at me with supercilious delight when I pointed out all functions needed to account for the full primary key of (id, territory) rather than just (id) because we will definitely be needing it imminently although the current build only worked with data for one territory. We then had to spend a long time cleaning up the mess when lo and behold, we needed to add more territories to the dataset. I think we've swung too far in the wrong direction when it comes to "premature abstraction" and yagni. The only acceptable reason I've seen for writing bad code is "we might not be here tomorrow" but that is literally only valid for extremely young startups and even then those decisions could ripple and indirectly kill the company in the future when they're no longer able to pay off the tech debt in time
- Guid_NewGuid 2y agoAs someone who has been operating in hacky mode for years there's another situation where > we might not be here tomorrow Is true and increasingly common which is the recurring rounds of layoffs we all seem to be experiencing. It's in the individual developer's interest to bodge something in if it makes them appear productive in time for the next layoff. Certainly not a healthy incentive for building good software but it is what it is.
- ohthatsnotright 2y agoIf the MBA-management class wanted good software they wouldn't be so short sighted, but it's all about the pump-and-dump right now.
- mewpmewp2 2y agoFor me database structure should be built with decent flexibility, everything else is easier to refactor in the future when needed and best to keep simple unless it is a pattern you have definite experience with in the past and it is basically no cost and high certainty of working out. I hear YAGNIs when I know a pattern from experience with past projects even though deep down I know it is not that high effort due to past experience and we will need it. I hate hearing YAGNIs when it is something I specifically have had experience with in the past and they think it is too complex because they haven't done it. And they won't get it because they haven't gone through it.
- jghn 2y ago> Don't try to solve speculative future problems. But if you are pretty sure you're going to need something in the future, you should probably take it into consideration in your design. This is the real balance being struck. YAGNI is a pushback against the "you never know, one day we might want to expand this thing. I can't think of why right now, but let's make sure it's easy to do when if it happens!" That's very different from the case of "There's a use case that we plan on getting to in 3 weeks. Why don't we save ourselves some future work and do this now"
- gwervc 2y ago> If anything, overly simplistic solutions sometimes make me feel like I'm repeating myself, but really since the code is so easy it always feels possible to refactor it. This is way underrated. I've been on a project that was in one hand quite over-engineered, quick and dirty on the other hand. The thing is tech leads insisted on factoring absolutely everything. So you had a component (not compliant with solid's O) that dealt with 2 cases, needed two more cases added. And this is where it all breaks. I wish we could have dumbly copy pasted the thing two more times instead of having to deal with the weird and unforcasted interactions.
- jajko 2y agoI've seen so many times the same situation - brilliant junior comes, after reading it all about design patterns and taking inspiration in ie internals of Spring framework, builds a small (or big) cathedral, optimizing for designs that normally will never come in future. Layers and layers of abstractions, matching various situations that happen during initial implementation, everybody seems happy, business doesn't care about internals. Then brilliant junior inevitably leaves for greener pastures since it becomes boring, or is reassigned elsewhere. Every single other, even more experienced dev, struggles with maintaining, changing and fixing that part. But it became so embedded in overall architecture thus nobody has guts to rip it out, and business rarely wants to finance internal refactorings. So this burden than stays around, mothballing problems, making projects take longer, unexpected issues keep happening since everybody else has hard time keeping good mental model of that part with all its implications. Also nobody wants to admit that design is just overengineered crap, people have ego issues and feeling inferior which is pretty toxic and immature behavior, but I've seen it also in older folks as well. I had discussions around this exact topic with various very senior devs over my 20 years in business. Its always the same story - they see the code, are in awe of how such complex and on first sight elegant code can be done so quickly and respect the author uncritically. But every single time, down the line, it becomes a nightmare and source of massive pain. Thats why I call them brilliant juniors, nothing more, seniority also comes in form of 'should we do it like that' instead of 'can we do it like that'. Focusing on 'having fun', 'being a code ninja' or whatever little ego game they need to play with themselves to not get bored. Guess what - business who pays your salary loves boring, predictable, measurable, estimable, and couldn't care less about some internal issues of its employees. One of the reasons C suites look down on IT is exactly these geeks who should know better, or be coached/managed better. Or yeah, just don't optimize for problems you are not experiencing, in 99% of the cases, for 99% of the apps.
- jampekka 2y ago> I've never been bitten by an interface that is too simple. I've been bitten by strcpy. And errno. And malloc/free. And many others. In general, simple interfaces are good interfaces, but it takes quite a bit of experience to learn what is a good simple interface. For example not having to resort to global variables or a lot of state or a tightly coupled mess is not self evidient, but something that comes with practice, and usually the hard way. It doesn't help that many "best practices" aren't very good practices.
- maccard 2y agoI get your idea but I disagree - I’ve had plenty of bugs where people don’t fully implement an “interface” or a design or a contract. I’ve had many issues where people don’t handle failure cases and leave things in a bad state. On the interfaces one, it’s less likely but a bad interface is a symptom of a bad design. An interface that doesn’t actually expose what it needs to means that the implementation ends up coupled to other areas. Just right now, I’m untangling an interface for storing “stuff” which has a save method. The implementation has third party auth in it, and now that something else is using the same service we need to share the credentials between the two services. It’s turning out to be a mountain of work!
- Aeolun 2y agoI think the problem with simple is that people that don't know what they are doing are too tempted to just copy the simple everywhere, not knowing when to stop. Then when you reach the point where you need to change the simple to something more complex, you realize that there's 249 places where you need to change that simple thing, and management is unwilling to take that risk just to prevent potential problems down the road, so the simple thing slowly grows to 984 places, when a massive, massive incident happens, and suddenly it becomes the highest priority to fix. Joy. In my experience, the _only_ time to make things complex is right from the start.
- shahzaibmushtaq 2y agoThat's why I prefer to distinguish code as good and bad rather than simple and complex
- HumblyTossed 2y ago> Don't try to solve future problems. This. The problem is people stay at a job for 2 years. You can't properly see how the software evolves in 2 years to know that the things you're imagining might be needed have never been needed. Software tends to change in fairly predictable ways. If it suddenly changes in a new direction, your market has changed and the old solution isn't going to work well anyway.
- CharlieDigital 2y ago> You can't properly see how the software evolves in 2 years I'd counter that this is subjective based on experience. If I've built a similar system before, it's in the same domain, and the customer/userbase has a similar profile, then it makes sense that an engineer that's "been there, done that" can foresee the needs of the system, domain, and customer and can more accurately extrapolate how the system will need to evolve. I assume that this is one of the reasons teams hire for both technical and domain experience. As an example, I spent more than a decade building regulated document management systems and it's clear to me what needs to be done to scale the system to support millions of documents. Is it premature optimization or over-engineering if I join a team that's building a new document management system and I design it to scale from day 1? Similarly, if you're building a product that interacts with calendars, perhaps you start with only supporting GCal, but you can already extrapolate that the market has 2 other major calendar providers to account for: Outlook 365 and Apple iCal. Wouldn't it make sense to write an interface here knowing that a year down the line, you'll add support for O365 and then another year after, add support for Apple? To an engineer or product manager new to the space, any extra effort looks like "over-engineering". For someone that's built similar systems for over a decade, some decisions seem inevitable because the usage patterns of such systems are not that different and will eventually converge so one might as well start with that endpoint. I suspect that some decisions made in the development of Threads or BlueSky might seem like "over-engineering". But those teams are not working in a vacuum; they already have a sense of how such systems will grow over time based on experience. Thus I would make the case that the cost of perceived "over-engineering" is also going to differ. For someone doing it for the first time, that perceived cost is higher than for someone doing it the 2nd or 3rd time. My take is that what is "over-engineered" has a subjective aspect based on the experience level of the parties involved.
- jillesvangurp 2y agoActually, under engineering is a common thing as well. It leads to systems that once they are implemented are hard to modify. Typical symptoms are people trying to hack around that. Or designers sacrificing necessary complexity in favor of an elegant look. If you've ever had the discussion whether the name field is 1 text field or 2 text fields, that's what's going on. "I don't care about first name last name, we just need a single name field, much more elegant". Fast forward a few months ... "hey can you auto-magically split that name field in first name, last name". No kidding, I've had to sit a PM down on at least two projects where that happened and explain to them why that was a silly idea. In case you are wondering, there's a good reason why most apps and sites use two fields: splitting automatically reliably is not possible and as soon as you want to address somebody by their first (or last) name in e.g. an email, invoice, etc. you need both fields. Another classic mistake here is that the first name and last name are two words. They can be multiple words. Both. And two fields is actually not enough for some names if you really want to cover everything. There's also salutations, titles, middle name, maiden name, etc. It's a mess. But you can usually get away with using just first & last name. Just one example. It's the famous Einstein paraphrasing of making things as simple as you can; but not simpler. The issue with over engineering is engineers getting carried away with edge cases that in practice aren't relevant. Like trying to build a super scalable web platform for a thing that has maybe a handful of active users. Optimizing a thing that only takes a millisecond in a request that takes half a second. Nice but your problem was somewhere in the 499 other milliseconds. Obsessing over the one in ten thousand users that might want feature x used in some weird way, etc.
- xnorswap 2y agoYou've correctly identified a problem, but you've come to the wrong conclusion. If you ask someone their name, a single field copes with a range of different name shapes. If you want to address them in an email with "just first name", what you're really asking for is a preferred name to be greeted by, and that should be an entirely different single field. By splitting or having "firstname/lastname" fields you're making the classic mistake about names. Ask in the sign-up or user preferences their preferred way to be greeted in an email. If the user wants their marking emails to start "Dear shithead" then free them up to do that. You could try splitting the "full name" field to pre-fill a suggested name by which to be greeted.
- chasd00 2y agoI don’t remember who said it but there’s a quote about communications protocols that goes “it’s not finished when there’s nothing left to add, it’s finished when there’s nothing left to take away”. I use that a lot in discussions with my teams.