4 ms·
I'm not really a fan of the story-point example. The article begins with: > it’s something that you get when you delay design decisions for later But then pre
by slightlycuban 12y ago
I'm not really a fan of the story-point example. The article begins with:
> it’s something that you get when you delay design decisions for later
But then presents us with a problem where we can "spend" 21 story points now, knowing we won't have to do much refactoring later. How do we know this? I thought the whole point was we couldn't see enough of the picture to make a stable design.
Instead of talking about how patches, hacks, and workarounds impact code, I'd like to see discussion on how you move forward when you know the requirements are going to change, but don't know how.
- sheepmullet 12y ago"I thought the whole point was we couldn't see enough of the picture to make a stable design." While still technical debt it is not the type the article is talking about or using in the example. FTA: "At this point the developers realize that the code is starting to get messy and the solution is refactoring it to have a decent permission system." I.e. You are at the point where you realise you need a better design and know the rough solution. Do you keep putting band aids on your solution or do you properly refactor?
- sheepmullet 12y ago"I'd like to see discussion on how you move forward when you know the requirements are going to change, but don't know how" I've found requirements do not change nearly as often as you would think. Only maybe 10% of the changes I make come from a requirements change. Take for instance the articles permissions example. Is that a change in requirements or a lack of understanding the requirements and domain? Sometimes it is a genuine requirements change. Maybe the company has recently adopted a new security policy, or maybe you are selling to a new customer and they require permissions even though none of your existing customers do etc. More often than not though the requirement has always existed but the dev team didn't know about it or didn't have time to deal with it.
- slightlycuban 12y agoIn my line of work, either I'm building a new component, or I'm dealing with requirements change. So dealing with the shifting sands of what the system should do is a major concern. Requirements come and go for me. And losing requirements can be just as disruptive as getting them. Worried about how component X will handle users? Well, we don't ship component X anymore, so any refactoring work you've done is wasted. I might be the odd one out with requirements changing all the time, but I don't get the choice between good design and fast design. I have to creep forward in my architecture, like I'm fumbling around in the dark, because what my system should do today may not hold until tomorrow.
- sheepmullet 12y ago"In my line of work, either I'm building a new component, or I'm dealing with requirements change. So dealing with the shifting sands of what the system should do is a major concern." And that is simply the case with certain lines of work. To help me determine which requirements changes are simply a failure in the requirements process I ask myself: "If I had shipped feature X a month ago would it have had business value?" If the answer is no then I'm likely dealing with a legitimate requirements change. For example: If I worked in the tax industry and the government changes tax laws then shipping these changes months before would not deliver any business value. Or if I have to make a requirements change because of an external dependency changing. No extra value.
- slightlycuban 12y agoSounds like you have a good idea of what I'm on about. Still leaves me searching for a way to deal with my system. Take your tax-software example. You need to start work before the law is written, but there could be changes in the law that require a rework of business logic. What do you work on? How do you prioritize? And how do you deal with that subsystem that no longer has a reason to exist? In my domain, technical debt is not really a choice I make. It is something that happens as the system ages. I wish I could get someone to speak to that.
- 12y ago
- msandford 12y agoIf you implement a robust permissioning system that has permissions related to group membership and one-off permissions related to a single user then MOST of your problems are solved. Nearly all new permission requirements can then be made without touching the code at all, or in more than a couple of places. The idea is to choose a new design that scales better. If you have M permissions and N permission checks then each new requirement might cause M * N changes to the codebase. If you have a reasonable permission system you might end up having to make N changes to the codebase (worst-case) or perhaps only M modifications to permissions or perhaps both. But in that case it's M + N changes, rather than M * N. For any values of M and N greater than 2 (and very nearly all of them will be) M + N is smaller than M * N.
- slightlycuban 12y agoThe issue I deal with isn't in choosing a design that scales better, it is uncertainty in how things will scale. Say I need to handle group permissions depending on the context. I could hard-code the permissions changes for the one group that needs it now, or I could abstract and generalize context-switching behavior into its own component, ensuring changes to future groups will be easy and low-cost. But, what if I never get a second group that needs this? While hard-coding values was an ugly shortcut, I may never have a need to revisit the code. If I had gone with a generalized solution, I'd still have to contend with maintaining all that code.
- msandford 12y agoThat's an interesting point. Here's my take: If you ask someone who knows about the business rules if something could EVER happen and they say "no" they're probably wrong, but not maliciously so. Be cautious when taking their word for something. Even if the CEO signs off on the idea of "such and such never needs to be able to do x, y or z" the second a big contract does need it, it all goes out the window. As a result whenever possible choose solutions that give you SOME flexibility without necessarily creating a supremely robust, exhaustive module. In this particular case, once you realize that you're going to have more in the way of permissions other than global can/can't do, it's time to be smart. Being smart might only mean creating a function which takes some context like userid and "permissions token" and/or the URL that the person is visiting and then doing a hardcoded permissions check for say one of a dozen userids who are basically root versus everyone else who isn't. Yes you didn't make a giant scalable system of awesomeness including a web-based permission editor. But you did make a function you can insert every time a new permission item gets created and eventually a system could be created for storing those in the database such that users can eventually be mapped to permissions also in the database. So if you want to hard-code those values into a single page, which then grows into two pages, which then grows into four pages which then grows into 29 pages that's the wrong solution. But if you want to hardcode those into a function which you then call, that's a good enough solution for now that doesn't hobble you later. Putting the function call in adds very minimal overhead in terms of execution and ranges from slightly negative to moderately positive on maintainability. Parts of software development are similar to being a speculator in a financial market. You need to have a fairly intuitive grasp of what's going to be a "good bet" for spending a little more time now which has the potential to pay off big in the future.