views:

216

answers:

8

Hello,

Sometimes I really wonder if my code is "lastable". I do everything to make it "last" and avoid depending on things while writing or solving problems. Things like "programming tricks" and assumptions which may change in the future if I rewrite or add to the code. Sometimes it's easy, other times it's hard, but it's all a part of being a programmer and making stuff work better, faster and easier.

Having said this, can you recommend some tips from your personal experience for writing better long lasting code in HLL? What should be avoided, what embraced?

Thank you!

+6  A: 

Avoid anything you recently read about and thought,

Well that is an interesting language feature, design pattern etc. , I think this can help me reduce my code complexity.

For some reason this always comes to bite me later on. Better to have this in side projects and then use it in production code once it proved a good idea, versus merely looking like one.

nasmorn
A: 

Look at SOLID principles. For example Getting a SOLID start.

Petar Repac
There are other guidelines like DRY (don't repeat yourself) and YAGNI (you ain't gonna need it). Google about that a little.
Petar Repac
Also KISS (Keep It Simple, Stupid).
Secko
@sheepsimulator I agree about SOLID, but dont completely agree about other concepts.
Secko
@ Secko - sorry.. we have a developer at my company who is a fanatic about SOLID principles and creates bajillions of classes that do small, insignificant things and is constantly "refactoring" things that other people write that worked correctly, and after refactor are more SOLID but then it doesn't quite fulfill requirements, b/c the dev didn't know them. Is he right about his recommendations? Usually yes, SOLID principles are better ways to do things long-term. But it's freakin' annoying when you write something and someone comes and removes features on you, just for the sake of SOLIDity.
sheepsimulator
I guess I'd sum up and say that SOLIDity for SOLIDity's sake isn't helpful.
sheepsimulator
From the link I posted: The SOLID principles are not rules. They are not laws. They are not perfect truths. The are statements on the order of “An apple a day keeps the doctor away.” This is a good principle, it is good advice, but it’s not a pure truth, nor is it a rule.
Petar Repac
So, yes I would agree: "SOLIDity for SOLIDity's sake isn't helpful."
Petar Repac
+1  A: 

To me it is a lot like sending an email or any correspondence.

After the code is "done" I will read back over it and walk through all the scenarios in my mind.

After that are the tests.

The best developers I have seen can read through code and get all of the basic stuff knocked out. And then get even more issues knocked out with unit testing.

Also, comments. I think in assembly programming they talk about "write once, read never" code. If you don't comment assembly code it cannot be maintained. HLLs require useful comments.

Maestro1024
+2  A: 

In my opinion, there is nothing wrong with letting program evolve. There used to be a time I always wanted to foresee every possible change, but I learned that most of the time, this is not possible. However, abstractions survive longer than implementation details. So my tip is to separate your application as much as possible into lots of components (classes and functions) with interfaces that are as abstract (hiding implementation details) as possible. This way, when something has to change, which unavoidably will happen, changes are likely to be isolated in a small part of the source code.

Dimitri C.
+3  A: 

Sometimes the key to making code last is not to try and architect some masterpiece of eternal durability up front, but just to get on and make something that's genuinely useful. It may even be acceptable to make certain assumptions up front, as long as they're all clearly documented, perhaps through comments, assertions or unit tests. Which reminds me: write plenty of unit tests so that as the code evolves over time, the assumptions about how it's supposed to behave are constantly being tested.

Don't assume that anything you write will remain unchanged through the ages. Count on constant refactoring and concentrate on making that as easy as possible.

andygeers
+5  A: 

Bit rot...

The problems I have most often come up against when compiling an old project are

  • Missing dependencies - It is a good idea to list any libraries that you depend on, including the URL you got it from. Your include path may not be the same as it was 5 years ago!
  • Compiler changes - These are usually not much of a bother, and can often be fixed with a #define in C/C++
  • Data size changes - This was a nasty one when moving from 16-bit to 32-bit. Try not to make assumptions about the size of variables.
  • Mysterious build process - For some projects, there may be obscure build steps for building resources, libraries, etc. Make sure they're well documented.
  • Overly clever code - I've seen code that assumes the machine has less than X megabytes of memory, and so uses the top bits of pointers to hold data. Don't do things like that!
  • Error checking - When things DO break, good error checking will help you figure out why a lot faster.
MrZebra
+1  A: 

I try to remember the following:

  • The code will likely live far longer than anyone would ever expect, or far shorter than anyone would ever expect (I left a project once and they completely re-wrote my app in a different language - however the new developer was happy because I left copious comments behind!)
  • If you ever return to your code, you will discover that it is horrible. It always is. Make comments before you forget how it worked.
  • Realize that someone else will look at your code, decide that it is crap because you didn't follow OOP well enough, and refactor the whole thing on you. Then later the person who refactored the thing will come ask you for help because it doesn't work, and you'll discover that the person who re-wrote for the sake of SOLID principles completely removed entire features from the app, which was the whole reason you broke SOLID principles in the first place (sorry, that's a rant...).

Either way, I would add lots of comments. Comments would remedy all of the above problems and make the code last a lot longer. I would recommend erring on the verbose side.

sheepsimulator
Good point about the "life of code", I have reviewed, learned and changed code from dead programmers (to dead programmers - thank you guys) for years. As I said about your comment earlier, I dont completely agree about the last dot in your answer. I would give you 0.5 but stackoverflow.com doesn't provide that so I'm giving you a 1 up anyway. Thanks for your answer!
Secko
@ Secko - sorry.. we have a developer at my company who is a fanatic about SOLID principles and creates bajillions of classes that do small, insignificant things and is constantly "refactoring" things that other people write that worked correctly, and after refactor are more SOLID but then it doesn't quite fulfill requirements, b/c the dev didn't know them. Is he right about his recommendations? Usually yes, SOLID principles are better ways to do things long-term. But it's freakin' annoying when you write something and someone comes and removes features on you, just for the sake of SOLIDity.
sheepsimulator
@sheepsimulator Lol, I know the feeling!
Secko
+2  A: 

I have found the following tips useful:

  1. Use meaningful variable/member/class/function names, even if your fingers hurt from the typing.

  2. Comment each class and function, procedure (unless it is boilerplate e.g. set/get methods) accurately, concisely. If this is not possible or easy then probably your function/sub is too complex.

  3. Keep functions/procedures small - 5-10 lines. This helps keep them easy to validate, test, debug, document, and use.

  4. When you review your code (usually during the course of bug fixes or further development) and something strikes you as off, document the issue or fix it. Often later you will find a bug and it will be related, or you will use the code in a way that violates some of these assumptions made and the documentation will help you.

  5. Keep a working log of the changes you are making throughout the day. When you save to the repository, you can cut and paste the part of the log from the last save to the current place, so your code repository changes are well-documented. Save the logs separately (repository, email, blog).

  6. Factor your code into independent, reusable components. There is a fine line here between over-engineering, KISS, and generalization, so you have to weigh the pro's and con's. The advantage of making reusable components is that you tend to design the component better to make few assumptions, to have clean interfaces, to have few dependencies -- all of which makes for better code. Also, the reusable components get used in more places, so the code tends to be better tested.

  7. Throw exceptions or use assertions wherever your code might fail depending on how it is called, i.e. parameters passed or dependency on any external factors to the function/procedure. "Never happens" only exists in theory -- the exceptions make narrowing down bugs much easier.

  8. Keep a running todo list/bug list for things that need to be done or enhancements as part of your log. Chances are this list will never be completed, because as fast as you can complete items on the list new ones will be added. At some point, the list will consist of low-priority, or deferrable items, and you move to production or to a new release. How many years has MS word been worked on and is it complete now?

Larry Watanabe
++ Nice tips list. Good point about MS Word. :)
Secko