25

I was thinking of this because I was trying to write an extension for an existing 3rd party software, and their database is horribly denormalized. I needed to use their existing tables and add a bunch of new fields.

I had the option of either creating new tables in their design style (which consists of almost all the propeties being in one big table), or creating a new set of tables alltogether and using something extra such as Triggers to synchronize data between the new and old tables.

I ended up going with the first option of using the existing poor design style, but I was left with this question: Is it better to go with pre-existing bad practices, or to implement good practices that do not play nicely with existing code? Is there some situations where I should choose one over the other?

NOTE: Many answers so far have to do with slowly refactoring the bad code, however I am unable to do that. The code is not ours, and it frequently gets updated by the vendor. I can only build onto it.

3

8 Answers 8

21

You should choose better design if:

  1. You are going to be taking over a large part of future coding

  2. Better design isn't more expensive to the client in the long run. For instance, I have witnessed multi-month "refactorings" for projects that were discontinued by the end of the year.

You should choose "same bad style" if:

  1. You're just helping out. It's unrealistic to think you can take an existing group and will them to higher design standards if you're just a part-time fill-in on the project. Better design is subjective and almost always has a learning curve. If that new design isn't learned by the rest of the team then the project will end up with a mish-mash of styles, and your better designed code may end up in the pile of stuff that nobody changes because they can't understand it. In your example above, what happens if there are updates to the third party software?

  2. Sacrificing "better" design will get you a tangible business advantage. Like adding feature X badly will get you a large contract, but missing the deadline causes you to end up with nothing. This is where the historic conflict between mgmt and the technical team come in. Like renovating a house, someone has to decide when to pay. You can pay down the debt initially by living with no electricity or plumbing for a year. Or you can pay 3x as much with the benefit of having those utilities.

1
  • Great examples of when to go with good design over bad design and vice versa, thanks :)
    – Rachel
    Sep 30, 2011 at 16:19
11

In the long run, it is better to use good practices. It will save time and effort as changes will take less time to implement.

If possible, take little steps to refactor to good practice (for example: in SQL that would be breaking denoramlized tables to normalized one and using views with the old table names).

You will note that I said in the long run - the "quality, time, money" triangle applies here as well (i.e - choose two). If you don't have the time you may have to go with old practices, but this will mean that you are adding to the problem and that your design will also need to be fixed.

If you keep working and adding code of bad design, you will never end up with a codebase that uses good design. As much as possible try to use good design and refactor to good design.

3
  • I never thought about that solution for the SQL data. Unfortunately, I'm not allowed to edit their code base because they still release regular updates. Anything I add on has to be completely separate.
    – Rachel
    Sep 30, 2011 at 15:14
  • 1
    @Rachel - If you are in control of the new tables, use good design for them (I am assuming that updates to the old design will not impact the new tables). When you need to change your code, your maintenance costs will be lower.
    – Oded
    Sep 30, 2011 at 15:22
  • Updates to the software frequency include database updates and new fields, so deleting existing tables and rewriting them as views is not a viable option for me. Users still use the existing part of the software that uses these tables, they just need an extension. If this were our code instead of a 3rd party vendor's, I'd implement this in a heartbeat :) Good point of view overall though for my original question.
    – Rachel
    Sep 30, 2011 at 15:31
1

Well, I think it very much depends on each case. If performance and design permits it, it is better to use good practices. But if for instance, if that table is a high access table, then creating a trigger for sincronization might have a negative impact on performance.

Now, your client wont see that you used a better design, he'll just see that your solution made his system slower. This type of decision should be made in a case by case basis, and you should use your experience and criteria to decide.

I think you probably made the right choice.

1

As much as possible, you should isolate your application code from the poor data design.

Are you updating their tables? If not, then create SQL views to present those tables in a manner convenient to your application. SQL views are relatively easy to write, and far easier to test than application code.

If you do have to update the legacy tables, consider writing stored procedures to manage the updates. They are a bit more complex to write, but they can be tested instantaneously.

1

To keep the old code in sync when you normalize a database with triggers ia a good solution if it is temporary. The goal should be to change the old code, but when dealing with a third-party, that may not work out. You'll have to stay on top of their schema changes.

Piling more and more features on the bad code is going to create continuous problems. Work-arounds become the norm. Users will become frustrated because changes are going to take too long and probably introduce other bugs or limitations. Who wants to be the programmer to say we can't do that instead of we shouldn't do that?

Some code can be left alone; we don't always have that luxury.

-1

You are dealing with technical debt here. In short, technical debt imply interest, that you have to pay over time, and at some point, you have to refund it.

Develloper's time cost money, so the technical debt can be seen just like the real debt, and cost real money.

You have basically two main solutions, and many solutions in between. You can decide that you don't want to refund that debt now, and continue to pay interest. Obviously, this will cost more in the long run, but allow you to have result right now. You can also choose to refund that debt, so you'll not go forward anymore as long as you don't refund it, but, at the end, you are free from interest.

Usually you have deadlines for delivery, and missing a deadline will cause distrust of your customer, and eventually you'll loose it. This could be a valid reason to burrow technical debt : you consider that what you gain with the customer worth the extra exepense of technocal debt.

You know that at the end, you have to adopt the new methodology, otherwize, you'll get more and more debt and you eventually go bankrupt (you now, when people decide to start again from scratch or when the project fail badly).

You have to plan how you'll change the existing codebase and transition to new practice over time, and distibute the change bit by bit on a daily basis. At some point, when thoses refactoring will leads to other losses, consider which loss is the worse and go for the best one.

The cost of not refactoring will increase over time (this are interests of technocal debt). So this will become eventually the costliest choice.

Be sure that your boss understand the concept of technical debt. Even with precaution, you will create technical debt. At some point, money as to be used to refund it. When you create technical debt on purpose, you HAVE TO have a valid reason for it, and see the debt as an investment (just like real debt). In any other cases, just DON'T DO technical debt on purpose.

You may be interested on methodologies to evolve DB and deploy thoses evolutions : http://richarddingwall.name/2011/02/09/the-road-to-automated-database-deployment

By the way, that's a difficult task, so good luck. It worth it !

-1

This is a typical problem of: "Do I need to reap the benefits of my work now or later?" and I don't think there can ever be a generic solution to that answer. Only you know all the factors (technical and human) involved in such a decision.

However your problem raises an interesting question:

Is automatic code refactoring making enough advances so that code uniformity should be valued more?

Ultimately, bad design should change or die. Or else, it's not a bad design. The real question here is about the cost of refactoring. It seems clear from your question that you (or your employer) is not willing to pay the price now, and in the current state of technology, is not likely to ever want to.

However, code refactoring automation is making some advances. If compilers can optimize binaries today, who's to say they wouldn't optimize code tomorrow? At some point, some tool is going to come up, allowing developers and designers to refactor their code very easily, in order to adapt to newer requirements. After all, dealing with legacy code is one of today's biggest challenges.

If such a tool ever exists (I wouldn't be surprised that it already does), it would be good to take it into account, when making such a decision.

-2

Good practices always trump poor ones. If your codebase is littered with code the wrong way, you shouldn't just cargo-cult your own stuff in the same fashion, you should write code properly and then try to educate everyone else on the correct way.

2
  • As a developer you should know the danger of absolute statements. Oct 3, 2011 at 16:38
  • I also know the danger of dealing with bad practices and writing code incorrectly, and IMO that's the worst danger of all. Oct 3, 2011 at 17:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.