How to stop workarounds forever?

Let's say there are two possible solutions to the problem: the first is quick, but hacky; the second is preferable, but it will take more time to implement. You need to quickly solve the problem, so you decide to crack the hack as soon as possible, and then plan to start working on a better solution. The trouble is that as soon as the problem is fixed, it will fall sharply in the to-do list. At some point, you still plan to use the best solution, but now it’s hard to justify its implementation. Suddenly you will find that you spent five years using a less perfect solution, cursing it.

Does this sound familiar? I know that this has happened more than once, where I work. One of the colleagues intentionally describes the creation of a bad GUI so that it is not accidentally accepted for a long time. Do you have a better strategy?

+79
language-agnostic
Oct 03 '08 at 17:10
source share
26 answers

Write a test file that failed to execute.

If you cannot write a test that breaks, then either there is nothing wrong with breaking in the end, or your test structure is inadequate. If the first, run away quickly before you spend your life on unnecessary optimization. If the latter, try a different approach (either for marking hacks, or for testing ...)

+37
03 Oct '08 at 17:56
source share

Strategy 1 (almost never selected): Do not use kluge. Do not even let people know this. Just do it right the first time. As I said, this one is almost never selected due to time constraints.

Strategy 2 (dishonest): Lee and Cheat. Tell management that there are bugs in the hack and they can cause serious problems later. Unfortunately, in most cases, managers simply say to wait until errors become a problem, and then fix the errors.

Strategy 2a: Same as Strategy 2, except for errors. However, the same problem.

Strategy 3 (and my personal favorite): design a solution when you can, and do it well enough that an intern or a code monkey can do it. It’s easier to justify spending a small amount of money with a code monkey than justifying your own salary so that it can simply end.

Strategy 4: Wait for rewriting. I'm waiting for everything. Sooner or later (perhaps later) someone will have to rewrite the thing. It is also possible that this is correct.

+17
Oct 03 '08 at 17:19
source share

Here is a great article on technical debt .

Basically, it is an analogue of debt with all the technical decisions that you make. Good debt and bad debts ... and you need to pick up a debt that will achieve your desired goals with the least long-term costs.

The worst kind of debt is small small accumulations of labels that are similar to credit card debt ... everyone does not hurt, but pretty soon you are in a poor house.

+16
03 Oct '08 at 17:33
source share

This is a serious problem when working with a deadline. I find that I am adding very detailed comments on why this path was chosen, and some hints on how to encode it. Thus, people looking at the code see this and keep it fresh.

Another option that will work is to add a bug.feature error to your tracking structure (you have one, right?) Detailing the alteration. Thus, it is visible and may cause a problem at some point.

+14
Oct 03 '08 at 17:15
source share

The only time you can ever justify fixing these things (because they aren't really broken, just ugly), when you have another function or bug fix that deals with the same section of code, and you can also rewrite it.

You must do the math at the cost of the developers. If the software requirements are met, and the only thing that is wrong is that the code is embarrassing under the hood, it really should not be fixed.

Entire companies can go out of business because overly diligent engineers insist on restructuring every year when they get into trouble.

If this is a mistake and meets the requirements, this is done. Send it. Move on.

[change]

Of course, I am not a supporter of the fact that everything will be hacked all the time. You must carefully develop and write code during normal development. But when you finish the hacks that needed to be done quickly, you need to analyze the costs and benefits, regardless of whether it should clear the code. If you spend more time coding around a messy hack for the duration of the application than you would fix it, then, of course, fix it. But if not, then it is too expensive and risky to transcode a working application without errors, because viewing the source makes you sick.

+13
Oct 03 '08 at 17:31
source share

YOU DO NOT PLACE INTERMEDIATE DECISIONS.

Sometimes it seems to me that programmers just need to say this.

Sorry, but seriously - a hacker solution is useless, and even at the first iteration it may take more time than to correctly execute part of the solution.

Please stop leaving me your shitty code for maintenance. Just ALWAYS CODE IS RIGHT. No matter how long it takes, and who yells at you.

When you sit there with your thumbs crossed after you set off early, while everyone else is debugging their stupid hacks, you will thank me.

Even if you do not think that you are a great programmer, always try to do everything possible, never use shortcuts - it will not cost you time to do it right. I can justify this statement if you do not believe me.

+7
Oct 03 '08 at 17:22
source share

Suddenly you will find that you spent five years using a solution other than perfection, and cursed it.

If you curse him, why is he at the bottom of the TODO list?

  • If this does not affect you, why did you curse him?
  • If this affects you, then this is a problem that needs to be fixed NOW.
+7
Oct 03 '08 at 17:23
source share
  • I make sure that I vocal about the priority of the long-term fix ESPECIALLY after the short fix is ​​fixed.
  • I will explain in detail the reasons why this is a hack, and not a good long-term solution and use them to attract interested parties (managers, clients, etc.) to understand why it needs to be fixed.
  • Depending on the case, I can even bring in a slightly worse fear scenario in there. “If this safe line clicks, the whole bridge could crash!”
  • I take responsibility for developing a long-term solution and make sure it is deployed.
+5
Oct 03 '08 at 17:16
source share

This is a difficult challenge. I myself did hacks, sometimes you HAVE to pull this product from the door and into the hands of customers. However, the way I take care of this is to simply do it.

Tell the project manager or your boss or client: There are some spots that need to be cleaned and better encoded. I need a week to do this, and it will cost less to do it now, then it will be done in 6 months, when we need to implement the extension in the subsystem.

+4
03 Oct '08 at 17:15
source share

Typically, such problems arise due to poor communication with the management or the client. If the solution works for the client, then they see no reason to ask him to change. Therefore, they need to communicate the trade-offs you made in advance so that they can plan extra time to fix problems after you have implemented the quick fix.

How to solve it, it depends a little on why this is a bad decision. If your decision is bad because it is difficult to change or maintain, then the first time you need to do maintenance and you will have a little more time, then the best time to move to the best solution. In this case, it helps if you tell the client or your boss that you took the shortcut first. Thus, they know that the next time they cannot expect a quick solution. Overcoming the user interface can be a good way to make sure the client returns to receive the corrected material.

If the solution is bad because it is risky or unstable, you really need to talk to the person planning and planning the time to solve the problem as soon as possible.

+4
Oct 03 '08 at 17:19
source share

Good luck. In my experience, this is almost impossible to achieve.

As soon as you go down the slippery slope to hack, because you are under pressure, then you can get used to living with him for all time. There is almost NEVER enough time to recycle what is already working, regardless of how much it is implemented domestically. What makes you think that you will have a magical time longer "at some later date" to fix the hack?

The only exception that I can think of in this rule is that the hack does not completely allow you to implement another functionality that the client needs. Then you have no choice but to do the second job.

+4
03 Oct '08 at 17:33
source share

I am trying to create a hacker solution so that it can be transferred to the long-term path as painlessly as possible. Let's say you have a guy who builds a database in SQL Server because its most powerful database, but your corporate standard is Oracle. Build db with the highest possible inexpressible function (e.g. Bit datatypes). In this example, it is not difficult to avoid bit types, but this simplifies the transition process.

+2
Oct 03 '08 at 17:26
source share

Enlighten the person who is responsible for making the final decision why the hacker way of doing something bad in the long run.

  • Describe the problem in terms to which they may refer.
  • Include a graph of cost, performance, and profit curves.
  • Teach them technical duty .
  • Regularly refactor if you are moving forward.
  • Never call it “refactoring” or “returning and cleaning” in front of non-technical people. Instead, call it “adapt” the system to handle “new features.”

Basically, people who don’t understand the software don’t understand the concept of revising things that already work. As they look at it, developers are like mechanics who want to keep sorting out and assembling the whole machine every time someone wants to add a feature that seems crazy to them.

It helps to make an analogy with everyday things. Explain to them how, when you made an interim solution, you made a choice that is suitable for its quick construction, and not in order to be stable, maintainable, etc. This is similar to the choice for assembling from wood instead of steel, because wood is easier to cut, you can quickly create an intermediate solution. The forest, however, simply cannot support the foundation of a 20-story building.

+2
03 Oct '08 at 19:19
source share

We use Java and Hudson for continuous integration. “Intermediate decisions” should be commented on:

// TODO: Better solution required. 

Each time Hudson launches the build, he provides a report of each TODO element so that we have an updated, very visible record of any wonderful elements that need improvement.

+2
Oct 15 '08 at 14:59
source share

Great question. This bothers me too much - and most of the time I am the only person responsible for setting priorities in my own projects (yes, small business).

I found out that the problem that needs to be fixed is usually only part of the problem. IOW, a client who needs an urgent solution, does not need the whole problem to be resolved, but only part of it - less or more. This sometimes allows me to create a workaround that is not a solution to the complete problem, but only for a subset of clients, and this allows me to leave the big problem open in the tracker problem.

This may, of course, not apply to your work environment at all :(

+1
03 Oct '08 at 17:21
source share

It reminds me of the CTool story. In the beginning, CTool was put forward by one of our developers, I will call it Don, as one of the possible ways to solve the problem that we had. Being a serious hardworking type, Don turned on and set up a working prototype. You know where I am going with this. At night, CTool became part of the company's workflow with the entire department depending on this. By the second or third day, bitter complaints began regarding CTool's flaws. Users questioned Don competency, commitment and IQ. Don protests that it was never supposed that this production app fell on deaf ears. This went on for years . Finally, someone was about to rewrite the application after Don left. By this time, so much hatred had become attached to the name CTool, that it could not be called CTool version 2. There was even an official funeral for CTool, somewhat reminiscent of the copier execution script (or was it a printer?) In Office Space .

Someone may say that Don earned slings and arrows for not correcting him in order to fix CTool. My only thing to say is that you should never crack the solution, probably unjustifiably in the real world. But if you are the one who did this, walk carefully.

+1
Oct 03 '08 at 18:21
source share
  • Receive it in writing (email). Therefore, when this becomes a problem, management does not forget that it should be temporary.

  • Make it visible to users. The clearer, the less likely that people will forget to go back and do it right when the crisis is over.

  • Negotiations before an interim solution is created for the project, resources, and timelines to get a real fix. Work on a real solution should probably begin as soon as the temp solution is complete.

+1
03 Oct '08 at 19:12
source share

You write down the second very descriptive error in your own “correction” and put the right to comment in the affected areas, where it says: “This area needs a lot of work. See defect No. 555” (use the correct number of course). People who say they’re not shocked do not seem to understand the question. Suppose you have a system that should be up and running now, your solution without a hack is 8 days of work, your hack is 38 minutes of work, there is a hack to buy you time to do the work, and not lose money, while you do it.

Now you still need your client or management to agree to schedule N * 100 minutes of time needed to complete the real fix, as well as N minutes needed to fix it. If you must refuse to implement the hack until you get such consent, perhaps this is what you need to do, but I worked with some understanding people in this regard.

+1
Oct 03 '08 at 19:30
source share

The real cost of introducing a quick fix is ​​that when someone else needs to introduce a second quick fix, they will present it based on your own quick fix. So, the longer the fast fixation in place, the more entrenched it will become. Quite often, a hack takes a little longer than doing everything right until you come across a second hack that is based on the first.

Thus, it is obvious that it (or it seems) is sometimes necessary to introduce a quick fix.

One possible solution, assuming your version control supports it, is to insert the plug from the source whenever you do such a hack. If people are advised to avoid coding new functions in these special “do it” forms, then in the end it will be more work to integrate new functions with a plug than it will to get rid of hacking. Most likely, however, the “good” plug will be discarded. And if you are far enough from the release that creating such a plug will not be practical (because it is not worth doing the double integration mentioned above), then you probably should not even use a hack.

Very idealistic approach.

A more realistic solution is to keep your program segmented by as many orthogonal components as possible and sometimes do a complete remake of some components.

The best question is why the hacker solution is bad. If this is bad because it reduces flexibility, ignore it until you need flexibility. If this is bad, because it affects the behavior of the programs, ignores it and will ultimately become a correction error and will be considered. If this is bad because it looks ugly, ignore it if the localization is localized.

+1
Oct 03 '08 at 22:27
source share

Some solutions I've seen in the past:

  • Mark it with a HACK comment in code (or a similar pattern, e.g. XXX )
  • Auto report via email and email weekly to those who count how many times HACK comments HACK
  • Add a new entry to the error tracking system with a line number and a description of the correct solution (therefore, the knowledge gained during the study before writing the hack is not lost).
  • write a test example that demonstrates how the hack fails (if possible) and check it in the appropriate set of tests (i.e. so that it produces errors that someone ultimately wants to clear)
  • after the hack is established and the pressure is turned off, immediately start with the correct solution.

This is a great question. One thing that I noticed when I get more experience: hacks buy you a very short time and often cost you a huge amount. A close relationship is a “quick fix” that solves what you think is the problem — only find when it explodes, it's not a problem.

+1
04 Oct '08 at 5:55
source share

Leaving aside the debate about whether you should do this, let me suggest that you should do it. The trick now is to do it in such a way as to minimize the effects of long-range action, it easily escaped later and became unpleasant, so you did not forget to fix it.

The unpleasant part is simple: make it issue a warning every time you execute kludge.

The cut part may be easy: I like to do this to put the name kludge under the name of the subroutine. This makes updating easier as you split the code. When you get your permanent solution, you subroutine can either implement it or be non-op. Sometimes a subclass may work well for this as well. Do not let other people depend on your quick fix. It is difficult to recommend any particular method without seeing the situation.

Minimizing long-range effects should be easy if the rest of the code is good. Always browse the published interface, etc.

+1
04 Oct '08 at 6:32
source share

Try to make the cost of hacking understandable for business people. Then they can make an informed decision in any case.

+1
04 Oct '08 at 7:54
source share

You can intentionally write it so that it is overly restrictive and strong, and it would require rewriting to change it.

+1
Dec 05 '08 at 13:33
source share

We had to do it once - make a short-term demo version that we knew that we did not want to store it. The client wanted it on a winTel box, so we developed a prototype in SGI / XWindows. (We spoke fluently to both, so this is not a problem).

0
Oct 03 '08 at 17:34
source share

Confession:

I used '#define private public' in C ++ to read data from another layer of code. He logged in as a hack, but works well, and his commit never became a priority. Now 3 years later ...

One of the main reasons hacks are not deleted is the risk that you introduce new errors when fixing a hack. (Especially when working with databases before TDD.)

0
Oct 03 '08 at 18:13
source share

My answer is slightly different from the others. My experience is that the following methods will help you stay flexible and move from hackey first iteration / alpha solutions to beta products:

  • Test Driven Development

  • Small refactoring units

  • Continuous integration
  • Good configuration management
  • Agile database methods / database refactoring

And it goes without saying that you must have the support of stakeholders in order to do any of this right. But with these products, you have the right tools and processes to quickly change the product with great confidence. Sometimes your ability to change is your ability to manage the risk of change, and in terms of development, these tools / methods provide you with more reliable support.

0
Oct 03 '08 at 18:32
source share



All Articles