Are You Proud of Your Code?
An anonymous reader writes "I am downright embarrassed by the quality of my code. It is buggy, slow, fragile, and a nightmare to maintain. Do you feel the same way? If so, then what is holding you back from realizing your full potential? More importantly, what if anything are you planning to do about it? I enjoy programming and have from a young age (cut my teeth on BASIC on an Apple IIe). I have worked for companies large and small in a variety of languages and platforms. Sadly the one constant in my career is that I am assigned to projects that drift, seemingly aimlessly, from inception to a point where the client runs out of funding. Have any developers here successfully lobbied their company to stop or cut back on 'cowboy coding' and adopt best practices? Has anyone convinced their superiors that the customer isn't always right and saying no once in awhile is the best course of action?"
One thing to keep in mind when determining the quality of your code is that other people will most likely criticize the quality of your code. Usually saying that it sucks, when usually its just the person having their own way of doing things. I don't know why this is, I think its just human nature.
I've seen time and time again programmers taking over for other programmers' code and saying that the previous person's code sucks. Its like a right of passage or something.
the problem is... the client doesn't always know what he wants, and the continuous changing of the specs (and hence of the code) make it a mess. It gets worse when near release some 'minor' changes have to be included and a lot of code has to be written in a very short time. There's a big difference between the theory of the 'waterfall-model'(and it's derivatives) and reality.
Yes, I'm left. You have a problem with that?
I think quality in general has gone down over the years. In IT, I've seen that pushing quality is career limiting. There's definitely a lot of people making lots of money with the current state of things. I'd suggest you do what you can to improve your own code quality and soon you'll stand above the others.
Regards,
Art
If so, then what is holding you back from realizing your full potential?
This post should explain it. If you think hiring practices are discriminatory for minorities, try being like me!
Cherish YOUR THUMBS!
I got a catholic block.
When looking back at my first project, I feel the same. But I also think that I've learned a lot from it, and all subsequent projects were much, much better.
So, by being "not proud" of your code, you've made the first step towards improving it.
I'm trying to do that where I am and there's resistance from the technical directory and team leader, though most of the rest of the company, including the managing director wants us to go the way of standards and best practices.
We write and support a financial application, it's poorly designed (which has lost us customers), buggy (which isn't good for any application let alone a financial one), written in several different languages and is slow and almost impossible to extend. Not surprisingly most of the site and supporting software were written by the technical directory and team leader.
It's not like I'm trying to introduce the world either, only good coding conversions, code review, sign off and tickets for faults/ enhancements, migrating things to one language and most importantly when we write something new don't repeat the mistakes of the past. All this seems impossible since there both too stubborn despite what everyone else says, it was a major headache just to get them doing something as simple as putting sensible comments into their checkins.
Obviously posting anon.
Often times you can avoid a lot of this headache by spending more time in design. If you can flush the project out in some detail during design, and include the customer, more of those changes will be included in the original design before you ever start to code. Unfortunately, others in your organization will often feel like design time is wasted time. You have to be steadfast in your will to spend time in the design phase.
Getting good IT practices is about establishing a business professionalism in IT that is respected. This means that you have to explain to the business what "good" looks like, you have to understand the business drivers so you can put your challenges into that context and you have to talk to the business in terms it understands.
All too often IT folks bitch and moan about coding, testing, requirements, design time or whatever and how its all the fault of the business. This is victim mentality IT, the way to change it is to actually work out what "good" would be for the business and then work with them to deliver it.
This means the most important coding skill in successful IT departments is the ability to communicate.
An Eye for an Eye will make the whole world blind - Gandhi
The customer is not always right.
Otherwise, it would be the other way around, and THEY would be serving YOU.
AS you might guess, I hated retail.
Mmmmmm... Bold, yet refreshing!
I think lack of direction and leadership is why projects drift. hence why many OSS projects have woeful code, because they are hobbies and lack a firm direction.
If you mod me down, I will become more powerful than you can imagine....
I'm happy with my code. It's beautiful, modular, fast, maintainable, portable and basic tasks take me only a few weeks.
I'm also not particularly proud of my code, but to some extent I feel that I've been limited by the environment I've been placed. Where I've worked for the past few months, I've developed classes to move away from our four-year old database libraries, including database abstraction (instead of continuous reams of SQL), along with simple things like fixing SQL injection bugs (no, not saying who I work for). So while I'm proud of these little bits and pieces, I know that the large majority of the code base is still being developed in a fairly archaic way (and it's embarrassing), because the culture tends to ignore best practices - so I'm mostly developing better systems for myself. I'm leaving the company in a couple of weeks, heading home - and I know for a fact that most everything I've developed will simply slip away into the sands, because no-one has really paid any attention.
It's depressing. I think one of the only ways to keep your code fresh and maintainable is to have complete control over your code base - whether that be on a personal development level, or by having a good IT manger who's actually good at defining your class specs, along with pre and post conditions - and to completely remove customers from the equation, of course (even OSS falls under this banner, because you're not really obliged to keep anyone particularly happy).
one learns from his mistakes or else ...
I seem to find that trying to code more slowly than I could helps a lot. I'm not the most efficient coder there is, but I tend to produce less bugs and have more time to make better design decisions when I slow myself down.
I've had several jobs where I've found that although management never seems to approve of a slower process in itself, they do begin to see the values once they notice that my code tends to be less buggy than that of my peer programmers.
As for turning around bad practices... That's always hard. Culture is a tricky thing. But it helps to use analogies, lots of analogies! System grown too large with too many kludges? Compare to building a skyscraper on the foundations of a cottage. Management wants to speed up a project by senselessly adding more people? Compare to: "One woman can make one baby in nine months. Two women can make two babies in nine months, but two women can't make one baby in four and a half months..."
Be creative, be thorough, and be proud of your work. Always try to make the next iteration better, but also remember that sometime meeting the deadline is all that counts.
My two cents, I guess...
.: Max Romantschuk
In programming, there are a million and one ways to do the same thing. There is no right or wrong, only good & bad. I've seen some damn shocking code over the past few years, and I've written my fair share too. It's swings and roundabouts, it's up to you to learn from your mistakes and push yourself as a programmer to better your code quality. Keep in mind that what you right is what people use, and it's the difference between "computers suck" and "hey, that was cool!".
And as the first reply said, someone will always criticise your code. Decent programmers know this and still do their best.
ilovegeorgebush
No matter what I think of my code, I always know (pray) that it'll never be bad enough to be submitted to Worse Than Failure.
That said, I do revisit code that I'd written a few years back and think "WTF were you thinking?!"
Summation 2
At my last job, the standard response to any request was "Sure, we'll do that, when do you need it?" and it "HAD" to be done whenever the arbitrary date given was. There was no reasonable estimations of time or scheduling given. The desired end product was a moving target, changing daily. Sadly, the department that was most frequently shorted on time was QA. It took as long as it took to write, and when we handed our best (rushed) efforts to QA there simply wasn't enough time for any regression testing. After several buggy releases, patches, and fixes, upper management outsourced the new version. They were in for a shock when every minor spec change required several weeks for reevaluation and extended the delivery date, plus added thousands to the price tag. When I left there they were starting to lay the groundwork to get some actual structure and communications in place. Hope that works out for them.
I'd say that you should always be proud of your code and always do your best writing it. I don't mean that your code must be perfect -- nobody is perfect, but if under current time constraints, requirements and all other circumstances you can do better, then do it.
When evaluating your old code you should take circumstances into account to: may be you were in a hurry and "fast" was more important than "good" at the moment -- it's OK, it's a part of a job. Go back and refactor later. Besides, you are making progress as a programmer, aren't you? So, of course your old code may seem as "bad" and "dirty" -- it's OK too, It's just a part of being a *good* programmer and making progress.
May Peace Prevail On Earth
I know that with my own management, they're quite uninterested in quality - and entirely interested in the "schedule". They have a schedule, and want to meet it with our client (we're consultants) no matter what that does to our quality.
Of course, once the code is accepted by the client then by #definition it is good enough and changes to existing code are only possible if we can prove that the existing code is buggy.
Then there's the bizarre requirement that developers use copy/paste whenever possible. It's not as if we get paid by the line, but it seems that some of the senior architect types think that LOC matters. (no jokes please)
Add in management's desire to see as little change to things as possible, we get a very poor heurestic for Hill Climbing as a model of our software development "practices".
I have a lot of applications that are elegant enough. It may not have perfect validation for every field and not all the GUI bells and whistles, but it does what it's supposed to. I know my share of developers that spend a ton of time making their code elegant and beautiful. In one case, the developer spent so much time making their N-tier application with huge numbers of tables that were normalized to the bajillionth degree that they were finally let go. The goal is to meet the need, not to fulfill some inner desire to create art with lines of code.
Buzzword alert: Agile!
But seriously: Things like Test-Driven Development (TDD) and even Behavior-Driven Development have proven to be great approaches in software development.
Also, software management methodologies have evolved in a tight interaction between business (customer) and the development team. Take 'Scrum' for example... think 'iterative'.
If your superiors aren't convinced that at least the test driven part is necessary then you should seriously consider getting out of there.
You can still write crap code, but at least that crap code is backed up by a unit test. Otoh, if your test is crap... you _are_ the weakest link: Goodbye!
The answer to your question as to what is holding you back is complicated and multi-faceted. I'm sure you'll receive many interesting answers (and I look forward to reading them...hopefully it'll help me become a better coder).
From a pure Computer Sciency standpoint, remember that no code is ever completely bug-free...its mathematically impossible. Testing does not prove the absence of bugs, it only proves the presence of successful use/test cases.
But the number one thing holing me back is time. When I'm coding on the company's dollar, there's only so much time to spend in design, in writing test cases, in having someone peer review your code. And thus, there's just not enough time to spend doing things in the absolute, 100% correct way. There has to be some compromise.
I suspect that even if I had time, I would run out of mental energy first.
"You cannot find out which view is the right one by science in the ordinary sense." - C.S. Lewis on Intelligent Design
Edsger Dijkstra
Sorry mate, there is no hope
...their company to stop or cut back on 'cowboy coding' and adopt best practices?"
I didn't need to, I work for a competent company that aren't going to compromise the quality of their product on the whims of a single customer.
I also happen to think my code's great, thankyou very much. I couldn't imagine going through life thinking my code was awful. I'd lose the will to live and find another career.
realizing your old code is crap means you are improving. if you have less than 10 years experience with a language, chances are in 5 years you will think what you write now is crap too.
"If so, then what is holding you back from realizing your full potential?"
Time.
I'm swamped with numerous projects. If I had the time, I'd go back and fix the kludgey spaghetti-code nightmares that I've conjured up, but since they work for their intended purposes, other projects that are more important to my management-types get priority.
The best code I've ever had the pleasure of working on, was made when I worked for an actual engineering company. Not software engineering, but engineers that build physical stuff.
They understand the need for excelent documentation, rock solid requirements and that you don't get halfway in a project and change its direction (ie, "sure, the Golden Gate is halfway done, but we'd actually like it to go from Lime Point and meet up with the Bay Bridge around Treasure Island Road"). They understand that some things take half the time to do but are four times as expensive to maintain, and they prefer quality over quantity.
Least the ones I worked with
We do not live in the 21st century. We live in the 20 second century.
Yes.
The product I work on at work features all three. It can be 'interesting' to maintain sometimes. That being said, it's frequently possible to rewrite sections and management sometimes listens to the programmer types and has let us restructure things sometimes. For example, we've mostly gotten rid of the RPC stuff.
When I want to satisfy my urge to work on good, clean code, I do some open-source work. Open-source tends to have that, because nothing else tends to work for very long.
PHEM - party like it's 1997-2003!
This GP is obviously speaking from many years of experience, and not just in IT.
And did you exchange a walk on part in the war for a lead role in a cage? - Pink Floyd.
The only thing i can advise, is have a small personal project aside. Yes program on your own (or join an interesting Open source project), when the project will be finished is not as important as using all the proper practices while doing it. That means flexible design, patterns, comments and such. Show yourself at home that given time, you can actually make good code.
Then maybe after a while some of those good habits will seep into your daily work. Very few companies will care about the code, they usually only care about the deadlines.
How often have you solved a mathematical problem, and the whole solution has looked and felt right, not just the answer? I have always enjoyed mathematics for this reason, and take the same approach in the way I write code. To me, my code just looks and feels right.
I realise that others don't feel the same about my code. I have often been criticised for not enough code documentation (but then, that usually means that someone can't understand code, rather than just not understanding my code), and I have often been criticised for not using temporary variables, but I am rarely criticised for delivering unmaintainable code that doesn't work.
Any fool can talk, but it takes a wise man to listen.
...to somebody, for some reason.
There is no Holy Grail of code.
What is good coding style to me, may be anathema to you.
Ok, there is utterly shit code (which probably accounts for a fair proportion of all code if my life experience is anything to go by), then there is 'run of the mill' code, then sometimes rare glimpses of 'great' code.
Great code for me is when you see it and understand the programmers intention, and you think: a) I would have done it that way, or more likely b) if I was smarter I would have done it that way. You learn from great code, if you're already a good coder.
I think the greatest obstacle to 'great' code is 'language fascism'. Some languages are better than others, that's true, but they way some people carry on you'd think it was only possible to write 'great' code in their language of choice. This behavior is generally exhibited by those that can code in one (or at most two) languages only.
I'm generally proud of my code and am happy for others to scrutinize it. All that means is that I spent the time to make it as good as I could withing the prevailing time/cost constraints.
I used to write a lot of assembler. Some of my colleagues used to think it was cool to use obscure instructions, in unintended ways, just to show how 'cool' they were at flipping the registers. I never subscribed to this idea and always used 2 or 3 common instructions instead of one 'neat' instruction. Performance never seemed to suffer and maintenance programmers were eternally grateful.
After a long time in the software industry, I came to realize that Code Is Communication.
By far the largest part of the lifespan of any code is Maintenance. Code has to be intelligible. Not just through commenting, but in every construct and usage.
Think about effective communication. The effort to be clear will improve what you are doing. It will also make your mistakes evident so you can correct them.
Rich And Stupid is not so bad as Working For Rich And Stupid.
Code is the killer. The less if it you have the better off you are. You can reduce code by a good architecture and experience.
Bad code is usually a result of either inexperience or through a lack of time (rushed project timelines = bad hacks).
Recognising that you've produced some bad code is the first step to absolution. Try understand why you produced bad code and improve yourself. Rushed project timelines can force you to code badly however maybe you need to be more skilled/effective at a wider range of frameworks allowing you to do more in the time you are given.
Gather around me kids, for I am sitting here in my 18th century rocker to tell you a story about a programmer.. A good programmer..
I used to work for a small-sized IT business; a popular community that housed some 130,000 members. It began with the loss of a fellow employee who had basically coded 99% of everything on the site. To that date, everything had worked fine. We had some issues every now and then, but a backup system helped us from getting hammered if anything bad happened.
We never worried too much about him leaving because, for starters, I had some experience with the code/system. In addition, the now departed programmer had left a comprehensive list of features and explanations of his system that would help any programmer (that would replace him) to get around any tricky problems that would/could occur.
Unfortunately, I won't go into what type of business this was, but let's just say that it's not typical programming skills. When I began looking for his replacement, I realized how hard it was to get someone with adequate skills and all the knowhow that was required besides the actual programming. As we were on a tight budget, it was important for us to find that one guy who didn't expect a zillion dollar salary. Typically, that would be someone who shares our interests, a recent graduate who knows his ways around programming.
Eventually I found one guy who claimed to be all that we wanted. After a month, it turned out that the guy was more and more frustrated over how things worked at the company. He disliked about everything about the code and spent most of the time cursing. At this point, I started to believe that our entire code sucked.
Roughly a month later, we decided to rebuild "everything" so that he could have his ways around the code. Since we only had one programmer, I had to comply because it was an important role in the company. My limited coding skills provided no extra help in evaluating our current code, so I trusted this guy since he seemed to be very thorough and experienced. Also, I was promised it would take no longer than one month to do all this.
What a fool I was. If it ain't broken, don't fix it. I should have known, but a company on a tight budget and no one else with good programming skills forced us into this move. Turns out, our super experienced programmer needed not one month, but two, three, four, five, six and seven months to complete his task. By then, he had reprogrammed almost everything and merged some of it with the old code. We waited for the relaunch of our software with great anticipation. Three! Two! One! Go! Oh crap, everything f*cked up.
Following the launch of our new software, we had months and months of trial and error problems. Members were complaining and nothing went in the right direction. Eventually, we were essentially bankrupt and had to let the superb programmer go. The guy who had left us with a huge mess.
When I read this Slashdot story, I had a smile on my face because I learned that a programmer can only know that his code is perfect by the response of many other programmers who can view his code (i.e. open source). Some programmers seem to think their code is perfect and that occurring bugs are caused by impossible-to-foresee problems. The point of my story is that if you truly want to know if you are a good programmer, you must let a lot of programmers decide that for you. Unless your name starts with J and ends with ohn Carmack, of course.
Full Tilt
If you have management that doesn't really understand what programming and programming personalities are all about, you can get internally inconsistent, half-thought out ideas as well as much pressure to do it 'now' instead of 'right'. If your programming team is more junior and easily swayed by the management's idea of software development, then there are no checks and balances and you get rushed out, low-quality code, with a never-ending cycle of quick patches that is ugly, bug-prone and a nightmare to maintain. And that's assuming you have a quality team of junior programmers. Mix in average or below-average programmers and......I shudder.
I work with/for some French guys. French people tend to have bright ideas in the most unpleasant moments (#include "irony.h"). Nevertheless, I was able to cope with the requests, and as a technical leader I was able to impose some of the solutions. The result is very neat, and I'm really proud of it.
I will say this: I am convinced that some better solutions exist for some specific problems; I do not agree with some of the imposed constraints. But: measure the quality having in mind time and cost.
So yes, there are nice projects outside.
Saying "no" to the customer is not normally what's called for. Instead, your team must clearly state the total cost of any proposed change. Factoring maintainable quality into cost estimates is an art that an organization must learn if it wants to get asked to do another job after the money for this one runs out (project drift leads to no results leads to unhappy customers, as you well know). When the customer responds with "Well, isn't just as simple as changing X into Y?" then that's when you get to say "no."
What do you mean they cut the power? How can they cut the power, man? They're animals!
My advice would be to read The Pragmatic Programmer book by Hunt and Thomas. It provides the best blue print I have seen to solving the problem for you.
You may not be able to implement all the changes at once but you will find that you've got more authority than you realize.
You may not even agree with all of it, implement what makes sense and your code will improve. I've found with my friends that the longer you've been coding the more sense that the book makes.
Man Holmes
Which means that I tend to get married to design decisions I made and have to deal with the inevitable consequences when what looks graceful programmatically is a nightmare when converted to a UI for the end user.
One of the interesting lessons I took from Mac OS X and GNOME, probably the two best mass market UIs on computers these days, is you can't always orientate your applications towards future expandability, because adding modularity and extendability frequently results in a poorer user experience.
You are not alone. This is not normal. None of this is normal.
> Have any developers here successfully lobbied their company to stop or cut back
> on 'cowboy coding' and adopt best practices?
For me, it was a matter of defining my own personal set of Best Practices and sticking to them. Something as simple as standardized variable naming, or consistent formatting. As _I_ set standards for myself, I shared them with fellow coders and we'd come up with an unofficial set of Best Practices. None of these things slowed my coding down or cost the client a cent, but they made all of my code more readable TO ME and helped me to cut-and-paste code (reuse, recycle!).
What's more, it made me feel like I was coding better than I did when I was in my anything-goes, cowboy days. And guess what? I _WAS_ coding better!!
Guessing from your post, "I enjoy programming and have from a young age (cut my teeth on BASIC on an Apple IIe)." , I am going to assume you are a bit more seasoned as a programmer. Well, one the best things to do is to drop the old code. Java may have been around, but it keep up pretty well. If your code is slow, write cleaner code. Object oriented coding the best way to go. Keep methods short and clean but board and ensure to have overloaders. In today's day in age, code must be very dynamic, static methods are thing of the past. They are still very powerful and good tools but your code should not be based around them. Well I suppose I should get back to code and will do my best to keep my code nice and clean today.
Which is why the water-fall model is rarely a good match for software development.
And, incidentally, also while outsourcing (especially off-shore outsourcing) software development is rarely leading to success stories.
In our organization we went from spaghetti code to excellent code in under 24 months. The catalyst were the introduction of testers.
They validated our requirement lists and reviewed our system designs. As (us) software coders got the knowledge that their code were in for in-depth testing they started doing proper design work, peer programming and later module testing. Then, with the help of the test team, we started to maintain KPI:s about the process and got better delivery precision of the software.
As the number of bugs dropped we didn't need to patch-and-ship code. Now we release bi-yearly instead of bi-monthly which leaves even more time for QA-work.
Testers doesn't do quality - they are a catalyst to enable quality in each step in the software development process.
Break the sound barrier - bring the noise.
in a shoe box for you. Set deadlines. Always too few programmers. People who don't give a shit about anything except you get the product out and sold. That'd be your boss. Crappy code. Nice wrappings. And marketing department spends 4-7 times more funds than the actual programmers. But hey, don't worry, in a month or two, nobody remembers the project you worked on. And the sad code goes the way of all bits.
Two thins I can suggest:
* Keep things small, and by small I mean one procedure or function does one thing small. Don't pack it with extras or this or that. KISS it. Using a language without procedures or functions? Space things out and label blocks of code with comments. If you can break that code up in to seperate files with includes then do so. Test all the peices seperatly.
* Documentation, don't put a one liner up at the top of a block of code and call it a day. Be descriptive, say what happens, what comes from where, whats passed in and whats to be expected in the return. The more you spell it out for someone and yourself down the line the quicker the light bulb will go on when someone or yourself has to review what you did several months or years ago.
~~ Behold the flying cow with a rail gun! ~~
I often use "Programmer: Alan Smithee" in the comment header
Yes, I am proud of my code, or maybe not always the code but at least my coding. It's not always possible to create beautiful, well mantainable code. I try to, but sometimes there's just not the time.
... it's a pretty large department for such a small company, as we write all our inhouse software ourselves and have been for the last 5 years. When I came to work here, the codebase was about that old -- 5 years -- and maybe a two dozen different 'cowboys' had been writing the software resulting in a large heap of steaming shit. They were not centrally coordinated and everyone of them was doing things in his own style either out of laziness of ignorance.
... she had no idea that it was a mess, the company being a travel agency and she having very little knowledge of automation herself. I used a difficult coding project (connecting to a GDS, the guys that administer plane reservations, car rental, cruises etc) and a general optimation project ( the application was becoming very slow due to all the bad programming going on ) to build her confidence in me and asked her to put me in charge of code sanity. She did.
... and I hope I'm succeeding. Gave them code standards to work to, asked them to clean up the code base where they stumbled upon crappy pieces, moved from Visual Source Safe to Subverion (thank god!) and started regular meetings once a week.
Yes, I have convinced my employer to stop allowing cowboy coding practices -- she didn't even realize it was happening. I'm currently head of the programming division of a inhouse IT dept for a large travelagency specialized in cruises
Anyhow, I managed to convince the CEO that there was a problem
I am now trying to reform the bunch of code cowboys that currently works here to a well disciplined programming team
The codebase is still very messy at places, but many basics (use of one and only one database class e.g.) have improved very much and I think the people here are happier for it. It's much less frustrating to work on nicely formatted code that doesn't have braindead sections that aren't commented.
To make a long story short, if you're not proud of the code you write, make sure you improve it.
---
"The chances of a demonic possession spreading are remote -- relax."
I came to the conclusion that you are the only person who is ultimately responsible for the state of the code you write is YOU. Nothing else, no one else.
:)
Project deadlines, crazy customers, chief engineers, thunderstorms, even a Tsumani. It's just you.
Reason:
if you write buggy code, whatever the reason may be, it falls back to you. You will have to fix it, you will be MADE responsible for it. EVERY time. No one asks WHY you did it.
And you don't like it yourself, which is a bad thing. One should LOVE his work, not hate it.
If you force yourself to push everything else into a state that enables YOU to write good/nice/beautiful code, you will gain something. If not, you will suffer. That's about it. It has nothing to do with other people, with companies, with unemployment.
So, get up, and write that good code. Whatever it takes.
Good luck
"Has anyone convinced their superiors that the customer isn't always right and saying no once in awhile is the best course of action?"
No. Welcome to the real world. Feature creep is unstoppable.
At my work, we don't do cowboy coding. If we do, people will die. So, yes, we've said 'no' to customers and established best practices - long ago.
When I look back at my first project, all I can say is no comments....
I've found that, no matter what they say, a customer would rather have a program with five features that work properly, than 50 features that are buggy.
I also agree with the guy that said slow down.
Switch to a langauge like Haskell. It will seriously improve the quality of the code you produce even when you go back to your original language.
I find that it's really up to the programmer to come up with the "Best Practices" to coding. I personally hate it when I see code that has 25 nested IF statements. I remember back in High school, one of the other students named is variables X, XX, XXXX, moook, Y, YYY, etc. (it was like reading PERL for the first time.( moook = X + YYY * XX / Y). He was able to read and understand that block of code. Needless to say that I had to stay up late one night to finish the project because he was sick and the project was due the next day. What I learned from that experience is that no matter what every one is going to have there own standards of coding, If you are not happy with the way you coded something, take the time to decide what works for you and clean up the code.
An anonymous reader writes "I am downright embarrassed by the quality of my code. It is buggy, slow, fragile, and a nightmare to maintain."
Well look on the bright side, your employer is the largest software manufacurer in the world, whose OSes are installed on nearly every computer made, and they pay well. So what's the problem?
Besides, your sloppy code is doing me a favor. When I'm using your database and something breaks, I can blame you and everyone will agree it's your fault. Don't worry about it, all your fellow employees write bad code too.
-mcgrew
Reserved error (-1517); there is no message for this error.
mcgrew's razor: Never attribute to stupidity that which can be explained by greedy self-interest
There is no incentive for programmers to produce code that they are 'proud' of.
The whole programming industry is based on shipping out mounds of steaming code that 'works' and 'meets the requirements'.
Programmers have no concerns about liability either, they can't be sued, or held accountable. There are 'metrics' used by some companies (# bugs, # lines/code/day), but these are just meaningless numbers. Anyone can produce 'bug-free' code, but will it meet the requirements, will it run fast?
If they don't build it right on the first iteration, simply try again in a service pack, or better yet, build 2.0, and charge users for the priviledge.
Software Engineers on the other hand, have a different problem. They can be sued, they can be held responsible, and more importantly, their whole education is based on the engineering principle of 'if I don't build this right, people could die...".
While the programmers education is based on how many lines of code they can 'produce' in a given timeframe.
Code Complete - Steve McConnell - this highly regarded book discusses the nuts-and-bolts of software construction, and is a pleasure to read. I'm not familliar with another book that discusses software development at this level. Worth picking up (get the second ed).
I'm content with most of the code that I write for myself, whereas code that I write professionally (read: on a deadline) more frequently leaves something to be desired. My own code is documented (manual+comments), usually quite efficient, and if there are bugs in there usually they are not very serious (forgotten null pointer checks). Of course, when dealing with my own code, I can refactor it as needed and as I please. At work, that's not always possible.
Visit http://ringbreak.dnd.utwente.nl/~mrjb/growingbettersoftware to download your free copy of the book
Generally, whenever I complete a set of code, it's perfect. It's flawless. It's the stunning pinnacle of coding, and it should go on some kind of display page where everyone can marvel at it, worship it and experience its perfection so they may find true enlightenment.
Usually, when I unearth the code 6 months later I wonder if there's any way to get this horrible piece of hacked crap out of the CVS somehow...
It's just that, well, you learn. You improve. Yes, even after more than a decade of coding, you still learn and improve. You learn new tricks, you learn to use new libraries, and you discover better and more efficient ways to use them by using them. So generally, yes, I'm proud of my code. For a while.
We used to have a Bill of Rights. Now, with the rights gone, all we have left is the bill.
If you truly understand software architecture and design, and the rhyme and reason behind the code you're writing - then you should be comfortable with your own abilities and skills. "Cowboy coding" is never going to be a directive of management, and is an entirely different problem from the "get it done" mentality. Any manager is going to insist that systems not be overengineered, and that objective consistently is client satisfaction. The customer *is* always right, and if they're paying for crappy, bloated, slow software - well, that's what you should build for them.
Obviously, this is probably pretty inlikely. Given that a) you're a talented software engineer and b) the client doesn't want you to build lousy software, I would say your problem is simply poor project organization and management. Arbitrary deadlines, poor scope management, refusal to consider bottom-up estimations, no rhyme or reason to task management, and no system of design and review of software will create that "Old West" mentality of software design where chaos rules. It's often not that there's a lack of interest in order, but a complete lack of knowledge to implement it.
If your group has a project manager or architect, they should be responsible for understanding these problems. If you don't have someone in this role, then I would suggest that you pry yourself away from your compiler for a bit and get a bit of an understanding of project management methodologies, SDLC, and more modern software methodologies like Agile. Understand why the process working above you is so flawed, and either try to assert change in this from within, or use that knowledge as your career advances.
The client (and your boss) will never likely see your code. Your shame (for lack of a better word) is not going to gain any empathy unless you can direct your attention at the problems that have put you in this position while at the same time showing how a more structured team environment when it comes to software can be better for the business.
StoneCypher is Full of BS
In what other line of work does principal construction begin before the customer has defined what it is they are ordering?
A software is not a product in itself. It's not like an "apple" or an "orange", it's more like a "building" or a "vehicle". A building and a vehicle can be the solution to many different problems. A truck doesn't necessarily solve a customers problem if he's looking for a way to transport people in style from A to B.
But while I think that most people understand this, they have a very fuzzy and indistinct concept of the cost of changing the specification once construction has begun because you can't walk the customer out to the building, point at the construction and say: "To make the changes you require we will have to tear out that wall there, remove all the concrete laid here, that will require a week and scrap more than four tonnes of construction material".
This is where software engineering comes in: With a good model and by sticking to the principle that you begin with a specification from which you construct a series of test to see if the specification has been fulfilled. From the specification a design is made. The design specification is used to implement tests to see that the design has been followed. From the design the code is written and on the code the tests are run.
Now when the customer changes the specification you can look at the design and the code and see (hopefully) how substantial the changes will be and what the cost will be. Your customer will thank you for being more accurate in your estimation, for pointing out the costs (which is the only thing your customer will care about, remember that time is money and is just another type of cost).
I have so far only worked in one workplace where this model was used and it was used very successfully in my opinion. Writing all those documents surely sucked, until it came time for implementation, which was frighteningly quick and painless. The ultimate pride for the well documented, well planned, well concieved and tested code has made me utterly incapable of being satisfied with any other way of working (which is why I've switched jobs a lot).
Changing to a structured approach to working is costly, but the benifits are bountiful and will ultimately save money and time. I can almost promise that while you might lose a customer or some goodwill of a few customers in the interim, in the long run, the customers will flock to you since you are delivering on time, the functionality they asked for.
Badgers, we don't need no stinking badgers! - UHF
"Has anyone convinced their superiors that the customer isn't always right and saying no once in awhile is the best course of action?"
Good luck with that one. Successful technology companies use pie in the sky marketing. Reality does not sell. When you are not saying yes I can do it faster and better then you are whining as far as CEOs are concerned.
I have a great career and made lot of money writing crappy code. My bosses have always loved it because I am fast to produce an end result. I call it prototyping and constantly remind my employer that I am creating a demo of what can be done. But in the end the demo always goes into production. I have seen several programmers much better than I get fired because they could not bring themselves to lower standards. I guess I'm just a code slut.
If you want to be proud of your code, you need to say no, and to look realistically at what your being told to do. Then you need to think of a way to achieve the aim without cludging it, basically your contuaally refactoring, rather than just adding functionality
I am downright embarrassed by the quality of my code. It is buggy, slow, fragile, and a nightmare to maintain. Do you feel the same way? If so, then what is holding you back from realizing your full potential?
My boss.
"We don't do design". Of course I tried anyway, but it had to work with his broken database "design". And it was never really designed for the features he wanted crammed in, because his ideas kept changing from one week to the next. The features might have been possible to integrate with the (shadow of) design, but he wanted it done "by next week". Of course it's a nightmare to maintain.
Now, testing on the other hand... Testing always started out with "I'm going to put the current release into production next week", followed by me frantically commenting out half-finished pieces of code to get the thing to even compile. When the testers didn't have time that week, the roll-out got postponed for one week. When the testers still didn't have time, the production system became a very realistic test environment. It wasn't unusual to have him roll back to the old version, because the new one refused to even start (it barely compiled, what do you expect?)
Is anyone surprised that I'm looking for a new job? That I'm looking for something that doesn't have anything to do with development?
One of the main problems I've experienced against clean/solid code in the industry is that new features will always please management more than debugging and cleaning code.
For instance, in my weekly tasks update, my immediate superior will always prefer, and thus push for, that I say I wrote new features as he enjoys saying "the system now does this" to his superiors. He doesnt sound as cool saying "we spent a week debugging what was already there".
With time the code becomes unmaintanable and you end up having to rewrite the whole thing, or at least large parts, in order to make it progress beyond a certain point.
Ive seen some managers having more foresight about this but most of the time they'll fall in the "new feature" trap...
Good leadership is the really hard thing to find.
Most project managers are useless middle management.
Your co-workers are usually yes-people who take whatever hilarious crap the corporates think up and pass it down to you.
They, in turn, are playing a public relations game trying to look good and not drop the stock price.
There is no plan.
A product is an interpretation of a needed technology, designed to make profit, not work well.
These are all insoluble problems of the way the technology industry works.
I've learned this the hard way at my current position. The powers that be simply cannot think through projects in a technically foreseeable way, and they have a habit of not telling everything they intend to do with the application until after the first beta. I'm learning to plan on worst possible scenarios with everything I do.
All this means is they have a fixed idea of how it should be done and cannot bear to see it done any other way. Frequently (as you found to your cost) the final product is the result of trial-and-error techniques. It's very likely the original programmer thought of and tried the way it should be done, then found the flaws in this approach and adopted methods that produced the results.
It's equally likely that some of the ugly code in any implementation is to get around bugs in the development system, programs it interfaces with or even the O.S. itself. The inexperienced programmer only sees the ugliness of the end result, they assume that the original programmer was dumb/lazy/old-fashioned (because that's what they see in themselves?) and in their arrogance assume that there's nothing worth keeping and only a complete re-write will meet their high standards. If only this was Usually none of the "experience" is documented - only a description of what a module does, not why that method was chosen.
Of course the BIG mistake is to only have one programmer. What happens when they take a break or leave? Everything stops.
politicians are like babies' nappies: they should both be changed regularly and for the same reasons
As long as my code is the only freely available code to do a particular task, and anyone is free to submit patches to refine it, i don't mind to publish it.
Afterall, it is the best way to refine it. My ego doesn't suffer significantly when i meet a better coder.
I just don't like people who criticise but don't submit any fixes.
Patents Drive Free Software as Hurricanes Drive Construction Industry
I work as an IT consultant in Denmark. Here I come accross a lot of code from other companies, customers and even collegues. And by the Gods of the Computer Chips: Code SUCK!!!!
No error / exception handling. No data validation. And NO FUCKING COMMENTS!
A collegue even removed the Mutexes in a multithread application because : "Data sync takes up too much time.." - result that a very unstable server application.
Just had a "attitude correcting" talk with my boss. It seems I take my job and quality too serious and therefore make my collegues look bad. I was then ordered to "Don't give a shit" about the job and the quality.. QUE?
Before joining this company I have written server software which runs 24/7 ( and has done so since 2000 without breakdowns ). Even on Emb. platforms. And now some idiot tells me that I produce too good quality?
Never buy Sony CDs - they will open up your computer to anyone..
In my experience (managed a 300+ person team producing millions of lines of code each year), best practices don't come from bottom up. Better practices, like code standards, documentation, etc. can come from the bottom up, but best practices take lots of man-hours, otherwise known as money, invested over years. This will only happen if executive management sees value, invests steadily for years, "encourages" sales and marketing types to play nice while some investment money goes into strange sounding software practices rather than into new products or advertising, and development managers spend their time creating a culture that supports a much higher level of engineering teamwork. Executives have to have the long view via the need to retain large demanding customers, support complex products for long periods, sustain a monopoly, etc. Your run of the mill web site, widget, or IT wonk support sees little value in truly best practices for software. A little better - OK, but it better be quick (says the CEO) - but not best. So if you truly want to experience best practices - and someday maybe push the envelop into uncharted territory for team results, go find a different company, and select them based on their industry reputation for software development. If you ask, you can find them. Otherwise, learn to love better practices.
Most the code I write is written ad-hoc, under the gun with no time for refinement, little testing, never get a chance to loop back and do it better, never gets re-factored, only gets improved if it happens to needs to be patched for a bug.
So not a line of it! I could do better but the circumstances under which it is written don't allow for it.
Power Corrupts,Absolute Power Corrupts Absolutely, leaving one person(group)in charge is absolutely corrupt.
I have really gotten onboard with using tested and trusted 3rd party frameworks, or using code generators. I can create about 30-50% of my code using generators. Code generation not only eliminates simple bugs, it enforces a standard practice across the group and keeps the code clean.
All code sucks, unless you did it, right? My code, although it might not be the most elegant, usually works, most the time. I tend to
create very basic stuff that I believe anyone can read and understand. Code that works is a dime a dozen, code that can be maintained
by others easily is worth millions!
1- Yes, I am definitely proud of my code. I have my style, and I'm proud of it. Personally, I tend to code in a "vertical" way, where I will dig a precise topic until no question is unresolved, and where my solution will be the best for many problems that might arisen. My code seldom need rework to do different tasks, and it's quite stable, to the expense of a horrendous amount of time taking to ponder and code. My good friend programmer who works with me is a "horizontal" programmer, he will take all facets of a software in its entirety and will do what is required to make the software work, however, he seldom thinks of all the implications, and his code will frequently need rework, but he can achieve a whole projects in matter of minutes. I know of two other types, one is the bull-programmer, you aim him to some goal, and he will do a straight-run to the goal; do not ever ever think of changing his aim from that point, it's your problem if your aim was not good. Finally, there is the back-bencher, the one who will do what he's comfortable working with, at a precise pace with a precise result, but only working with something he already knows.
Note: these are made-up names, used in my company
As you might understand, each coding style has its own advantage and disadvantage, and there is no real answer on what and how to do something. My kind of programming does not bode well with coding competitions, as I overthink stuff, and frankly, I don't mind, as it's not required for my job anyways. I constantly look at ways to better my code, to understand better algorithms, to add to my personal toolbox. I read a lot on coding, I explore open source projects, I look at what I like and what I hate. I use coding standards.
2- Cowboy practices from companies are not compulsory, but sometimes, they exist. You want to achieve goals at precise times, then, work from there. You might wander around at every version but try not to change in between versions. Even if every week and version, you do a 180 degrees, at least, you have a product that is more and more refined. More changes means more brittle code, that's the drawback, but that's the way it works. Eventually you need to ask for a few days to clean up everything. That's life.
3- Clients are the king. You can convince them their changes are not for the best, but it's all through dialogue. If they are paying and if they want changes, you got no choice but to abide, or look for another contract or another job if you're tired of that.
And if there is one thing I've learned over the past 6 months (having no prior experience in management), its that if you do up front design, the code is about 10x easier to write for any non-trivial problem. I dont mean going into full uml diagrams and that shit, as my prof in software engineering said "in ten years working in the field I've only ever seen one person willingly write uml specs before programming, they were russian". But coming up with class interfaces and the overall breakdown of the code before writing it, will result in code that is much more modularized and reusable, not to mention easy to write. That and practice makes perfect. Shit my code from 6 mo's ago is horrifying, and in 6 mo's I'll say that about what I'm writing now. Practice,practice,practice. The only other thing I can suggest is find a team you enjoy working with. Even if the code is not pretty, at least you can have a good time at work. Thats by far the best part of being in a very high growth startup. ;)
My code style has improved a lot the four years I've been out in the workforce. We were fortunate enough to have somebody at the start of the project who really cared about methodology, metrics and style, and it has paid off. We've been using unit tests and code reviews all the way through, together with fairly powerful tools (IntelliJ has nice refactorings). While my coding quality still varies, it is no longer where I'm embarrased, and some of it I can plainly say 'this is the way to solve this problem.' The three practices I have found the most useful are:
1) Always document your functions and variables[1]. I don't agree with Use The Source, Luke. The source says what's being done, not why, and if the code has an error, you'll translate that error into your thinking about the program rather than fix it. Documenting the code *before* writing it lets you think about it first and forces you to be explicit rather than clever.
2) Write unit tests first (this is the one I find the hardest to follow). This encourages smaller portions of code and clarifies what the code should do. Plus, it gives you a place to do cowboy programming:)
3) Refactor mercilessly. Any time I cut-and-paste a chunk of code, I regard it as a candidate for refactoring, even if it's just a couple lines. Making it a new method adds testability, reduces cut-and-paste errors, increases documentation and makes it easier to use that third time.
I'm applying it as I go along to the OSS project I'm maintaining, and it helps both me and others.
-Lars
[1] Except trivial getters and setters. Maybe.
Most businesses only care that it works! And works "Well Enough" for their delivery deadlines!
Yes, I was actually trained in good coding practices and the total lifecycle costs of software development, but most places only care about checking the "Done, now ship it" box. A very significant indicator of whether or not they care about code quality and style is this: How beefed up is there QA?
If the QA effort consists of a bunch of people doing things manually, they don't have time to check code; only functionality.
If the QA effort is primarily automated with tools to parse and check code, as well as run serious automated testing, then you have something there.
I'm afraid many shops are now in the mode of "just code it and get it working...we can clean it up in maintenance..."
Supreme Granter of Doctor of Obviology Letters ("A FIRM Command of the Obvious")
I find that I am usually ashamed of my code when I am rushed. I think that its a sign of my long years of programming and learning as I went.
When I am rushed, many of my old bad habits come through and the most recent "best practices" fall by the wayside.
I know a lot of developers suffer from this as well. Its a lot like fighting, the habits with the most hours behind them come to the front when shit hits the fan.
I also noticed a common thread that refactoring a second or third time always makes huge improvements, but then later iterations start to have diminishing returns..
One good way to slow down would be to put more eyes on the code. Get a projector and stand up in front of 2 or more or your peers and explain the code. Learn to take criticism and learn from the experience.
As a programmer you are often building an application for someone else - someone else is paying the bills, and they want to see value for money. Hence you need to be delivering value, this can be in straight code, but it can be in other ways too.
Generally however, a lot of projects consist of building one application for a specific purpose and then leaving it as it is - this is the problem of the business, not yours - they have no plan for an evolving or expanding system, they want something that can get them kickstarted and able to fund enough money to do their next development, a bridge they will cross when they come to it. And fair enough, usually budgets are so tight on first implementations that an extra 10-20% could make or break that first stage, and without a first stage, the project will go no further, no matter how elegant the code is.
Therefore, as someone who may code something more elegantly and more maintainably, but more slowly, you become less effective and hence less valuable to your employer, than someone who slaps it together in half the time and ends up with a nightmare of spaghetti code and hacks. While the latter approach may make the coder feel they are irreplacable as they are the only one who understands the system, such a system will often be treated as a prototype once funding is secured, and rewritten from scratch.
The only way out of that situation is to avoid it in the first place - don't be forced to work to tight deadlines and have to compromise your work in order to fit a business plan. However, it's a very lucky artist indeed who can pick and choose his work, and is given the time and money to do something that will last. Sometimes we have to make this compromise, but hopefully with more experience you'll be able to negotiate a better position.
I mentioned at the top that you can give value to your employer in other ways: documentation, stability and reliability of your code, hassle-free maintenance, the ability to provide long-term development plans and milestones. These are only useful if your employer is also planning that far ahead. Until then, you may have to concentrate on trying to plan your code ahead of time and anticipating and second-guessing what your employer will want 6 months or 6 years from now.
For nearly every company that I've worked for, it's been the same old story. Get it done as quickly as you can, cut as many corners as you can so that we can keep more of the budget by keeping development costs down.
Testing? What's that?
If you can't test it as you're building it you don't last. If you complain about time-lines, you'll be out the door. If you gripe about the feature creep, you end up on the Sh*t-list and they start looking for ways to let you go or force you to quit. Quality left the building years ago in favor of down and dirty coding that simply makes it work. The last project I worked on for a company, I was only given 12 hours to go from drawing board to production. After getting it done and functioning in 14 hours, I got my butt handed to me by a pointy-haired doofus that said I wasted valuable time and needed to "better manage my time".
I'm supposed to listen to a guy that still uses IE as an FTP tool?!
After I quit, it warmed my heart to see that they ended up hiring three people to fill my position.
I tried to be proud of my code while in the corporate world, but it wasn't until I left for a smaller private company (less than 100 employees) that I finally got to a position where I can take pride in the code I write. I can do all the things I know I need to do. I can now document things, comment my code and test until I'm sure that its solid before putting things into production.
-Goran
Carpe Scrotum - The only way to deal with your competition.
Isn't taking every penny they have the entire point? Please, no lectures about sustainability -- we all know that most businesses run themselves into the ground pretty fast anyhow. It's better to get their money from them while they have it than during the 20 years they spend settling their debts for pennies on the dollar.
I scream. You scream. I assume that means we're both acquainted with the problem. We proceed.
I'm a contractor. I do what the client asks, and essentially it comes down to this trade-off: good, quick, cheap. If they don't allow you the time or resources, then they didn't really want good. If you feel you did as good as possible within the constraints, quit worrying, and stop being embarrassed about your code.
threadeds blog
It's one thing to run your business systems well. But I do have to point out that hacks to code and systems are required from time to time. If your business is doing anything beyond just using single package A, there is always integration with other packages. Things go wrong. People have to recover somehow.
I'm particularly... well I'm not proud of this, but I feel accomplished for figuring it out. The pipe command of << stopped working on my jumpstart, and while I don't know WHY it happened, I figured out what it was breaking and worked around it. It's annoying, yes, but at least now google will hopefully pick it up, and the next person who has to do the same ugly ugly hack will not be alone.
In the comic, as a sysadmin, I'm the one who's breaking the branch that I'm tied to, so instead I'm tying it to 10 other small branches that would break one at a time, but collectively, hold together. At least, sometimes that's how it goes. But at least the next person who has the error knows that doing this might work for them.
Gonzo Granzeau
"Nothing the god of biomechanics wouldn't let you into heaven for.." -Roy Batty
Ok, so this might sound a little harsh, but you see, the solution to your problem is this: code better. It really is that simple. Yes, it's nice if you can anchor things with project managers or whatever you have above you, but it's not really necessary.
Having problems with bad interface? Design better interfaces. Jumbled, complex code? Refactor it. Slow execution? Improve the algorithms. There's basically no project that takes longer time by doing things right, more often than not the opposite is true. A good refactor can save tons of time.
There's no magic bullet, however much support you get from superiors or coworkers. The only thing you can do is simply write better code.
...as if the guy who is going to maintain it is a 6'6" tall two feet wide bodybuilding psychopath who knows where you live.
My opinion? See above.
I often feel the same way about the code I write.
I've also been involved in projects with 'dynamic' specifications, which required a lot of re-writes and architecture changes.
I bet when you write your code, you seal it in and make it as efficient as possible, only to discover that it is not compatible with the new specs and the required hacks make it ugly and buggy.
But there's a positive in every situation. In time, I've discovered that my code has become more 'spec-change proof', I started to anticipate changes and was forced to write more modular and abstract code.
1. When designing your classes or modules, make sure you make them truly 'unaware' of the rest of the world - create small modules or 'components', which can be re-used or shuffled around to adapt to the new changes.
2. Use a strong standards-compliant library and try to adapt their architecture and even syntax style. For instance, in C++, I would highly recommend QT, as it has a beautiful architecture and forces you to use the signal-slot mechanism, which helps a lot in designing truly component-based code. It is also open source and cross-platform.
3. Plan ahead. The many bugs are usually a sign that the algorithm or architecture isn't thouroughly thought through (TTT). Although I know that for some people, coding is more interesting than planning ahead, so try to plan while coding.
4. Don't get discouraged. Every mistake is a lesson learned. Lots of lessons learned = experience. Remember, it is the path that matters.
There have been allusions to this in other posts, but automated testing helps the quality of your code greatly. It's something you can start doing on your own without reference to other developers, and when your code works better you can roll it out more widely.
The greatest benefit to code quality is that you can refactor fearlessly.
I say this having had experience of both sides of the coin in the last year. A year ago I built a test framework for the application I was working on. There was already a comprehensive test suite for other areas of the product so it was easy to just plug all the new tests into that, but having automated tests for this application made a phenomenal difference to its stability and reliability.
Then nine months ago we brought a new application in-house. Its operation was reputedly very good, but it needed to be updated to cope with a new environment. The code was superficially quite well written, although it had no comments. And there were no automated tests.
Suffice it to say that the last nine months have been less than entertaining. Without automated tests in any part of the new (to us) application, the rework and refactoring required has been next to impossible.
So, get that automated test suite in place now. You will be happier for it, and your code will be better.
Clearly the author and I have something in common, we must have had a lot of the same employers.
I routinely find myself being the guy they always seem to call to clean up somebody else's shit. My entire career has been spent cleaning up other peoples messes, trust me - it makes you a better programmer.
Try maintaining and refactoring a few old programs and/or keeping a job for 5+ years.
Ready data structures and code-theory books, they help too.
I am assuming you want to improve your coding for maintainability and such.
However it is also reasonable to reserve your best coding efforts for code that will be used heavily by others, and spend less time on throwaway code.
Remember that the more code you put in, the fancier your coding structures get, the more comments that go unmaintained, the more difficult your code will be to follow.
Here are some rules you can follow that will help you no matter what language you use:
Rule #1: since the more code you put in, the worse it will be, it follows that putting in less code, or even removing some is always a good idea. Refactor your code mercilessly.
Rule #2: reduce your function/method argument counts where possible. You can group arguments together into a stucture, or hold some in member attributes as object state, but _only_ if it makes sense to do so. Passing _unrelated_ arguments through member variables can lead to a yo-yo coding style that is more difficult to follow and induce unwanted state on an object (ie. unnecessary coupling). Sometimes, to reduce argument count, it is easier to break up the method into multiple ones. Anything above 4 arguments should be reviewed. Anything above 6, you should make a serious attempt to reduce.
Rule #3: use proper english. Methods should start with a proper verb and be followed by adjectives and nouns. Proper spelling should be used. Avoid made up acronyms (Microsoft code is the worst for this)
The effect you are trying to achieve is to make your code literate (not quite so much as in Knuth)
Rule #4: make variable/argument/method names meaningful. The variable name should describe what it contains. eg. index, count, accumulator. Don't use short forms or single letters. If you can't come up with a good description, and it is a trivial variable, then you can do the Smalltalk trick of calling it after the type. e.g. aString, theNumber, anElement. If a method name is hard to understand, then someone trying to follow the code may have to do a lookup of some sort such as looking at the method comments if they are visible (or perhaps even calling the original coder) and it will break their focus. If you are in doubt about what to name something, go find a dictionary or a thesaurus. Don't just name it something junky and meaningless.
Rule #5: make the code obvious. No fancy coding tricks that lead newbies astray. Unless it can't be avoided.
Rule #6: comment only when not obvious. If the code is the least bit non-obvious (because it can't be avoided), then add a small comment above it or beside it. Otherwise, let the code speak for itself.
Too many comments that just repeat what is obvious make the code look like gibberish. And that volume of commenting usually gets out of sync with the code as it gets maintained by people passing through. Just comment the important and non-obvious stuff, and maintainers may be willing to update the comments too.
Rule #7: keep your functions/methods small. A good size to aim for is 5 lines of code. 30 lines can be OK if an algorithm warrants it. More than that and you need to consider splitting it apart.
Try to make the finer methods still meaningful/useful by themselves. Ideally, each function/method should be independent of the others. Make it obvious when they are not e.g. private adjustAmountHelper()
Practice the above rules faithfully and you will already see an amazing improvement.
If you want more rules than that, and you are on-side with your boss, you can try looking at a coding standard, such as
C++ Programming Guidelines, Plum and Saks
Despite the C++ in the name, the concepts in the book are fairly applicable to other languages as well.
I have had bosses that wouldn't endorse any coding style guidelines at all until I presented them with the Plum and Saks book. Some bosses just need to know they are not following your arbitrary standard, and presenting them with an actual book or website is all you need
... the code that I've written that actually works (eg does something useful) and that has actually shipped.
In the course of my career, it turns out that more often than not, the code that's simultaneously been the most useful and that has actually shipped has been my cowboy code: quick-n-dirty programs; bash-scripts, perl-scripts, one-offs, and the like.
I've also produced a lot of code under "best practices", and I've found that while this is useful (and it's generally the right way to do things), this code has a tendency to never ship. It (along with a lot of other useful code written by a lot of smart programmers) tends to gets stuck somewhere in the "process" and languishes. Sometimes, it eventually oozes out of the "process" and ships. More often, it just dies a lonely death somewhere in the repository.
I don't care about code that isn't useful or that never gets used. It could be beautiful, well designed, easy-to-maintain code. But if it never ships and never gets used, it's absolutely worthless.
So, yeah. I'm most proud of my cowboy code that has been shipped and that gets used. It may not be fun to read or maintain, but by God, it's useful and it's getting used. That's the primary goal of this industry.
In the course of every project, it will become necessary to shoot the scientists and begin production.
I was a computer science major. Working as a lab tech/shipping clerk for a company that pretty much used Macs and FileMakerPro back when...well, NO ONE USED MACS for non-design business. *lol* They were Mac before PPC processor Macs were around.
Anyways, we had numerous issues with properly labelling our products. I had given my notice to the company. The last week was kind of slow. So I hacked out a really crappily-coded app that would let you enter a lot #. And then allow you to select the brand. The program would automatically select the proper label types for printing.
Vwaala!!!
It worked. This had been a request of the shipping department for a couple of years. IT said it'd be weeks and weeks of work. I was done in 3 days. Sure the program was crap (I used stacked IF/ELSE IF statements because I did not know how to create a case/switch statement in FileMaker Pro's coding environment.)
That said, it wound up being a God-send for my old supervisor. Greatly improved the shipping time and greatly reduced the shipping errors. So the end result - crappy code created in 3-days saved thousands of dollars for the company.
I used to be able to write really good Java and C++ code. I know write mostly PHP code and I can honestly say it is terrible in comparison. Does anybody know how to write good PHP code? I learned how to do it for Java and C++ but am still learning when it comes to PHP.
10 print "my code rocks, thanks for asking" 20 goto 10
echo $SIGNATURE
The code I write for commercial use tends to start ugly, but functional. Its development is driven by schedules and fluctuating specifications. If the code has a long life, and I am maintaining my own code, it tends to gets more beautiful over time as I improve it.
The code I write for myself starts off being beautiful. It does exactly what I want, in the way I think of as best. Over time, as I learn more, I start to see flaws and the code gets uglier. I tend to recode my own stuff more frequently to more efficient and elegant implementations.
In both cases, there are some small segments, like a subroutine, that I consider gems. They are beautiful to look at, and I carry these from project to project, almost as a seed.
For some people, coding is a trade. For some it's an art. In most cases, it's a mix of the two. The proportion is what I think changes the perception. Of course, no one but another programmer can even see the beauty in the code, and in many ways that's a shame.
Can You Say Linux? I Knew That You Could.
...It doesn't matter if they sign off on it and you charge them double for "extra features". There is always something they forgot about. All you can do it learn to design your program so you can make changes easier.
Mike http://thenextgenerationofradio.com
Comment your code well and it does not suck. Don't comment your code, or comment it poorly, and it sucks to the point of being worthless.
I had much rather implement something from scratch than have to walk through code and try to read someone's mind. And this goes equally for open source code. You haven't done me any favors if you GPL your code but don't provide adequate comments or documentation.
FAQs are evil.
> Have any developers here successfully lobbied their company to stop or cut back on 'cowboy coding' and adopt best practices?
I tried and I tried and I tried. Now I'm about to vote with my feet; after a given point, it becomes the only sane alternative.
Economics has transformed the:
"Make it work, make it fast, make it nice"
to:
"Make it work, distribute it, then make it fast and then nice through service packs/updates"
And sometimes you don't even have the chance to make it work properly. So you ship a non working product and then make it work using service packs.
I got my first programming job this year straight out of college. I was armed with a software engineering degree and found a company looking for a cheap programmer.
My first week I was handed an ungodly mess of a system written almost entirely in VBScript with some minor C# parts. It was a nightmare. The previous programmer had left me 10 modules that were "60%" done. Which essentially meant I had 10 modules that were completely no working messes. The best part is that the day I started the project was already 6 months overdue. I almost quit my first week.
The director of engineering came to my first week and told me the hope of the project rested on me. Millions of dollars of sales rested on my abilities to finish it all in 2 months. I have no idea why you would risk millions on a programmer with no experience instead of hiring a few with some.
Anyways, I finished in just a little over 2 months. By finished I mean I rushed out an untested mess to customers. I told my boss it was not tested and he replied that our customers would test it for us. So 6 customers got totally useless systems and paid boat loads of money for them. It was enough to shut them up for awhile.
I am now in my 6th month of employment and the system is still not 100% complete. Its almost there and the pieces that are done are tested. Keep in mind I also spent 2 months on the road installing said system.
I learned that sometimes you just have to do what your boss tells you even though it sucks. Probably not the greatest lesson to learn. I am also now the proud owner of some working code that will be a monster to maintain. My hope is I will be gone by then and the next guy will worry about it. Basically, by the time anyone realizes how horrible the system is I will be gone. This cycle will repeat again and again here due to this management attitude. Also the fact that we sell ideas and not products can't help. The system was sold before 1 line of code was even written with 6 month guaranteed delivery.
The formula is:
1) Promise what you don;t have
2) Hire no experience cheap programmer
3) Give them the impossible task of hitting deadline
4) ????
5) Lose Money
6) Repeat
This is a subject which has been exercising me greatly recently.
Good code to me is readable, obvious and 'efficient enough'.
Readability is a combination of whitespace, layout and good choice of symbol naming. It's got to be pleasing to the eye and easy to scan through without missing some important fact of execution. I should be able to figure out 98% of what a variable/function is just by knowing it's name. If the only way to encapsulate that sufficiently is to have a symbol something like DoXThenY then I'd rather have DoX and DoY.
'Efficient enough' is simple. Does it do what it has to do in the time allocated to it? For 90% of software this is a pretty undemanding requirement since to most users the difference between 1msec and 100 is neither here nor there. The remaining 10% is either real-time or very large data sets (and is where I've spent the majority of my career). In my experience the majority of efficiency problems in these two arenas are usually algorithmic in nature. For real-time it tends to be about how you use the hardware (cache miss, context switches, blocking I/O etc) for large data-sets it tends to be data structure related (using a list when an n-tree is faster etc).
Obvious is the difficult one. What's obvious to one coder is not necessarily obvious to the next guy. There's one overriding principle I've found to stand me in good stead in this regard. I constantly ask myself: "Is this the simplest possible *correct* way of doing this?". Simplest is not always in the least lines of code but it is often roughly equivalent. Simple also suggests a minimum of coupling. For functions this means the smallest set of args I can get away with. For methods this extends to the smallest number of members I can touch. Code paths should generally be straight through and down the page. Recursion (and same-thread re-entrancy) should be reserved for recursive problems.
The other great producer of non-obvious code is OO (or rather poor OO programmers). It takes time to become a good OO programmer. Years, I would say. The most confusing code I've seen has consistently been written by people who just don't 'get' OO, who perhaps have read a few patterns books and then go off in completely the wrong direction making problems fit inappropriate patterns and solving procedural tasks with labyrinthine object hierarchies and call-graphs.
And then.. after you've pared your code down to the very barest essentials, when your call graph is easy to visualise, your data structures clear and your source reads like a well written instruction manual on how to solve the problem you were tasked with.. if you are left with some section that is irreducibly non-obvious: COMMENT IT !!
Design Patterns (http://en.wikipedia.org/wiki/Design_Patterns) can really help out with maintainability and flexibility. Makes everything easier if you pick the right ones for the task at hand.
I'm proud of my code when I actually try to write quality code, and I write it from scratch. The problem is that most often at work I am modifying crappy code, or writing code that is built on top of crappy old code. The crap is contagious, and pride flies out the window.
The GeekNights podcast is going strong. Listen!
Generally, before I do anything major from a coding perspective, I get a clearly defined set of objectives for the software. It won't necessarily eliminate drift of a project, but it gives you something solid to go on when it comes time to question why something is changing. Nothing has quite the same weight as something the customer already signed off on.
...The Pragmatic Programmer by Andrew Hunt and David Thomas.
--I'm so big, my sig has its own sig.
-- See?
Now you're upset and become very vocal about the problems you now have to deal with.
From my experience with one company, that is about the same time as the ask you to leave. Granted not all companies are like that, but some are and you have to decide what management decides is good for the company. Remember management rarely, if ever, see the code, so they can't appreciate the real issue. To some guys in management its just the rantings of one of the developers.
Jumpstart the tartan drive.
There are two good ways to defend against shifting requirements.
First, keep in mind during design that changes will happen. They may be in 5 years or they may happen before the first line of code is written. If your design is modular and consistantly uses a decent internal API, many changes won't require a great deal of pain.
The second defense is the "change order". If you do not have a change order process in place, the customer will expect to make major revisions at the last minute without consequence. In turn, this will result in crappy code since the project will suddenly be late and go from profitable to a net loss.
OTOH, if you gracefully hear the customer out, then produce a change order for them to sign which outlines how much longer it will take and how much more it will cost, all is well. They'll either tell you to forget about the change or they'll approve it and the extra work is extra profit. There may be a few customers who will cancel the project in a huff, but that was their choice to make. At least you don't get the reputation for producing fragile bug ridden unmaintainable junk.
A useful rule of thumb there is that if you can accomplish the change more uickly than you can produce the change order, just do it to keep the customer happy. If that encourages them to bury you in trivial changes, you can always gather them up into a change order at that point and explain that the project is now too far along to trivially make those changes.
Unfortunately, this accurately describes the code base I am currently working on. Sometimes, criticisms are deserved.
Visit http://ringbreak.dnd.utwente.nl/~mrjb/growingbettersoftware to download your free copy of the book
Source code is like shit. It stinks if it's not yours...
-- All Gods were immortal.
-- S. Lem
It's hard to be proud of your code if it's mixed with old one. :-P
I would say yes if I could start a project from zero and build it, but when your mission is to maintain old code fixing bugs while developing new features over it, there is little you can do to make it beautiful and clean
Realizing your code is crap. This is the first step to becoming a good programmer. The second step is educating yourself and working toward improvement. This is the path of wisdom. To use an old cliche', it is a journey not a destination. It is only the inexperienced and the narcissistic bastards who believe their code to be perfect, holy and pure. The inexperienced can be forgiven the narcissists should not be.
Maybe we should develop a 12 step method to improve coding skills?
Anyone?
putting the 'B' in LGBTQ+
3/4 of the things that make code good vs. bad is error checking and commenting. If you check the return code of everything and account for all possible errors in your code, you will become a good coder. As far as spacing and comments go, if you make your code neat and very readable by inserting comments where they should be, other programmers that have to read your stuff will appreciate it. Sure there are other things that have been mentioned in this thread and I agree with a lot of them, but being anal about your error checking is the best way to start writing good code.
...I try and make it look nice, and if i really want to feel good I try and learn something in the process.
I'm a CS student at a canadian university. We have a professor who is very proud of his code. His terrible, incomprehensible, code.
If he was teaching theory, it would be understandable, but this is a second year Java course. And he's breaking every standard. How can I speak to him? How do you deal with a superior who codes terribly?
Posting as AC
Never hire Zonk.
I wouldn't say I feel proud - I feel confident. I think after a while (OK, several years, then) you find a style of programming that is 'right' in that it works for you. It's like anything else in life; when you start on doing something new, you will probably not do the best of jobs, but after some time it will be routine.
The trick, of course, is to get into the right routine so it doesn't become simply bad habits. I find these rules help:
1. Take the time to write your code well.
2. Be willing to rewrite bad code.
3. Maintainability is usually more important than speed.
4. Don't let managers bully you.
Point 1 and 4 are probably more important than you would think. It is no use writing code quickly, if you end up spending ages debugging and maintaining it. Managers of all kinds are often one of the biggest reasons why programmers produce bad code - they often don't know much about actually producing code, and if they don't know much about leadership either, they think that you will work harder and better if you are kept under pressure; but all that achieves is to make people not take the time needed.
Believe it or not, there are some large groups that are adopting the SEI's PSP (personal software process) and TSP (team software process). Such groups have a clear understanding of how individuals and teams contribute to potential defects and have taken a lot of trouble to eliminate the problems.
Such groups see significantly higher productivity and quality. It is painful to start this process but it does provide the results advertised.
"If all the American people want is security, let them live in prisons." Eisenhower
My best work, was that which I've done for myself or my own clients where I could design it from the ground up and I was the only one writing code for it. Then you can do some beautiful stuff with PHP (a language often slammed for poor code quality). By contrast, at my day job I use ASP or .NET (people often claim these languages make for better quality code than PHP) and it's the ugliest mess you've ever seen. Nothing is object oriented, functions are repeatedly declared because we have no reused library files because the IT dept has declared that relative include paths are a security risk *rolls eyes*, so there's no code reuse. Tons of legacy code is commented out and left in there, and there are even spelling mistakes in the function or variable names. Add to that the culture of just get it done, and constant scope changes, and well, you can imagine.
I once started up a flowcharting program to diagram a particularly complicated set of logic I was getting ready to write, and I was reprimanded for not starting coding right away. Planning is a waste of time I guess.
In my spare time I fix spelling mistakes in variable names and removed old commented out code that has long since stopped being relevant, and tried to clean things up. But, it's one step forward, two steps back.
Don't get me started on security.
It's the culture you work in, more than the language.
Frankly, I'm impressed by any code, and I think you should be proud of your code, regardless of whether or not it is perfect. It is all a part of a learning process. Even coders that I know who have been doing it for years tell me they are always looking for ways to make their stuff better. I can't code, although I'm learning.
If you can code, you've impressed me because you have done something that I would like to do. You can critique your own work, and that is fine, but I think it goes without saying that people are going to do their best to write quality code, and if you've done your best, then be proud of it.
Just my non-coding two cents.
I'm not a troll, but I play one on Slashdot.
Looking back at my old code I find that a lot of it is crap. I do find various aspects of what I've done in the past to be practices that I like to perfect in the future. The problem is, as the poster notes, that you're writing something for your employer to get a job done quickly and as long as it works at all it's good enough...next task. So, a lot of anyone's old code is bound to have a lot of rushed, poorly thought out half efforts. That said, I have found that many projects I've started on my own (and often effectively abandoned) turn out very aesthetically pleasing, though tend to get grandiose in scope or attempt the improbable (I'm smart enough to make my own 3D physics engine...I'll just whip that out...then after a month of heavy physics reading you find yourself looking into M theory instead of having any working code to speak of except the surrounding code...sigh). At any rate, I've had the luxury of having a lot of artistic freedom because I've worked with small companies, so I've explored and expanded several pet ideas into full fledged production systems, which is pretty fun.
Of course, the smart way to use dirty workarounds is to document where and why you used them. That way future generations will see why your code is so ugly and perhaps not run into the same problems again when they decide to clean up your stuff.
USE HOT GRITS WITH STATUE OF NATALIE PORTMAN (NAKED AND PETRIFIED)
I know that I can't help but look back at older projects and think that there are better ways to do what I've done. Now I know better. Now I'll write things in a more efficient and maintainable way. I can only hope that in a few years I'll look back at the code I write this week and have an even better, cleaner, faster, and more maintainable way to do it.
BillG is that you??
Man.. I came into an organization and saw this gem:
LOGDIR=/opt/oracle/logs
cd ${LOGDIR}
rm -rf *
The above ran as root. I'm hardly a graybeard programmer, but that just gave me chills because they wanted me to help with the code.
Many good comments already. I'd like to add some based on my experiences since 1972.
Background: I was fortunate to be introduced to structured programming early on. I've used, and helped develop/test tools to implement, various coding methodologies (CASE, anyone?) I've worked on operating systems and compilers. Yes, plural on each of those. I've worked at huge multi-nationals and a 3-man startup.
Observations:
Lastly, here is a quotation I found back in the 80's (IIRC from someone at SofTech) and it has guided my thinking ever since:
Strive to understand your problem.
Don't try to solve it.
A fully-stated problem
embodies its solution.
If I find any problems of the sort, my India teams fixes the problem right away!
This is of course after I have 5 conference calls, 7 pictures, 3 DFDs, 9 code examples, and 10 emails later.
I like working with terse,object-oriented languages like Smalltalk and Ruby. All code could be written such that the purpose is hidden, or you can make careful choices that make the line speak for itself. Comments then are needed much less often. Best practice: write the automated test before the code. Get the most modern tools you can (the good news being that they're nearly all open source). Better code requires discipline, hard work with calm reflection & focus. Better code comes from a sort of zen outlook. I've worked as a coder for 20 years and everything I've worked on has gone to production use (that's kind of rare, or even unique, I'd think) but I've worked with some giants who make me feel as if I'm a self-taught gradeschool whacker... maybe they're aliens.
Actually I quite like my code. It's usually well structured, well commented, built on sound principals. I usually abstract it one more step than required so as to adapt it to changing business needs. I have great conventions about organization, case, functionality. It's completely source controlled. Planned features. Loosely coupled.
What the hell is your problem? Are you just lazy or something? Shut up and write better code?
People have to work on my code while I am still there, just given the nature of our environment. We are all over each other's code. That's just how we roll in our office.
So I think my code is ok. It's not amazing or anything, but most of the time elegance is more important than amazement.
In answer to the article's question...the thing that holds me back the most is one of my managers. He is very much a micro-manager, tends to grossly oversimplify problems, and thinks he is a much better developer than he actually is. He is very good at telling us precisely how to do something and then blaming us for its failures later. When we try to demonstrate the harm that his presence causes, his ego jumps in, insisting that without his level of direction nothing would work at all.
He also happens to be the one that signs my paychecks. So, there is only so much I can do.
I've been writing code in various forms for 40 years as a hobbyist and almost 20 as a pro. That's a lot of code. :-)
:-)
There is code I write as a quick-n-dirty one-off for personal use, code I write with the intent of exposing it to outsiders, code I write which is a modification to someone else's work and style, and code I write which was mine from the beginning and (hopefully) somewhat more stable and elegant.
Some of the solutions I've up with over the years I think were elegant, some were hacks I made because I couldn't think of a better way, and some were/are probably poorly thought out.
As I gain experience in a given language/environment/platform, it's often interesting to go back and view my first attempts at writing code in that context. More often than not I see a LOT wrong with my initial attempts, but that is what experience is all about.
Mainframe/UNIX Bit Twiddler and long time Windows/Linux Hobbyist.
The Theorem Theorem: If If, Then Then.
Adopt a development methodology that defines what features will be developed and what features WILL NOT be developed. Now you have a place to put all those "great ideas" people have while you're still making the base product. You can also keep them in mind while making other modules, so you know you can make them later. This eliminates scope creep. It may not seem like a piece of paper will work, but as a society we all know the power of forms. Act like it's not your choice, that someone in management is making you use the methodology. No one will want to contradict anyone else so they will just accept it. And when it works, and you come in on-time and on-budget it will become part of the corporate culture.
Your deliverables (above) will be a part of your project charter. You will also include stuff like: a list of stakeholders, RISKS AND ASSUMPTIONS (such as a deadline not being met, etc.), testing, and of course "Success", which will be a list of metrics that define a successful product (ie: it can generate payroll checks, it can print report A, etc). Then, take your project charter (look it up on google) and put a bunch of lines on the bottom for you, the team and the management and the key users to sign off on. Do not start work until it gets signed off. Then make a copy for yourself and file the original with the project documentation. Work and complete all the features to be developed. At the end, take the project charter and make sure everything is fulfilled, then give it to the "customer" and have them sign off again for completion (after you demo the software).
Usually scope creep means poor project management, and as a developer you can't expect anyone else to do it. Just do it, you will be very thankful you did. Also, if it's a short project, try something called Quick-Kill project management. Large projects need a better methodology. I use one I made up that's based on the quick kill and some microsoft stuff, with some unix version control stuff, and oracle business process analysis stuff... Over time you will develop your own methodology and become a star senior programmer making $300,000 a year.
Have fun
Cool! Amazing Toys.
One of my coworkers told me the other day he loved my new authentication and credentials system I used for the Data Access Layer. So much so that he snagged it and used it in another system that had similar authentication requirements.
Now, I've written a lot of bad code in my life, and I'd like to think a lot of good code to. I've seen beautiful code before. New attack vectors and amazing ways to approach problems I never would have though of. And each time I see those nuggets of perfection, I snag them. They get added to my pile of code samples for later use. Either in a straight copy or as a foundation of an idea that gets recoded, depending on license requirements.
Bad code is easy enough to deal with, bad design however... that will kill a project. Bad code can be hot fixed, cleaned up, or straight up replaced. But bad design will require new work from the ground up, getting the users and management to come back to the white board, verifying the requirements... If the system is not designed to meet the needs of the users, a memory leak won't be an issue because no one will ever use the software.
-Rick
"Most people in the U.S. wouldn't know they live in a tyrannical state if it walked up and grabbed their junk." - MyFirs
I can't say that I'm proud of ALL my code. Sometimes a quicky-fix or work around is left in place because there is no time to clean it up. Also, there always seems to be fragments of abandoned code left in a project that gets forgoten. As for what to do . . . Well the problems are there mostly because of time restrictions and nobody is going to provide the time to repair them unless they cause real issues. And on the topic of drift! Sometimes it seems to me that the client has no idea of there own business rules and goals and will request the damnedest things just because they saw something similar somewhere and though it was cool!
"Have any developers here successfully lobbied their company to stop or cut back on 'cowboy coding' and adopt best practices? Has anyone convinced their superiors that the customer isn't always right and saying no once in awhile is the best course of action?" Not successfully. No.
The smartest man in the whole, wide world really don't know that much. - Mose Allison
If you're openly aware that the quality of your work is poor, and you're constantly involved in projects that seemling 'drift' until clients run out of money, then maybe it's time you find a new profession.
Based on your statements I don't think you're cut-out to be a software developer.
I was hired to work with someone who had been the sole person on this project for awhile. The first thing I did was start asking questions like "Why did you do it this way?" Sometimes, he had a good reason. Often, it was that he'd done it that way before he quite knew what he was doing.
But I was lucky -- we both pretty much agree on the "right way" to do something, and in cases where he had done something we both thought was brain-dead, I often had the time (while "learning the codebase") to refactor it. And that, I was proud of, particularly how fast I did it.
Now, I'm kind of in the same place -- I started out with a pattern that was kind of cool, and powerful, and when I was about halfway through implementing the classes that use that pattern, I realized how much code I was duplicating. Because I had to get it out the door, I just kept right on going, practically copy-and-pasting. This week, with any luck, I'll be able to take a few days back to clean that up.
So, in my own opinion, my own code will pretty much always look ugly before the first refactor. But I'm lucky, because I have a boss who programs himself, and thus understands the value of frequent refactoring and getting it right. And none of that really has anything to do with other people, they just have the advantage of being able to see where your code suck before you do (because they haven't had to live with it).
Don't thank God, thank a doctor!
People are apt to confuse arrogance and bluster with knowledge and ability.
The first step of a successful con artist is convincing you to distrust other people.
The grass is only greener, if you don't take care of your own lawn.
I've worked both as a manager and as a programmer, and -- although the programmers do have a significant impact on the quality of the code -- I feel that management's impact is even greater. Technically, even if the programmers all suck, it was ultimately a management decision to hire them (or to not hire enough developers, or to not train them if needed, or to re-assign them if required, or fire them if warranted). Sure, other factors may constrain what management can or can not do (budget, etc.), but... the buck stops somewhere, and that's usually at some manager's desk.
Now, I have seen programmers that wrote lousy code, but I've also seen a lot of really good, bright, motivated developers that were forced to compromise the quality of their code because they had no other choice. I remember one newly hired, enthusiastic jr. developer complaining about another developer's code (cutting and pasting, hacking, etc.), and then 6 months later he was resigned to the fact the he himself had to hack most of his code in order to meet the latest deadline..... this being a deadline that was already 50% shorter than the original developer estimate, grew larger due to "extra" customer committments (while keeping the "schedule" basically the same), and having to have worked most evenings and weekends for quite some time to "stay on schedule". There really wasn't much else that programmer could do, and he couldn't work any longer hours then he was already doing. If the schedule wasn't being met, then the developers were expected to make that time up and they weren't getting much sleep as it was.
And yes, the developer (not the manager) was still held responsible for the quality of the code afterwards. During one team meeting, a manager even stated "do whatever it takes, just get it done". So the developer did do whatever it took -- including design and coding shortcuts (and this was the developer's last resort: he tried working longer hours, but at some point couldn't keep it up). The developers even told management that they would need to take shortcuts to meet the deadline. Of course, the management critisized their designs and coding skills months afterwards.
Some of those managers believed that this aggressive scheduling was a "good thing" (after all, "...work expands to fill the amount of time given...", along with the reasoning that if they only give the developers 3 months to a 6 month project, then they have 3 months of buffer). Now, some managers were keen on actually changing things (as per some developers suggestions), but this turned out to really mean: "We're interested in changing things if it means that the developers change the way THEY do things. We're still going to keep managing things the same way we always did." That latter part was probably partially intentional, and partially unintentional (some really did want to change the way things were managed, but they themselves were too familiar with the old way of doing things to really change anything).
Now, I don't want to put too much blame on management (and some of my slant might be a bit biased, since the incidents are still fresh in my memory), but the point is that management can, and does, have a significant impact on the fate of the project and on the quality of the code being produced. Just because the developers are the actual ones writing the code, doesn't mean that they're solely responsible for the quality of that code.
As for improving the situation, I HAVE seen companies make changes for the better when those changes were management-driven, and driven by a manager that knew what changes to make and believed in them. When the changes were initiated by the developers, they tended not to really get adopted -- mostly because management didn't really embrace the new way of doing things. Not that that's a reason to remain quiet if you're a developer: your best bet may be to talk with management about why things aren't working well under the current system, and why things need to change (along wi
Once in a while I take a small change and tell the client/boss/myself that it is a really BIG change.
Then I go through a totally re-write the code from end-to-end. I look for unused sections, variables, etc. I re-order all the logic so that it is logical. Then I test for the necessary period of time.
Since most of the code is already written, I start by writing out the business rules and I make the order of the code follow the order of the business rules, more-or-less. I put ALL of the business rules into the code as comments. I also send the rules to the client/boss/myself/others.
Doing this just once a year, on each critical section of code actually saves me much more time than the initial investment, so everyone wins.
- I live the greatest adventure anyone could possibly desire. - Tosk the Hunted
I am one of those people who likes lots of code. So much so that I've developed a style, similar to how I used to code 68k assembler, of running comments down a second column (usually 40-60 characters in) that describes what is going on. After all, it doesn't interrupt the flow of the code, and if you're editing Java on an 80-column fixed-width interface, you're doing it wrong to begin with. I wouldn't say I comment every line, probably one in every 3. However, this gripe with over-commenting is fundamentally flawed:
:) However, if it was being used in a loop, why is it being set to a+2? Is a some sort of offset in an array? Is it a user-entered value? THIS is what the comments will illustrate, eg:
// skip the first two elements in the loop as they contain other data
// user input will be off by 2 because of (strange reason here)
// now split the input into an array and parse ready to give to the file handler
and I've met people who won't even look at code unless every single line is commented telling them precisely what it does, so "int i = a + 2;" has to have a comment above it saying "// create a signed 32-bit integer variable, i, and assign it two more than the value of a".
Why on earth would you write a comment like that? That is ridiculous. However, the line DOES need a comment. It's declaring a variable with a non-descriptive name and doing something specific with it. Now, the comment should do something like say what the variable is used for, if it's non-obvious. In this case, "int i" is usually used for loops, so it doesn't need a comment unless it's *not* used for loops.
int i = a + 2;
or
int i = a + 2;
writing comments like "initialise variable" is useless, but thinking that may be all there is shows a misunderstanding about how comments work.
You can assume the person reading your code is a programmer, familiar with the language used, and able to follow general program flow. However, he may not be familiar with the rest of the system, nor with any specific tricks you may use[1]. Comments should be like a director's commentary on the code, pointing out what may not be obvious, and giving the bigger picture - the reason why a specific variable is used a certain way, or what a messy few lines of code may be achieving, eg:
(horrible loop declaration here)
(even more horrible regex here)
(custom function calling here)
It's said comments are like sex - even when they're bad, they're still pretty good. I'm pretty sure I've never spent 3 hours trying to work out how to get THAT to work, though!
[1] eg, I use a relatively uncommon trick in Java doing string comparisons of if(!"blah".equals(myString)) because it can't fail on the null pointer check that if(!myString.equals("blah")) can. A simple example, but something more complicated will save someone time if it just has a quick comment next to it saying what that section of code is achieving.
The difference between a competent and an incompetent programmer is that an incompetent programmer thinks his/her crap code is the best, while a a competent programmer knows that his/her code is crap.
Sure this is funny, but there's an underlying truth to this. Someone that knows what he/she is doing, knows all the ways the code could fail and all the the checks and exceptions that should be there that is isn't, and how the assumptions of the underlying algorithm may not be strictly guaranteed, and is just waiting for the code to break. Someone that doesn't know what his/she is doing thinks everything is great since it passed his/her incomplete unit test. Or to put it another way: Ignorance is bliss.
I think the code to be most proud of is when it's written to work with limited resources. Who isn't impressed by the assembly coders who crammed fast, fully functioning programs into some minuscule space? Sadly, fast processors and gobs of memory have made things too easy. Now you don't have to think several steps ahead. It's still possible to be proud of inventing new algorithms (i.e. shaders, bittorrent, etc). But the programs themselves are much more pedestrian.
The world is made by those who show up for the job.
In my experience, I find that quality of code versus quality of execution begins closely correlated when the bulk of code belongs to a smaller set of talented engineers. As soon as you bring in third party API's and less talented engineers, the relation becomes inverted - stability and performance often begins to depend on the amount of hackery one does to get around shortcomings outside your control. Not saying this is always the case, just is often the case.
You should consider adopting test first development, this will have numerous advantages for your situation:
"It is buggy, slow, fragile, and a nightmare to maintain."
1) Test first code isn't buggy. It has tests that prove the correctness for all important cases.
2) Test first code isn't fragile. It has tests that allow easy refactoring without risk of unknowingly breaking an important use case.
3) Test first code isn't a nightmare to maintain, for the same reason as #2. The tests also help to document the use cases in a way that comments frequently fail to do.
It won't do anything about slow, unless your test cases help to specify minimum performance levels. In which case it can solve that problem too.
As a coding practice, it has one main additional advantage: it has good empirical results, and that's sellable to management. Management likes good practices, particularly one you can sell as cutting costs in qa through automation.
"Who is the Journal of Quantum Physics going to believe?" --Stephen Hawking
The number one reason: "You never get to do things the right way". So maybe some of the blame is circumstances?
I also cut me teeth on the IIe.
It is possible you are just not a very good programmer. But maybe you are, and you're being "poorly managed". Being poorly managed is your fault.
Here is a list of your responsibilities:
Implement what the customer needs.
Implement what the customer wants.
Do what your manager needs (distant 3rd).
Do what your manager wants.
Here is a list of your manager's responsibilities:
Make it clear to you what you are supposed to be working on.
Make it possible to do what you're supposed to do.
Make it easy to do what you're supposed to do.
Your manager works for you. If she asks you to do something you should not be doing, don't do it. If he is not making it possible/easy for you to do what you need to do, complain. Learn the word "no." Say it over and over. If you are the [only] programmer, or you are the team lead, you know what is best for the project. Explain how and why it is best. Be understanding, but be firm.
It is important to be honest and clear very early in the process. If something can't be done [in some period of time], you have to say so. Better if you understand what they want and see if you can do something similar in the timeline suggested, in addition to explaining how long it will take "their way" - that's "being flexible". Doing something the wrong way (most of the time) or agreeing to something that can not be done in the time given is not "being reasonable", it is being harmful to the project.
My notion is that 90% of the work done on any project will be after it is "complete." I don't know where I picked that up, exactly (in some college course, long ago), but it seems like a reasonable attitude to approach a project with. And if I'm going to spent 9 times the effort maintaining the project as I spent writing it, I sure as hell want it to be easy to maintain.
My last two projects have been to babysit and sun down legacy systems. These were written in Perl, are web & database based, were written over a period of about ten years by multiple people, had no development system (all changes are made in production), and are each at least a half million lines of code.
One such system has two very different kinds of programmers. One kind produces very small, tight, elegant code. Each line may be complex, but there aren't very many of them. Another kind generally codes for conceptually easier tasks, and has a verbose style. Individual lines are trivial assignments, but there are sometimes thousands of them.
The elegant code is MUCH more difficult to debug. It's also, generally, broken much less often. The verbose code is generally very easy to fix.
But i've gotten an appreciation for other ways to do things. And, there aren't nearly as many of us 'elegant coders' out there for replacement. But i still don't see how some apps can be accomplished at all without us. This appears to be language, library and tool independent. Fred Brooks seems to have something to say about this.
I'm firmly in the realm of 'elegant coder' myself. My favorite piece of late is 750 lines of very dense code involving a seven dimensional hash (but sometimes six - it varies) with dynamic indexes. It replaces a 25,000 line chunk that had to be changed every year. The new bit never needs change. However, despite ample documentation and three tutorials, i was unsuccessful in showing the new team how it worked. The new system has designed this bit out completely.
One thing about both projects is that the employer either started a project to replace them, or actually replaced them. In both cases, it was an incredible amount of work and expense to do this. Millions of dollars. It would have been both cheaper and better to fix their problems, and update their user interfaces. At least, once an appropriate programmer was found. Oddly, we have at least two on our current team.
Oh, yes. The replacement projects went over budget and were late by at least a factor of two. Much more, if you consider that something like half of the functionality was removed. And there seems to be one chunk that the new team doesn't seem to be able to deliver. Perhaps the new team needs an elegant coder.
-- Stephen.
You need to look into agile development practices
Improve the team, improve the code and let the customer INCREMENTALLY decide what functionality to put into their product.
The customer is never wrong - it's just that their requirements change over time and both you and the customer need to embrace and capitalize on that rather than constantly fight it and end up delivering a product that neither you or the customer are happy about.
I spend so much time on thinking design, using best practices and thinking names of my variables to making the code more efficient which is sometimes even irrelevant to the project/problem but since its my passion so I'm the slowest programmer around I think :/
But I am proud of my code! B)
The only formal programming course I ever had was a VB class in college (needed a "computer credit and I didn't know VB). Everything else I've learned from looking, reading, and writing/rewriting code till it worked.
"The problem with socialism is eventually you run out of other people's money" - Thatcher.
Not quite true. I can think of a few people whose code gave me no reason for complaints. To pick just two extremes out of the pool:
- one of them is pretty much the pragmatic programmer prototype. He'll (also) apply some pattern only if it's needed, not because it would be fun to have it on the resume. Sometimes a switch block with 10 cases is really all you need, you know? His programs tend to be compact, work and be actually fairly easy to get the hang of.
- one of them is, well, pretty much the opposite. His programs tend to be a lot larger than they need to be, and have layers upon layers of patterns even to print "Hello World". With some reflection thrown in for good measure. Strangely enough, though, they _are_ well organized, and you can fairly easily find the class that processes a given event or command... or the singleton factory that supplies it, or the manager class it's registered with, or...
Are they perfect according to my tastes? Nope. But I can nevertheless tell good code when I see it, even if it's not perfect. And say it.
On the other hand, at the other end of the spectrum, I've had to deal with pieces of code which were truly atrocious. E.g., one particular program not only raped all best practices known to mankind, but also was living illustration of half the techniques from How to write unmaintainable code. Literally. It even had stuff like the using people's first names for variables, in addition to the more mundane techniques like mere undescriptive names, obfuscated flow, heavy use of global variables, non-obvious side-effects to those variables, or methods which can also do some 2-3 other unrelated things if called with the right parameters. And I don't mean just side-effects or cramming more functionality in one call than expected. I mean stuff like the class which should have normally sent an email, could render and print a PDF _instead_ of sending one email, or update the contract in the database instead. And for bonus points, not even determined by parameters, but by the contents of those global variables. But, again, the nicest touch was finding uninformative variable names like Pete and Eve in the very first class I opened.
Basically IMHO lumping it all into one everything-is-the-same "all programmers hate each others' code" pool doesn't do it justice, and paints a misleading image. _Some_ may be just nitpicking about the style, but some code is genuinely evil stuff that should be buried at crossroads with a stake through its chest.
A polar bear is a cartesian bear after a coordinate transform.
Code Complete is a must read in that matter.
At least for me, the key is to feel like I have time. Not even to have time, but to feel as though I do. Then you go the extra mile to make each piece easier to use, easier to understand, and simpler.
You actually get done earlier, too, so you usually don't have to actually have time to do this. But I still haven't managed to convince my brain to ignore time pressure when I'm in a hurry, so I still churn out less elegant, buggy stuff that takes longer to write when I'm under time pressure.
I am downright embarrassed by the quality of my code. It is buggy, slow, fragile, and a nightmare to maintain.
That above statement is holding you back, Everybody's code sucks in one way or another, my code sucks in some ways I do things but there are things I do that make it worth the effort. And I know my next bit will be better, I know how to do what I've done and I have better iseas on what to do next. Also in that tangle of code I bet there are things you ARE proud of, did you pull of some nice intuitive user interface? Or maybe you made that page of data look real professional, don't overlook your good skills.
I got my start in BASIC (on the Commodore PET, then on the 3.5K VIC) I still write BASIC programs for my Commodores in my collection in BASIC. I also have worked on many different programs - databases, data conversion, graphics, games, sound, etc. all are good experiences on how to do or not do things. Every time I do something new I take the wisdom of what I did before and the ideas I have learned since and integrate them, Along the way I pick up some style tips, or a better method to do something, those go in the next project or future rewrite. I liken good programming to woodwork you can make a lot of functional pieces, each one getting better then the last as you work toward masterworks.
Sadly the one constant in my career is that I am assigned to projects that drift, seemingly aimlessly, from inception to a point where the client runs out of funding. Have any developers here successfully lobbied their company to stop or cut back on 'cowboy coding' and adopt best practices?
Part of that can be alleviated by good coding but it sounds like your is more a communications issue, where the customer is going back to some base function and making significant changes. Also, again from the filed project learn from your mistakes and the knowledge you gained from the experience, paraphrasing Thomas Edison, you may not have learned to make a light bulb but you learned many ways not to.
Has anyone convinced their superiors that the customer isn't always right and saying no once in awhile is the best course of action?
Communication also; start with encouraging some realistic milestones not everything in one fail swoop, if it is something 'completely new' encourage the customer to start off small (and inexpensive) and build from there as you both learn the system and all the data/customer needs. You probably will need to rewrite, but you will not be rewriting something you were unsure of in the first place and still are.
Also thinking on this, maybe part is the platform you are developing on; some development languages/tools are a pain to try to do advanced stuff with, others are just not well suited or specific things. Ask yourself: "Am I struggling on the project or the platform I'm developing in?"
"Enjoy what you're doing! If it becomes drudgery, you're doing it wrong!" - Jim Butterfield
Long term, I'm never proud of my code.
There's been a steady increase in the amount of time it takes until I stop being proud of my code, though. Several years ago, it used to be that I already couldn't stand to work with my code after 2-3 months. Two projects ago though, it took me a year and a half before I first started thinking the code sucked, and then I only needed to rewrite a single component before I was happy with it again. The two projects since are still quite perfect.
I have no illusions though. As customer requests keep coming in, and the design reaches the boundaries of its flexibility, the code will slowly become less and less suitable for the purpose to which it's being put, and any pride in it all will vanish. Yet, I'll keep learning, and setting up my code ever better (without falling in the trap of over-abstracting), and the useful lifetime of it all will keep increasing.
If that process ever stops, it'll be time to start looking for a new job.
The problem is compounded by programmers like myself who have gone from working for a COTS software company to working as a programmer for a non-software company. In the past I would strive for creating the "elegant" solution. But now if I decide to spend time refactoring code, I seeing the people who churn out code the fastest - regardless of quality or maintainability - being rewarded with the best work. Screw that! I've given up... now when I edit someone else's code I follow the same low standards they did.
Ah, kids these days... so easily impressed.
I remember one piece of code that makes even that seem tame. Assembly, mind you, back in the 386 days.
Someone had calculated something as a 4 byte float, then took it as a 32-bit integer, swapped the higher and lower 16-bit words, wrote it into a memory location at the start of a function, and then actually jumped to that location. I.e., he actually executed that result. That was actually in the (uncommented) assembly source code, mind you, not some accidentally disasssembling a piece of the data segment and discovering that it makes no sense.
To this day, I have no clue what that did. Awestruck is putting it mildly.
A polar bear is a cartesian bear after a coordinate transform.
Over the years I've noticed a trend within my jobs. Often I'm "the technology guy", yes that's singular. For example, I'm currently working in a research lab as "the tech guy". I'm often never given the time or resources to write truly clean code. This is usually due to three situations, though all are similar. Let me explain:
Situation one is when a need is perceived and a fix is desired *now*. I'm asked to implement a fix, then constantly asked if it's done yet. The moment I can give an example of it somewhat working, I'm pulled off the project with the declaration of "it's good enough". The code is usually barely out of the prototype stage. Subsequent fixes to the code are done sporadically and in between more pressing needs. Again with pressure on quickness rather then robustness.
Situation two is a result of gross under estimation of the depth of the project. Such as "Hey, can you implement a usb driver for this new device we have that isn't supported. We also need a gui front end for it. Oh, we have two weeks." I work solo btw and have never written a device driver before.
Situation three is a lack of appreciation for specialization within the technology field. I find this one very surprising being that I work amidst individuals whose careers are defined by their specialization. For example, I'm given a project of the utmost priority to back port/port an application in a language I've never seen before. Or perhaps asked to spec out an enterprise level backup system. Since I'm considered "the computer guy", my "expertise" is viewed to encompass network engineering, hardware design, all languages ever conceived, and the ever pervasive "helpdesk" type tasks.
It makes for an interesting and dynamic work environment, but also leads to less then ideal code and many projects I would consider incomplete.
Reduce, reuse, cycle
Q: How many developers does it take to change a lightbulb?
A: None. It's a hardware problem.
If your code is so crap and you can't seem to get better at it, maybe you should get a new job where you can do work which you are reasonably proud of. Do you really want to be like those CEOs who do a crap job and get paid for making everyone else suffer?
:).
:).
:::* port 80, and unless we're all wrong here there's no way my program would do that - the socket binds are all IPv4 only (pretty easy to check :) ) only done at the start and both the program and apache were running fine before. The program was started days before and was still running at the time apache was restarted (and failed to rebind to 80).
;) ). At some places Vista machines could not get an IP when behind some network devices. Turns out to get things working the dhcp server had to send an IP broadcast but ethernet unicast.
;).
I'm definitely not the best coder out there, but wow there sure are plenty worse - the benefits of open source is you get to see how crap (or good) other people's code is compared to yours
I don't like some of the stuff I had to write in the style of someone else's code - fixes/changes to old (and often very crappy code). Sometimes you can only just make things less crappy - if you try to remove all the crappy bits you end up having to rewrite everything, but nobody will reward you for that and you'll get in trouble for anything they don't like.
The stuff I write from scratch for production usually has very few bugs. I don't churn out code rapidly like others, but my stuff tends to work and keep working. I have a fair bit of experience in IT security and breaking/abusing stuff, so I write stuff accordingly.
I'm also really lazy, so I'd rather get things right first or second go so that I can waste time on slashdot and other stuff
Typically the "problem reports" I get end up being due to something else.
Recent examples:
Someone thought there was a prob with one of my programs, so we looked, then got another colleague to look and conclusion was it was likely to be a bug in Linux, perl or hardware (in order of likelihood). Somehow after a restart of apache, Linux/netstat claimed that my program was listening on IPv6
Then there was a reported problem with the dhcp server I wrote. I initially thought it was my bug. My dhcpd sends IP broadcasts in ethernet broadcast frames as replies to Vista (as default vista wants) which worked fine everywhere else (unlike some versions of ISC's dhcpd. Nyah!
I thought, "oops my fault, should have done that from the start" (I actually did have a comment there wondering whether I should use unicast ethernet replies- seemed more efficient ), but after rereading the RFC2131 and doing some thinking (it's not explicit that broadcast = IP AND layer2 broadcast, but reasonable enough assumption right?), conclusion was the way I originally did stuff was RFC compliant, and it was the network device that was misbehaving - it should behave like a switch/hub and pass the layer 2 broadcast frames. So the fix will be a "configurable workaround" thingy. Easier to "fix" my dhcpd than to fix a few hundred network devices made by some other vendor.
Oh well side benefit is my dhcpd can now be configured to reduce dhcp broadcast traffic due to vista. I doubt we'll encounter that many vista machines though
As for the customer not always being right, well that's the company's fault, and fault of the person handling the customer.
The customer knows _vaguely_ what they want, you have to help them figure out what they really want. Take building a custom house as an example.
The Architect has to sit with the customers and say things like "If you want an olympic size pool, you can't have parking space for 4 SUVs unless you're willing to fork out a lot more money, and it'll take at least 3 months longer, and we'll probably do things this way".
Thing is most companies don't have people who 1) understand that, and 2) can actual
I fully agree. I inherited a LOT of uncommented and shittily commented code, and it is a royal PITA to figure out WHY it is doing what it is doing (which was basically your point). On the other hand, at least with crappy comments, there is occasionally a nugget of useful information...I despise the comment-free code more, but the code itself also looks like it was designed by someone on an acid trip.
.NET. And the other programmers whose code does NOT suck (separate project group) have given me positive feedback on what they've seen of mine. A limited degree of self-doubt is good for keeping you honest with the quality of your work, but don't worry about it TOO much.
So yes, comments should say WHY more than WHAT (specifically) a line or block of code does. A short narrative is usually the most helpful, ime. Basic description of what the method (or even a crucial line if it's the least bit unconventional or otherwise unintuitive) does (in bird's-eye-view terms / how you would explain it to a non-programmer), and WHY it is doing it if that purpose isn't obvious from WHAT.
And I also say (most of) my predecessors' code sucks, but in this case, it does. There was one guy who seemed to have a decent idea of what he was doing, and I think he got burnt out by the complete buffoon of an "IT Manager" they had at the time (hurray cronyism! He still works here in his own project group because he's friends with the big boss). But the other guys...one would have actual end-user visible error messages like "the stupid polack messed up again", and had one of Shakespeare's plays in its entirety linked on one of the maintenance web sites. The other guy consistently set up SQL accounts with "password" and sysadmin privileges (I've gotten it secured now, but it's causing quite a bit of havoc for some users). Crazy and stupid, respectively. Then we have a contractor (still with us, hopefully not much longer)...who is arrogant AND stupid (with coding, anyways...quite manipulative with the non-technical people who control his paycheck). He implements concepts and technologies that he does not understand in completely useless and excessively complicated ways. He also has a big problem with turnover of his underlings, resulting in even crappier code. The rest of us want to completely scrap his project because it's so bad (the aforementioned "acid trip code"). But you know what they say: "CONTRACTING: if you aren't part of the solution, there's good money to be made in prolonging the problem."
I am lazy: I make sure it works before it goes out, and I write it so the user can configure it to do what they need without having to bother me to do hard code changes, recompile, and redeploy. I've already got enough of that with existing code I've not yet had time to rewrite.
So, in short, if you are neither crazy nor stupid, your code probably won't suck that bad. Every time I'm skeptical of my own code, I just look at the code I am maintaining and replacing. I simply remind myself: mine actually works. I wrote them from start to finish, so the code is consistent. My boss can look at it and understand what it's doing with his experience with older languages and teething knowledge of
Code is organic by nature, because humans tend to evolve things in an organic way. As such, keeping code in good health requires a lot of attention, which costs money. Automatic refactoring tools may be evil for VCSes, but they are the most valuable tools we have to keep code in shape.
Code is also (usually) a collaborative exercise, bringing lots of different ideas and principles to the table. That is why software "Patterns" are so valuable, so that people can communicate about code in a structured and compatible way.
Code is something that no one has time for. Visual programming 4th generation languages and Functional Programming are ways to get the job done faster, easier and with less of a hassle, and more docs to read. Both are still way off the target goal, but in the last few years some nice tools have developed.
Code is bound to run on something, and that "something" is changing all the time. You can't check in and label your machine in your VCS, which means you have to try to make it run as good as one can within certain constraints. This is where the virtual machine has helped make a lot of progress.
Code will always be needed, though the format and logic behind it will keep changing and morphing. The battles between speed and memory, cost and ownership, data or function, abstraction or generalization, top-down or bottom-up, these battles will always exist. In the end, writing an executable program that does the job is just a very sophisticated search in a search-space that we still need to define better.
That said, check out Variform by kewlers for no apparent good reason, other than to look at code as an artform. Ps. There's tons more where that came from.
Cheers!
With great power comes great electricity bills.
Yes. Yes, I am proud of my code, even some of the awful stuff when I consider the circumstances in which it was written.
I think that part of the problem these days (rather than part of the solution that it is touted to be) is analysis. Some of the best work I've ever done had minimal analysis. It was the result of hand-drawn scribbles from a customer (internal, Billing Department honcho) discussed during an informal talk about the project. Data/timing issues and customer must-haves were thought out (and scribbled by me on my own notepad). "Unprofessional", by most any standard. But it was a very reliable system for years, and it was internally documented to perfection. Customer kept their own copy of the descriptions they created (and understood), and programmer (me) kept his own copy of the descriptions in the code commentary itself. Meshing the two interpretations was the responsibility of the PEOPLE involved, not the documentation PROCESS. Any last-minute show-stoppers were avoided by occasionally showcasing the test environment to the customer prior to final q/a exams.
<soapbox>
After nearly two decades in the tech business, I still do NOT understand why "documentation" (the usual kind) is considered a helpful tool. That stuff is written in legalese that is not the first language of EITHER the programmer OR the customer. How could it benefit anyone to write/read specifications in a foreign language? It would be like insisting that customers write out their specs in COBOL (more English-like than most doc formats I've seen). It makes no sense to me.
I'm of the opinion that customers should be responsible for writing out the test scenarios that they want to use for verifying the product. They do their own quality assurance, in other words. It's up to the programmer to create a system that fits those tests. Customers write out their test scenarios In Their Own Language that they're comfortable with. Programmers are smart folk, by and large. What they can't understand immediately, they're inquisitive enough to ask someone to explain it to them. Everyone knows up front that if something doesn't work, it's the programmer's fault. For not asking the right questions, for not examining the right interfaces, for not doing proper module testing, for all of it. (Well, short of actually writing the final test scenarios, which is the responsibility of the people knowledgeable about the process being automated. That's not the programmer.)
It was a great system that worked wonderfully for both me and my customers. It produced what I still think is good code.
On the other hand, when that same environment went ISO certified, it all came screeching to a halt. Massive delays, useless finger-pointing over documentation errors, people involved who had no understanding of either programming or the process being automated. In essence, legalization of the creative process... introducing mandatory opposition where there had previously been cooperation. Just like a legal court, the PROCESS is designed so that BLAME (codeword: "responsibility") can be determined with certainty. No creative process should have to endure such insult.
</soapbox>
No, wait...
<soapbox>
It's incredible that anyone would think documentation could answer the question, "How long will it take you to do something that you've never done before." Yet the entire industry still seems bent on producing these estimates that are, as a rule, wrong.
</soapbox>
I think that most developers already experienced the same (or will experience it at some point in their professional life). The best advice I can give you is to buy Creating a Software Engineering Culture by Wieger. You should definitely buy two copies. You keep one and you have a nice Christmas present for your boss. The message will be straightforward and unambiguous.
If he is not a total incompetent with a MBA (sorry dudes), he will read it and realize that his company has implemented a lot of the Culture-Killer things from the book!
Sometimes, the code wasn't written with the mindset of how things *should* be done. Sometimes, the code was hurriedly slapped together by somebody who didn't anticipate the ways that things could fail (e.g. malloc() failure, disk full, database connection failure, etc). Sometimes, it's code that was written poorly because the developer didn't know of a nice standard best-practices way to do it, didn't care to figure it out, or dismissed it out of hand because they didn't get it.
Other times, you run into code where the developer gets fancy in an attempt to shave every last cycle out of their code (especially when the application isn't even CPU bound to begin with). Sometimes, developers like to do it the hard way just to show off how smart they are.
Finally, sometimes the code you inherit is truly spaghetti code. Some of my favorites:
my experience has been that:
- anything that feels "clever" probably isn't. abstractFactoryFactoryFacade
- if you can't describe the code without using an acronym - it's probably something you don't need. ESB/ebXML/UDDI/EJB/Portal blah blah
- a bad solution that's used universally in an application is better then 3 good solutions.
> I am downright embarrassed by the quality of my code.
Good. You recognize you have a problem, thus you are already
getting better.
> It is buggy, slow, fragile, and a nightmare to maintain.
Instead, put your effort into maintainable, correct, and fast-
enough code, in this order of priority.
> Do you feel the same way?
Only in part. As I get better, I see the problems with my old
behavior, and I try to correct it.
> If so, then what is holding you back from realizing your
> full potential?
I do not think there is a full potential, I think there is
always some room for improvement, with diminishing returns
probably.
> More importantly, what if anything are you planning to do
> about it?
I try to always improve myself. Always try to produce the best
I can possibly do, compatibly with deadlines and such.
In no way I allow myself shortcuts for short term gain, which
I could then regret later when I have to maintain the thing.
> [...]
> Sadly the one constant in my career is that I am assigned
> to projects that drift, seemingly aimlessly, from inception
> to a point where the client runs out of funding.
Try to implement those project well. Maybe they'll fail anyway
(management mistakes), but you can find your satisfaction in
that you have done a good job. Probably nobody cares, but you
should. It is what makes coding interesting to me: caring
about the codebase, and improving it (and thus myself).
> Have any developers here successfully lobbied their company
> to stop or cut back on 'cowboy coding' and adopt best
> practices? Has anyone convinced their superiors that the
> customer isn't always right and saying no once in awhile is
> the best course of action?
Yes. "Best practices" is a very relative(!)term, but I get
what you mean. I try to convince the people around me
(especially above me) to avoid half-baked solutions in favor
of good maintainable ones, or at least to avoid panic and
think things through before acting. It is not always possible
to avoid customer-driven development completely, but you can
always make your case, especially if you do not fear to work
more to implement the good stuff.
(man one of these days I've got to attempt another password recovery lol)
I'm part of the Enterprise Architecture group at the company I work for. As such, not only is good coding skills important to me, it's part of my job to evangelize them throughout our organization. It's actually not too hard to avoid sloppy coding (and, incidentally, the other common problem you mention; running out of money)... the most important thing in my mind is to provide the client an estimate, and to get the estimate directly from the person(s) who will be doing the work. And don't consider code quality or rigorous testing to be an afterthought of that estimate; these tasks are first class citizens of your estimate, just like designing the application or coding the web pages... if you plan for and estimate them from the start, it's much easier to make sure it's accounted for...
Seriously, refuse to work on an application that you aren't given an opportunity to estimate. An estimate is only as good as the accountability of the person making it, and it is both illogical and counterproductive to expect someone to deliver someone else's estimate. I certainly don't quit my job when in a situation like that, but I do make sure I communicate clearly the risks involved in not re-estimating at that point in time... Then when we run out of hours and crucial tasks are left undone, at least it's not a surprise to the client and/or project managers, and they can deal with it appropriately...
...when I was just starting out professionally, and I must say it looks pretty darn good. The key to not be embarrassed about your code is to not cut corners when writing it. If you know you're writing crap, stop and think how to make it better. Don't write crap against a deadline, writing good code doesn't take that much longer. Don't be afraid to refactor/rewrite, just do it during your development/testing cycle, not right before shipping.
I have to repositories of code 100% written by me.
One of these is for a future closed source software. The code there is beautiful and elegant.
The other one is for a Lisp interpreter. Some parts of the code are elegant, some are pragmatical and the numeric tower stuff is damn ugly.
I believe that it depends on the task at hand. The lisp interpreter is far more complex than the closed source software, and it can't be made 100% elegant, some compromises had to be done.
We are Turing O-Machines. The Oracle is out there.
Bow-ties are cool.
i like perfection. i use code to get as close to a perfect understanding of the underlying system as possible. the flip side is that once i understand the underlying system i try to insert my code in the system in as perfect a way as possible. of course i am a rewrite fanatic. code is almost never as good as i want it. usually it improves after a few readings, but it rarely reaches the level that i require. reorganizing and rewriting are two of the most hated words for most engineers and managers. i consider these two skills to be my biggest asset. I have no fear throwing out the old, and writing it a new, and it is always better after i'm done. intense thought goes into every rewrite i do, sometimes days of walking aimlessly trying to figure out how to perform these operations in a "perfect" sort of way. I don't like workarounds, and i don't like patches. if something can be done, then it can be done well.
i have many years of experience working for the same embedded systems company, and i have earned company wide respect for my ability to solve anything. my habit for rewriting is known, and was originally "feared" but not anymore. when i want to rewrite something my company is behind me 100%. if it could be done badly then it can surely be done well.
ps. everything has its exceptions but what's written here is the rule.
nachum kanovsky
Not that long ago I had to write a PHP-script to take care of a couple of pretty simple and mundane help-desk things. I started out with about 4 or 5 different PHP-files, most of them libraries. Then after working on the project for a while, I had something like 30 files, again most where libraries. So I decided to put these different libraries into a single class in a single file. But still I had some seperate files. So, long story short, I ended up with 20 files all depending on at least 2 other files. Whenever I changed something in file A, I had to change file B. If I change file B, I have to change file C. But if I change file C, I have to change file A. I'm sure that if I posted that code here, some of you would probably start feeling sick and end up throwing up before you are finished reading the code. This is the worst piece of code I have ever written. But it works good enough, at least until I have to change something.
I prefer two spaces as well; inevitably people set their tabs to different widths, which means they use different numbers of tabs to line things up to make code look 'clean'. When it gets to your machine/IDE it generally looks garbled because *your* tabs are, of course, different. But, worse than that, when you're using tabs you might throw in a space or two to line things up - and then things really become difficult to read. Better to keep it all as spaces, in my opinion. Tabs are for things like theses, where print formatting should be taking up more of your time. But, then, I'm very clearly a visually oriented thinker, so the garbled text thing really irks me.
[Ego]out
I'd better not comment on any code then, lest someone thing I'm experienced.
You need to do some pair programming. Yes, I hated it at first and I thought it was silly. But after a short time, and having generated high quality code, I realized that there is some value to XP. I still prefer to NOT do it, but by not doing it you are depriving yourself of learning from someone else's thought processes. With one person as the coder, and the other playing the devil's advocate you can learn about what you fail to consider. With enough time, you can ask yourself: "what would my partner comment on?" Being able to do that will undoubtedly help your code.
It is easy to get offended when people make comments at first, until you switch places and you realize everyone gets comments on their code. Eventually you should be proud of the code that was done together because it will be better than the other parts of the program. Once that happens, then you should see pair programming as a means to an end.
Slashdot's rate-of-post filter: Preventing you from posting too many great ideas at once.
It must have been something you assimilated. . . .
I am one of those programmers that put a great deal of comments in my code. On average about 50% of my code is comments (including Javadocs). I have found that pretty much without exception those who complain about the amount of comments in my code don't put any comments in their code.
I have the same relation to my code as my wife has to her but. No matter how many compliments she gets, she still can't admit its any good. Sure, it could always be a little better. And the userbase will gripe a bit from time to time when comparing to the newest out there. But the stake holders makers are happy enough not to want to make major changes.
If you design it right in the first place, you don't have to worry so much about scope creep.
If you design it right in the first place, you limit the kinds of problems you can have; hence, you don't need to spend as much time in testing and debugging.
If you design it right in the first place, you might actually be retained to maintain your code, as opposed to being fired when the whole project tanks. And yes, I have worked at places where this happened.
Design isn't done because management wants to fulfill some programmer's odd views about how things should be done; it's done because management realizes that it reduces the cost of software over the entire lifecycle.
But I wouldn't be surprised if you're one of those types that management loves, but programmers hate. You know, the type who gets things done quickly, but in a manner so sloppy that the code maintainers curse you under their breath.
The society for a thought-free internet welcomes you.
I suspect that if you are involved in "projects that drift", then the basic problem is not coding quality. I have recent got involved in some absolutely terrible projects myself, and my impression is that the #1 problem is giving too little priority to design. Software engineers should understand the problem they have to solve as well as the customer -- actually, they should understand it better than the customer. Or alternatively the customer, and not some external IT guy who has first to be taught the basics, should be able to do the top-level software design. (Because understanding the task the software should accomplish, is usually more important than knowing the technical details of the implementation.)
Unfortunately, customers usually assume that software design is a trivial problem that any typist should be able to do after a few hours of explanation. And as for so-called IT professionals --- don't get me started on the crass amateurism that I have witnessed. The result is often that the programmers create gordian knots in an attempt to make the best of a chaotic design. That's not their fault. You'll go mad if you start worrying about it.
But if you have a good design, then achieving good coding quality should not be that difficult, if you are technically competent. I've noticed myself that when I am writing bad code, overcomplicated, unstructured, intertwined, and full of bugs, then the reason is often that I don't properly understand what I am trying to do. Because the design is wrong. If the design is correct, then it should be clear what a piece of code should do, and writing it should be relatively straightforward, and you should not introduce complicated bugs -- because you know how it is supposed to work.
So my first advice is: If you have the feeling that you should to be ashamed of the code you are producing, then stop right there. Probably your design stinks and you don't understand what you are doing. Re-analyze the problem, break it down in components again, make sure that you properly understand every step. Think it over thoroughly. If possible, go for a walk; that usually helps more than staring at your screen. Then first redesign, then rewrite.
As for coding style, I think it is most important to be consistent. I once got back a mathematics paper back from my teacher with a bad grade, not because the answer was wrong, but because there was no method to it. "Use a method" was what he wrote on it. I still hate to admit it, but he was right.
Most people don't use the full vocabulary of their programming tools, which in case of languages such as C++ is not a particularly good idea anyway. Instead they develop patterns which they understand and routinely re-use. It is best to adopt some set of patterns as your own; which one does not matter that much as long as you are aware that you rely on them, that you understand how they work, and are familiar with their pros and cons. From time to time step back to analyze your code for repetitive patterns; and think of what you should do with them -- retain them, build on them, forget about them.
The one advice I would give is that if you are using a coding style that aims for saving on the number of letters and braces you type, that is probably not a good idea. Saving on typing should be at the very bottom of your list of priorities. You should nearly always go for highlighting the structure, if you can.
Personally I also tend to over-comment, documenting every private field and method. And I write my comments first, and the code later, on the principle that you shouldn't be writing a class or a method if you can't explain what it is supposed to do. Of course I usually have to update the comments later, because one always modifies the flow a bit to optimize it, but that is fine.
* Low-level form and factor: The code is written by somebody of much lower ability, so the code is disorganized with lots of run-on functions. You can understand the code, but modifying or maintaining it is next to impossible just as speaking with invalid grammar is very difficult if you know better (ie "somebody sent up us the bomb", or repeating verbatim pretty much anything GWB says).
* Syntax and naming: The code is roughly at your same level of ability. You can understand it and modify it, but you don't want to because it smells bad.
* High-level structures: The code is written by a more skilled programmer. You probably do not understand why the code was written as it was even with documentation, and even if you do then changes you make will cause a lot of side-effects and unexpected errors. Sadly you should rewrite this code because you cannot make other than superficial changes since you fundamentally do not understand it.
Generally the code is at the lowest level you are complaining about.
Another common trait is to deny one's own faults. First of all, if somebody says something is "equally likely" as something else that's almost always some kind of rationalization. There are precious few things that are equally likely (or fair and balanced), and in this case any decent programmer should be able to determine immediately if there are some few ugly sections vs the whole program being a huge pile of crap. Of course the BIG mistake is to only have one programmer. What happens when they take a break or leave? Everything stops. Another mistake is to have programmers of very different talent (as opposed to experience) working together. This invariably causes the very talented ones to leave and the poor ones are left with code they don't understand.
Most employees are remarkable at aligning their effort with the incentives in their environment. The problem for management is that the employees align themselves with the actual incentives not empty platitudes about how quality is important.
In the software development environments I've worked in management values schedule predictability and turning around projects fast. Management does not care about or even evaluate code quality or long run productivity. They would rather have a short development phase and blow huge amounts of time and effort in maintenance. Lower levels of management might know that sloppy coding has long run consequence but they are incentivized to get releases out quickl. Upper management rarely if ever has any understanding of software development even in companies that exclusively develop software so they don't know any better.
Over time, a project that started with 5 people now has 3-4x times as many people who can't seem get anything done. Changing anything seems to result a cascade of bugs.
The solution would be measure productivity over the life of system but in most environments are way too short term focused for that.
When I deal with c++, and it's not often as I do mostly system level stuff, I'm usually looking for 'the work'. That is, I know that 'the work' is being done, but finding where that code actually is turns into a nightmare of following inheritence trees or container classes or vtables. Once I find 'the work', changing its behavior is usually pretty easy.
The funny thing is that I transferred from one University to another for the sole reason that the first wasn't teaching any c++ classes (though they still required pascal). Now I look at c++ as being 'too much rope' for the average programmer.
C++ was supposed to make things like reuse easier. It doesn't. C++ was also supposed to make code cleaner and easier to understand. It doesn't. Sure, you can write clean, reusable code in C++, unfortunately, it's not the usual outcome.
As long as your code works, who cares? Okay, forget efficiency and all that, when you have 1 week to work on a program someone wants, there's no time to tidy your code up unless you're nearly finished with it.
>I am downright embarrassed by the quality of my code. It is buggy, slow, fragile, and a nightmare to maintain. Do you feel the same way?
No.
Honestly, most of the time writing bad code is not faster than writing reasonably good code.
To improve even more, try having a policy of doing a quick code review before non trivial check-ins. Knowing that you'll have to show and explain your code to a peer, that does help in resisting the temptation to take some shortcuts (e.g., why save time writing when it will take longer to explain). Code reviews should be easy to "sell" to upper managers, as they provide a certain degree of mitigation for the risk of one programmer leaving.
Personally, the worst code I've had to write has been when I had to follow so-called "best practices". Things like excessive comments which quickly become out of date and incorrect, dictated program structure which doesn't correlate with the intent of the code, etc. Also, the more rules/procedures the company has, the slower people code, the less creative they try to be, and the more they resign themselves to just putting in their 8 hours a day following the rules, instead of trying to produce as best they can and get better at their profession.
Sure, there are ways to write good code. However, I find that whenever manager types get involved with dictating the rules for coding, you end up with worse code. That's my experience, anyway.
Do you feel the same way? Not anymore. I did and do about code I wrote when I first started. But I like my code now. If so, then what is holding you back from realizing your full potential? I learned design patterns and how to implement them. That's what's made me a better programmer. Have any developers here successfully lobbied their company to stop or cut back on 'cowboy coding' and adopt best practices? No because most non-programmers don't agree with the business value in it. But, implementing design patterns to solve my problems helps enormously. Has anyone convinced their superiors that the customer isn't always right and saying no once in awhile is the best course of action? No. Cuz the person with the money is always right, or they'll pay someone else to do it.
jg
..and "Design Patterns" by Gamma et als. 'nuf said.
- Try to do as good as you can at work, knowing in advance that the results will be fully compromised. The purpose of this work is to make money so that you can support your family--that's it.
- Do outside work on at least one Free Software (or OSS) project that meets your standards for quality. This is where you get your professional satisfaction.
Good luck. Mike"Not an actor, but he plays one on TV."
My code before I started taking computer science was largely modelled on the coding styles of whichever projects I'd been recently reading the documentation for (I used to spend a lot of time going over the GTK+ api docs for example). Now, after doing Comp Sci for a year, I'm starting to develop my own style (by taking the techniques I'm taught and modifying the ones I dislike), which I'm quite proud of and I think works rather well. My code is modular (broken into functional, replaceable sections) and hence easy to modify, easy to debug and easy to document. I say easy to document because their can be "high-level" documentation that describes what each of these modular pieces actually does (for a forest-for-th-trees kind of overview) and then, their is low level documentation describing how each modular piece does its job. By breaking it up into sections (big task? put it in a function, even if you only use it twice), the documentation job is much less daunting. A practice I highly recommend. As for judging other peoples code, I'm probably pickier about my C/C++ but I remember starting javascript at age 13 and seeing someone use a for-loop to go through all the elements in an array using the array length as the loop counter and the index of the element inside the code block and thinking "Wow, that is really clever, its concise and when you know what it does it makes heaps of sense." I think we're most impressed by coding technique we feel we would never have thought of.
Censorship is the opposite of education. If neo-darwinism were defensible, people would not need to try and censor ID.
Wow! Just wow! I mean, I can do a mental interpreter, but you're saying you can actually compile your code mentally? You must have done decades of mental training!
Have you considered changing your profession from programmer to jedi? You could probably give Yoda a run for his money.
You know, there is a difference between trolling and pointing out the flaws in your reasoning. Just saying.
The biggest thing I see wrong with other people's code is not at the syntax level or to do with commenting. It's based on a misunderstanding of basic CS principles. An example is in order from last week...
In the codebase I work on, there's a module that analyzes documents and tags them, assigning different weights to each tag based on relevance. (Think of the way google works--it reads a web page and tags it with terms, then if you type in one of those terms while doing a search that document comes up--yes I know this isn't the way google actually works, save it. :-p ) At one point we send a list of tagged documents from one system to another, and this area was the source of many, many bugs. The responsible developer spent the better part of last week slaving on this code and every change seemed to introduce more bugs than it removed. Finally, I got involved to see what the problem was.
Here is one thing (out of many) that I found. After the docs arrive in the new system, each doc is supposed to be persisted along with the top 5 most relevant tags (the rest discarded). The code was written to create a Document, check a hash table that maps the doc to the number of tags it currently has, add a tag if that doc doesn't yet have five, then increment the value associated with that doc in the hash table. When I saw this, my head almost exploded. At some point, this developer thought it would be a good idea to create a hash table and keep this information, information which is available in the document itself (he could've just called doc.getTags().size() to see how many tags it currently had). Now he created this hash table and all his code was written to depend on it, so of course he had to write a lot of code to keep it in sync with the state of all these documents.
This sounds like a simple enough thing, right? It's not necessary, and it's not the best thing, but it's a fairly simple mistake and one that couldn't impact code readability all that much, right? Maybe--but consider that this is one of about 10 simple mistakes I found, and you can imagine the explosion of interactions of all these simple mistakes...and that's why we burned a person-week on something that should've been trivial. When I pointed out to this developer that he could just get the number of tags directly from the doc itself, and doesn't need to keep this state in some other object too, he said something to the effect of, "That's a different approach, but whatever...one's not better than the other."
But one is better. If this developer understood the difference between intrinsic and extrinsic, he never would've written that code in the first place much less defended it. To put a fine point on it: the number of tags associated with a document is intrinsic to the document itself, so that is where the information should live...not there as well as some hash table somewhere. The document is the authority and the final word on how many tags it has at any moment in time. (There's a principle in databases called the SUA Principle--it means one should keep data in a Single place, in an Unambiguous manner, and that should be the Authoritative source of that data and no other. It applies here too.) Putting this info into some other object, even if that object exists solely for the purpose of tracking that info, means you're creating an object that stores information that is extrinsic to it. Never a good idea...now you need a whole bunch of supporting code that keeps the extrinsic info in sync at all times.
Let's say I'm designing a Ball class for use in a physics application that students learning physics can use. They can shoot the ball out of a cannon, put it under water, in deep space, on Jupiter, etc, and see how the simulation behaves. As the developer of this class, I decide to add a characteristic to the ball that keeps info about its "heaviness". What should I add, a getWeight() method or a getMass() method? The developer I was talking t
but have you considered the following argument: shut up.
In my experience, the following principles seem to consistently produce good outcomes for both devs and customers alike:
The first point mainly addresses issues at the project/team level. You can find more information on Agile at http://www.objectmentor.com/resources/articles/Agile_Methods_-_The_Bottom_Line.pdf
My second points bears directly to the issue of code. There are many ways of solving problems. One is to bulldoze ahead and use ad hoc programming, dealing with bugs and design issues cropping up everywhere as you go along. Another one is to leverage other people's experience in the forms of design patterns and good design principles.
I used to use OOA/D and ad hoc programming. Code would work, but defect repair and adding new features would most of the time take a huge effort. I now realize that good OOA/D skills alone isn't enough. Without the aid of design patterns and good design principles, I would be much worse off (no, there's no kool-aid involved.)
The Object Mentor website ( http://www.objectmentor.com/resources/publishedArticles.html ) is a great resource. The Wikipedia project has a lot of pretty good programming related topics ( http://en.wikipedia.org/wiki/Design_pattern_(computer_science) ). Good luck!Finding code that looks like this is far more annoying than the lack or excess of comments: Now imagine misleading bits like that all over the code.
No problem. About half of all the code I've written in my 20 year career is for use in spacecraft, or space related stuff on the ground. I have absolutely zero problems convincing management that code quality is paramount. Coding is only a small part of the product development time anyway, documentation (Requirements, Architectural Design Document, Detailed DD, Test & Verification plans, lifecycle plan,...) and test activities take ca. 70% of total time.
I've coded in assembly for Mir, in C for Spacelab and I.S.S It doesn't get much better :-) So my advice: try to find the right place. Embedded programming typically has to be better quality than for instance web apps. People just don't tolerate a washing machine that needs a three finger salute (or a spacecraft for that matter).
Life is good.
You need to get into the habit of planning for the unforseen. I think a lot of that comes with experience, after a few hard knocks with projects where new requirements caused a lot of ugly hacks to go in because the original code wasn't flexible. Every time I write a function I try to think of how else it might get used or abused and try not to lock out such growth. Often for me, it's a matter of realizing that there are features they are going to want that they powers-that-be haven't thought of yet, and coding for the eventuality. It won't completely eliminate the problem of "drift" but it can help...
Eg, you wanted a professional but didn't want to pay for it. The result was fairly predictable from that point on.
-- And when Justice is gone, there is always... Force. --Laurie Anderson, "Oh Superman"
Sometimes you can't make them modular.
.h file.
You put all the headers inside #DEFINE statements in each
That way you can include them ten times and only the first one is processed.
We are Turing O-Machines. The Oracle is out there.
As always, start small. Introduce best practices one by one. And don't go overboard. Unit tests are good, but you shouldn't spend the next three months doing nothing but writing tests. After all, you get paid to provide business value.
And remember that sometimes little things can have big impacts. Static code analyzers can sometimes find bugs for you without you even having to write a unit test. A unit test that catches a bug introduced by a co-worker may get his interest in unit testing. And if the little things you do have only little impact, well, that's fine too. After all, you're in for the long run, aren't you? You're running a marathon, not a sprint.
Yes, and no. Mostly the customers are right. After all, they are the ones using the software, not you. But I work on shrink wrapped software and sometimes what one customer wants is just not what most other customers would want. In those cases, you need the luck that the one calling the shots notices this too and isn't blinded by $. In the former case, you're blessed. In the latter, well, you probably have more than one problem...If you code in a language with C syntax TABs are better.
Some people prefer 4 spaces for indentation, some 2 and some 8. Tabs lets all of them work in the same file with ease.
Spaces should be used in languages like Lisp. In fact, all your arguments against TABs were first done by Lisp programmers, and were done against TABs in Lisp source files.
I don't know how the hell can you format C code to need spaces mixed with TABs in front of the source lines. (Something trivial in Lisp, as every single character indentation counts there.)
We are Turing O-Machines. The Oracle is out there.
I am pretty proud of my code. How? I design my program before I start programming. I think before I fix a bug. I test. A lot. And after that, I test again.
;-).
Good example I had today. There was a bug in my code that was a bitch to fix on-site (I work as a systems programmer in industrial automation). My boss tells us to never, NEVER program on-site, and there is a reason to that. When I got the code back at the office, made some tests to simulate the results and did some severe thinking, I fixed the bug by changing 2 bytes. Yes, you read it right, two bytes. If a bug is fixed that easily, it means your code design was pretty correct.
Adn this is not an incident. In the same project I had more simple fixes to seemingly complex problems before. For me, a sign of good design and proof that I am FUCKING BRILLIANT
-- The Internet is a too slow way of doing things, you'd never do without it.
I agree with the parent post that ... ... this gripe with over-commenting is fundamentally flawed:
...
IMHO there's a deep fallacy in the flip comment that
If the code is written well, it will speak for itself.
Real-world program code is written for at least four 'audiences': the author, the machine, the user, and the maintainer.
The first three of these need only 'worry', in the aggregate and at a minimum, about the code compiling and running ok with correct results.
But the fourth has an additional worry: to know about the design (or at least part of it), and its purpose.
For these audience members, the code must amount -- somehow or other -- to a sufficiently explanatory description. The question is, what is sufficient?
(Clearly it's of no use at all in anything except an exercise for language-learners to comment at the level that int i=0; declares and initializes an integer.)
How much real background you give to explain a story depends, mainly, on what you think your audience already knows.
Code itself can intrinsically give only part of a story -- the concrete operations or conditions that are to be performed or set up. That doesn't in itself tell the maintainer why it is being done. (Sometimes it doesn't even indicate when it is going to be done -- in any way that illustrates the purpose.)
Some coders seem to think, that they should be able to ignore any members of their audience who don't know or understand as much background as they do themselves. They may have reasons of pecking order, or maybe it's a matter of imagined professional honor. Some coders may even think, that if they give out more than a very few snippets of explanation, they may even be letting themselves or their colleagues down, with a risk of giving out some kind of a subtext message, that they believe their audience doesn't know or understand very much. (Such factors as these could also explain the tones of scorn and contempt that sometimes seem to creep into these discussions.)
But it's important to acknowledge frankly that there can be all kinds of reasons why the audience, especially the maintainer, may not be acquainted with the reason for this or that aspect of the code.
(At the moment I'm writing some code that is full of arbitrary-looking numbers and features that come from outside standards. Maybe it's an extreme case. But it's been a non-trivial issue here even to determine on checks for correctness -- let alone actually carry out the checks, and very hard to know where and how to put in any modifications. That's true already for me, let alone anyone else who may come to it later on. So my comments here are for my own benefit as well as for any later-comer. The comments cite external sources and reasons for the commented features, including literature-references and a few words about what they stand for. This is code that can't possibly speak for itself.
But I've seen code with equally-strong dependence on the outside world, 'cleaned up' and 'prettified', by getting put through a formatter that strips out comments, indents 'nicely', and then substitutes all the meaningful variable-names with totally meaningless ones. The result is totally unintelligible and uncheckable -- and valueless.)
So my take on this is -- if in any doubt (and that's practically always), tell the story.
-wb-
Uh... no it isn't. I don't give that time away for free, it's billed at a nice hourly rate. The more design time, the better.
Patterns were developed to create a common ground where people can think about problems in a similar way.
I don't think that's worked. If anything, they've just created more confusion and more ways to head down the wrong path. The more experienced developers merely call them "suggestions to consider", not a central bible of truth.
Table-ized A.I.
I had this problem with a guy that was complaining that my code was full of GOTO statements, used all global variables, and didn't have any comments or subroutines.
Goto's are "in". They are part of the Organic-Driven Programming craze. The brain has biological wires all over timbuktoo and back, so why shouldn't your code? Goto's were good enough for God, so they should be good enough for you too, a lessor being. Let the Vine Shine! Blocks and subroutines are for liberal control-freeks.
-1 Troll
Table-ized A.I.
Let's don't forget that we also need better programming languages. After all, we think and speak in human language, and code is written for machines to understand. Often, even when you can think of a clear and beautiful solution, converting it to actual code still takes ridiculous amount of time, experience, pain, and frustration; consequently, the results are bad code and poor program structures that are very difficult to maintain and evolve. We need better programming languages that can take high level human descriptions and convert them automatically to machine code. I guess this sounds like a joke, maybe for now, but who knows what we will have in ten to twenty years.
When I write my code I try to keep in mind what could happen if I'm in an accident and my coworkers have to maintain the code. I don't write comments for myself necessarily, but for the poor soul who has to deal with the code when I'm not there.
(I had pneumonia in college once and my project partners for one class were in my room every day listening to my hoarse whispers about how my part of the code worked. So I learned this lesson early
I am very proud when I come up with a compact, easy to understand way of doing something. Especially when that tiny bit of code is easy to harden until it is bullet proof. I am proud when I can take existing code and make it twice as fast or faster. When I can take existing code that is a mess of interlocking hard to understand functions and change it around so that it has clear easy to understand and test interfaces.
Have gnu, will travel.
I fully agree - Having well worded comments is just as important as well thought out code. There are many times when I am debugging a piece of code and I know what the code is doing by reading the code, but since there are no comments I have no idea what it is supposed to do. And if you have to work on code that is not documented anywhere , except in the murky gray matter of someone that thinks they remember telling someone to write something, the in-code comments become essential.
I typically preface my more complex code blocks/functions etc with a brief algorithm this way someone in the future knows what I was intending to write and well and when I am writing I can verify that my code does what my algorithm says. This sort of documentation also helps clarify the task and helps define all possible logic scenarios. This way you can write a more complete, stable piece and possible bug free (yeah right) of software.
This is just a mature way of programming.
P.S. - I never claim someone else's code sucks just because they don't have my 'style' of coding. I just want the code to work properly.
The unfortunate truth, and this goes for ever profession, is that the customer is almost NEVER right, in fact, you can count on them being wrong about 95% of the time.
The worst part is when the customer doesn't know what's best FOR THEM. Especially when it's your job to do what's best for them... then you have a contradiction. I work in advertising, and I run into this constantly. It's my job to help my clients sell their products/services, and they've hired me to do just that. But many times, clients think they know how to do it themselves, and then tell me what to do, when their ideas could, likely, harm their image and their sales.
What do I do? They've hired me to do my job and help them, but their very instructions will certainly harm them. My hands are tied, I just want to scream at them, "Let me do my job, and make you lots of money!"
Multiplayer Gaming (defined): Sitting around, discussing single-player games with my friends, at the bar.
I look at a piece of code and say: "Who wrote these f**king lame code in our project? It sucks."
And it turns out to be me. Well, I'm just having a second thought on how to do the job.
But not anymore.. Well, I take that back. I'm proud of some of my code, mainly the libraries and such. But most of my code for work is in C# using ASP.NET, writing random pages for people to get various reports, change database settings, etc. I tried to keep things clean for a while, but I came to realize that:
1.) Users want quick changes to things, and don't want to listen to why it's going to take longer to do it *right*
2.) Most of the stuff I do does not need to be repeated, or if it does its rare enough that its much more convenient to simply copy code than to create 5-6 new classes to do something that's only going to get used on 2 pages
3.) ASP.NET does everything it can to discourage you from creating your own web controls
4.) I just don't care enough about *this* kind of programming to put any more effort into it than I have to
Now the stuff I write for fun.. That's a completely different story.
I've spent a lot of time improving how I write code, and one of the most frustrating things that I've come up against are that a lot of people present programming techniques as magic bullets, but then when you go to use them, you find that they haven't actually been thought through very well.
Consider the famous patterns book by the gang of four. If you do a lot of software development, you probably know what I'm talking about. This book is referenced more in general software design discussions than any other. People often proscribe solving some software problem with a solution from the GOF book, or various article that present other patterns in a similar fashion. The problem is that some of the GOF patterns and derived patterns are inherently broken! They were written up perhaps because they were widely in use in some communities where certain sets of problems don't have to be dealt with, but if you take them outside of that, they can blow up in your face.
Probably the most obvious issue is the singleton pattern. In its most common implementation, it allows you to grab a universal single instance of an object through a static reference. It is highly convenient and almost universally used. However, it makes it almost impossible to do dependency injection, and breaks the ability to do light weight unit testing on many areas of the program! In practice, singleton is equivalent to and just as bad as a global variable, yet it is proscribed all over the place. I wish they'd revise the book with a "singleton considered harmful wrt software testing" warning.
Another pet peeve of mine is the visitor pattern, or at least how many people use a variant of it in practice to solve the double dispatch problem. This may be a bit esoteric for slashdot, but let it be known that visitor is in no way a good solution to double dispatch. Think about it! Every class in the hierarchy needs to know about every other class in the hierarchy. That is not encapsulation! An addition of a class requires changes to every single other class! It isn't even possible in many situations (if you have a lot of classes, or if you need to load some classes dynamically from a plugin). The visitor pattern is widely proscribed here, but a little thought and experimentation reveals it as a horrible hack! That said, the double dispatch problem doens't have a great solution in C++ and some other languages, but some form of dynamic typing (which is otherwise a bad idea in most statically typed languages like c++) is clearly necessary here.
Anyway, those are a couple of my pet peeves about how software development is practiced and taught. Generally I've found that coming up with flexible, correct, and efficient software is a difficult, but fascinating problem. While there's a lot of people who are domain experts and know how to write a compiler, a web app, a video game, or some other kind of software really well, I don't think I've seen a lot of good general approaches to the problem of software. Everyone seems to think they have general patterns, but this is largely due to the fact that people overly specialize and don't step outside their field enough. In practice, engineering seems to be about finding the simplest structure that solves the local problem (which is fine, great even for practical purposes) and we've yet to address a lot of the general problems of software development.
When it comes to PC-based code (VB, C++, whatever), I've got a few "Hello World" programs that I'm particularly proud of. Everything else always seems to be a work in progress.
But that's not what I'm paid to do, I write software for PLCs (Programmable Logic Controllers). PLCs are used to control automation (as in the machines in a car plant).
It's pretty much based on the bit level (we can do multiplication and division, but it's mostly a graphical representation of Boolean logic).
We get inputs from the machine (pushbuttons, limit switches, pressure switches, temperature RTDs, etc) and based on what we want to be on, and just as importantly, what we want to be off, we turn on outputs to run motors, light pilot lights, whatever. Now that code I'm proud of.
I dream in binary.
Use a good language! That will reduce the complexity of your code greatly. Forget C/C++. You just can't write good code in those languages. I prefer BlackBox/Component Pascal. o Modular o Garbage collection o Great compiler that puts the cursor *at* the error in your text. o Development environment has compound documents for high quality publishable writing and the same document for source code. You can embed bitmap images to aid documentation of your code. o No make files! o No compiler switches! o No linker switches (no explicit linker)! o ABSTRACT and EXTENSIBLE data types for generalizable programming. o many other good features. Best regards, Doug Danforth
Most of my income over the past 10 years has been programming, usually freelance. I have no degree or other credentials so I only can work for people who already know what I can do, or companies small enough to be persuaded that I can get the job done.
I find that all entrepreneurs work more or less the same way - they don't know what they want, but they want it RIGHT NOW; then when you give it to them, they have no time to look at it. Their checks clear, but I'm pretty sure half my projects never even got looked at... which is just as well because they were mostly crap - no design stage, vague goals (frequently changed along the way), and under-tested. Documentation? HAH!
Contrast with a research organization I was associated with, where instead of "We must do this fast or we will lose money" the attitude was "We must do this right, or all our conclusions could be wrong and people might die"... There, I had the time and resources to do the job, and my employer knew what they wanted - and tested what I gave them to make sure. Stuff I wrote 8 years ago is still running fine. Documentation written, but never needed.
So, I'm proud of SOME of my code...
If you write your code and are afraid to go past 80-characters you are either i) nostalgic or ii) old or iii) think that 80-characters per line is cool or hell, all of the above.
Seriously, does limiting yourself to 80-characters bring you back to the disco era (remember long hair, sandals, and leisure suits)? Or maybe you still use punch cards? Eighty characters is definitely less than half of the way across most modern screens if you haven't noticed. Oh wait, you might want to print out your code! Again, symbolic debuggers have been around since the 1980s (at least for most modern operating systems). Blah, blah, blah...
Merry x-mas and buy yourself a new video card that can sport up to 132 characters per line!
To actually answer your question:
Have any developers here successfully lobbied their company to stop or cut back on 'cowboy coding' and adopt best practices?
While I wouldn't say "best practices," I did work at one small company where me and another developer were able to convince management that we needed to have some standards in the way we wrote code. The company was a mess and often lied to our clients about what we could produce, but we were able to make the job significantly more fun and produce significantly better code by implementing some very basic things. We got them to start using source control. We were able to get them to let us write better and reusable code by convincing them to start using some basic "agile" development. Customers really appreciated having periodic drops (milestones) of what we were working on to make sure it was going in the right direction, for example. But we had to put forth the business case before we could convince them. That's the biggest thing. It has to make business sense.
I am not a software programmer, just an engineer who is familiar with number of programming languages.
Regardless what language, I usually try to do first is to get the requirement and write a very controversial, uncommented, messy code which fulfills the requirement. Once its working perfectly, I investigate the ways to improve its performance in whatever ways possible and make a finalized version with comments.
Back in my uni days, one assignment was to write a MIPS emulator (for a large pool of commonly used instructions). Others were wrestling with neat codes while I highly insisted on the accuracy and reliability of the code. After 2 weeks of double shot espresso, I developed a perfect emulator, which later selected to share at the Uni server as a reference. Of course I did lot of finalizing (commenting, renaming variables etc.)
I was quite scared at first, as many would not understand my code (because many were using this to the follow up assignment, losely based on this code). But... astonishingly, people didn't find it a big issue at all.
So.. some of my experience in bullet form
- write simple code, forget about bringing complexity as its not gonna help you when things go large.
- use as many as functions/classes.
- name variables with common names rather with encrypted security code.
- first concentrate on the reliability of the code, make it work.. then think about how to improve.
- rule of thumb "less complexity, less things can go wrong" (this is why many GT cars are electronically not fancy)
You could for one thing start not using the excuse that everyone around you is not acting as expected and start writing quality code (what ever that is...) and not worry so much about what other people do. I see this behavior every day at work, someone puts something together saying, It sucks but so does the rest. That way of approaching things are wrong. I the old two wrongs doesn't make a right. Do your best even if it only a few functions or methods on a class - it better than just following the flow of bad code. What I'm trying to say is, don't follow the flow do the right thing yourself, use best practice and others will follow you.
It's inevitable that some of your code will be sloppy. Not everything deserves to THE FASTEST IT CAN POSSIBLY BE. First of all, that's what optimization is for, and there's a reason to do that last. Trying to get too fancy too quick means mistakes. Second, much of any program is going to be pretty trivial stuff. An hour spent prettifying an unimportant function is an hour not spent fine-tuning a mission-critical function.
That said, there are always going to be times when you have to go back and make some of that horrible code elegant. Or worse, go back and rework someone else's code. The SINGLE MOST IMPORTANT THING is function documentation. Every function you write, sloppy or otherwise, should specify
1. General, high-level, informal stuff:
a. What it's supposed to do in simple terms. (More mechanical descriptions should be inside the function, generally over control statements)
b. Where this function is intended to be located in the program flow (esp. what functions call it and what functions it calls)
2. I/O:
a. What its inputs are.
b. What its output is.
c. Acceptable values for both.
3. Potential tripups:
a. Any external side-effects or dependencies (setting a global variable, destructive behavior, RPCs, etc). (Ideally the answer to this would be "none" in almost every case.)
b. Brutal kluges (AKA the ubiquitous "fix this later" list)
c. Known problems
Functions written with even 2(a)(b)(c) and 3(a)(c) on that list should not only be trivial to test, but more importantly, it means that if you need to scrap the function and start over from scratch (which, let's face it, happens a lot), then in theory you should just be able to delete everything after the declaration and write a new function that does exactly what the previous documentation says it's supposed to.
Any code that describes its functions this way and uses reasonably descriptive naming conventions should need little in-line commenting. I generally don't worry about sloppy code, I worry about code that works and is maintainable. Even my own code often looks incomprehensible to me 6 months later if I don't follow good function-documenting practices.
We should always approach good coding like we do good writing -- tell 'em what you're gonna say before you say it. If you can do that, everything else is a breeze.
Almost as good as pointers.
CS is a science? First I've heard. I treat the whole thing as an engineering endeavor.
John McAfee 'It was like that time I hired that Bangkok prostitute; to do my taxes, while I fucked my accountant'
I am downright embarrassed by the quality of my code. It is buggy, slow, fragile, and a nightmare to maintain. Do you feel the same way?
... no.
Well
The higher the technology, the sharper that two-edged sword.
The interesting thing about commenting is that it's very hard to teach in a classroom, mostly because it's hard to give students a project in which it's really important. (OOP was the same way for me, honestly... in college it seemed like extra hoops to jump through for no real reason because even a 'big' project you do for a class pales in comparison with the kinds of things you work with in the business world.)
The first time I had to maintain someone else's code and didn't know what they were trying to do, I thought I finally understood the reason to comment code.
The first time I had to maintain MY code a year later and didn't know why I had written it the way I did, I really did get it.
Writing clean, readable, self-documenting code is important, of course. Writing a pile of comments is no substitute for it. The limitation is, even the best code only enables the person reading it to know what the code does. It doesn't convey intentionality.
If something seems like it's written in a backwards way to me, was that done because the programmer didn't know better, or because of a reason it really needs to be that way that the original programmer knew but I don't? What if the code is right in a certain set of circumstances, but makes some assumptions that now don't pan out? What if the code was right five years ago, but now the business rules have changed? (Or worse, what if they've changed for half of the business that uses the program, but not the other half?) What if what seems like a hack turned out to actually be necessary for the program to reach its performance requirements? I've seen all these situations and more constantly.
Comments aren't there to help me understand what the code you wrote does if you wrote it well; they are there to help me understand what you were thinking when you wrote it, so I'll know how I should change it and why.
I once felt the same way, but then I found a company where failure was not an option. If your code wasn't good enough, there was a seniour developer there to take over, if you failed to complete your assigned task, someone else was there who could do what you could do in a month in a single day. Failure is not an option - find a way or find a way out.
Its an interesting way to do work, but in the end, you end up with a decent product which has many bugs, but not many critical ones.
Actually, I encountered this very conversation at work today.
There is a differnece between a junior and a seniour software engineer. While the junior engineer sees the senior as unable to recognize the "brilance" of unit tests, the seniour engineers remembers his folly into unit tests and recognizes only the stupidity of unit testing with disregard for the whole - unit tests are only that. Ultimately, it is experience that matters, and no matter how smart, clever, or cute a solution is if it has not experience behind it it is ultimately horse patutity.
Before end-of-2006 I had always won these arguments, or not taken the job to begin with. Now I am facing 1/10th of the hours needed for critical financial applications, violating copywright law specifically with GPL licences, and long hours of free work in the promise of new paid projects.
All of these things I have said no to in the past and won, since 2006 I've lost every client or job for trying to enforce business law or standards. What gives? It hasn't been this bad ever and I've worked 11 years in SF developing websites and intranet applications.
More often than not, I've seen people putting in comments that explain the code:
//initialize i
int i = 1;
I mean, what sense does that make?? The mistake most programmers make is they comment the code and not the intent of the code. Some people write the code first and then comment it. Often times, the actual algorithm doesn't reveal itself at all in these comments. The reader keeps wondering what the hell is going on. I have tried to understand one such algorithm that used several different heuristics for accomplishing a particular purpose. The "code" for this function was more than 1000 lines and it was sparsely commented. It outlined the "intent" of what it wanted to do. But the code was too darn confusing. The sheer amount of variables that were used made it very hard to actually keep in mind what was going on.
What I have learned is that you cannot "understand" code that is written by someone else and is complicated. You will be limited by your intelligence in trying to understand that code. The only thing you can do is fix some bug that may arise.
I am proud of some code I have written, ashamed of other code I have written.
I hold all code to the standard of elegance. I think elegance is largely a matter of taste, but there are absolutes. Repetetive code is not elegant. Large blocks of code are not elegant. Special cases are not elegant.
Recently, I have been getting the impression that whether the code I write is elegant mostly depends on the circumstances. Given enough freedom, I will write elegant code. When constrained by the language, time, or the code I have to interface with, my code often comes out less elegant than I could wish.
The ugliest code comes when (1) the language does not provide powerful enough abstractions (which I could use to contain the mess), (2) the library I have to work with is buggy, and (3) I am pressed for time. I guess the process is somewhat like this:
1. Use trial and error, and copy-pasting from the 'net, to write lots of snippets of code, until you hit one that works.
2. Copy-paste that one and adapt it to all places you need something like it.
3. Be happy that it seems to work now, and hope you never have to deal with it again.
Whereas my normal coding flow is something like:
1. Review the requirements and available building blocks.
2. Design a solution that implements using the available building blocks.
3. Look for patterns you can abstract from and code that can be re-used.
4. Implement the solution with a minimal amount of self-documenting code, with comments in the parts you can't make self-documenting.
5. Document what you've implemented, why, and how others can use it.
Please correct me if I got my facts wrong.
At our shop we would add the member function below. We would also add some (unit) tests. It's more work, but in the end the quality and the maintainability of the code is higher. Note that code like this is automatically inlined and that there won't be a performance penalty.
void InitializeToOppositeEndsOfRange(ref int nIMin, ref int nIMax, ref int nJMin, ref int nJMax)
{
nIMin = m_nIMax;
nIMax = m_nIMin;
nJMin = m_nJMax;
nJMax = m_nJMin;
}
Obviously there is a balance to be had when documenting your code. For me, commenting is a literary endeavor; good comments should explain exactly what the code does, explain anything that's non-obvious, proudly point out your brilliant insights, and own up to any sleazy hacks that you were forced to perform - and do so in an elegant and entertaining manner. The ideal comments are those that allow your audience (even if it's just an audience of one, you) to understand what your code does without boring them to tears. This helps the comments do what they are supposed to do: explain what your code does, and reduce the number of "WTF?" moments your readers have (it is particularly embarrassing when you are the reader going WTF?!). They will also remind you, when maintaining your code, of both your mad skilz and the stuff you really need to make more refined before anyone else sees it and thus realizes what a kludgemaster you really are.
As a rule of thumb, you should probably have as many comment lines as code lines, but they will be clumped in particular areas. Of course, YMMV.
A bit OT: a previous poster wrote: "And each time I see those nuggets of perfection, I snag them. They get added to my pile of code samples for later use. Either in a straight copy or as a foundation of an idea that gets recoded, depending on license requirements."
This reminded me that old programmers don't write code, they just remember it and type it in again. Though I doubt I'll have to remember any 6502 code anytime soon, a pity since it was such an elegant little instruction set.
Best,R
"World Domination - a fun, family activity"
... and by writing crappy code and assuming all other code is crappy, I can avoid both Pride and Envy. Two deadly sins down, 5 to go.
That should really be getRestMass() since the apparent mass will change with the relative velocity of the observer.
But then if you put the ball into a subspace field, the inertial mass will decrease, so it should really be getRestGravitationalMass()
(Mis)Using enum to introduce constants is _evil_ (IMHO of course) since you are poluting the global space but you aren't providing any kind of certian type info. That is, you don't know the size or signed-ness of an enum element.
scoped constants are why god invented "const"...
Which is cleaner and more clear:
enum {
Target = 8,
Repeat = 17,
Factor = 16,
Fault = -1
};
or
const unsigned int Target = 8;
const unsigned int Repeat = 17;
const double Factor = 16;
const int Fault = -1;
The explicit typing (in C++ and ansi C, the enum above is possibly a signed char) and the removal of "bogus" associations Fault and Factor don't necessarily have a relationship to Target or Repeat, so why are they in the same enum? What would be the increase in clarity if they were each in a single element enum?
See, even you have bad shortcuts in your standard approach...
Innocent people shouldn't be forced to pay for inferior software development.
--"Code Complete" Microsoft Press
...single neuron out of Spock's brain. Some of my private code is downright pleasing, although revoltingly non-commercial. When I was (*ahem*) "coding" — HR geekphreeze for munger wrangling that translates more or less 103% correctly as "less money than programmers get," just as HR learned very early on that "programmer analyst" is $35,000 more per annum than "programmer" — back in my shrinkwrap daze, I always felt my stuff was three weeks too premature for genius. Deadlines. It's worth noting that NOT ONE LINE OF CODE that was commercially successfully for that company (long since gutted by a buyout during the Dot Com shakedown) was ever written in-house.
``Tension, apprehension & dissension have begun!'' - Duffy Wyg&, in Alfred Bester's _The Demolished Man_
I have worked at several companies where I have had to drag the team into following some sort of agreed practice. I'm not saying a "best practice" because hardly anyone has metrics to prove that their practice gives them a competitive advantage. I'm not even saying a "documented practice" because that would be asking too much. This is more of a "gentleman's agreement" on the minimum level of work that will be accepted.
... because It Can.
In my experience any change you propose will face resistance from your co-workers and management if it appears to involve more work. This means that anything you try to introduce must have a clear and immediate advantage that actually reduces workload (and/or reduces cost).
Straight off the bat you can forget about coding style. It's where most practice-mongers start, and it's why most attempts at introducing "best practices" fail. No only do you force your team into a religious conflict, the benefit of a Single Enforced Coding Style is marginal (and there is academic research to back that up). Once you have buy-in for the value of practices, introduce two simple rules to handle coding style: (1) within a file maintain the style; (2) don't restyle an entire file (it wastes time and makes version diffs impossible, especially if everyone starts doing it).
You can also forget about taking the stair machine to Agile. You boss and peers aren't going to buy pair programming or that amount of unit testing (and certainly not writing the tests first).
Step 1 is to introduce source control. Use something Really Bloody Simple. Visual Sourcesafe if you can. Subversion with a GUI client if you can't. Don't restructure projects to make them play nice with source control; don't use branching and all the other advanced crap. Stick to the basics. Check out, change, check in, tag/label occasionally. Focus on the value proposition: everyone has access to the code, the repository is an "extra network copy" in case your development PC crashes, and you can diff between versions which makes finding out what you broke REALLY easy. Tags/labels allow you to easily find the last known-good build.
Step 2 is to introduce MINIMAL documentation standards. Encourage developers to put a one-liner at the top of each function saying what it is _intended to do_. Then state what it is supposed to return. That's it. Anyone maintaining code will see the value of this level of documentation very quickly, and will start bitching at developers who fail to document their functions. Point to you.
Step 3 is to introduce DBC (Design By Contract (TM)), or part thereof. DBC is IMHO the first step to bug reduction and improving the ease of debugging. Every function must be able to return a valid answer or an error, and must start by checking all of its parameters. EVERY function. Even that inner inner loop that has to be fast because otherwise the universe will end. If you were working on something that really had to be that fast, your team would already be using Best Practices. A Lot. Whenever you call a function, check for errors. Never assume that the function call succeeded even if you Know Deep Down that it Cannot Fail
Another way of looking at this is to remember that every CS 101 course says "check input parameters". You should do so in The Real World as well.
Step 4 is to create a culture of unit testing. But do it right. Test as LITTLE as possible, but test the most likely to fail conditions. Most people write unit tests starting from the simplest cases and working up; don't waste time, go for the jugular. The intermediate cases help in debugging, not in regression testing. If the worse possible cases (especially corner cases) chances are good that the rest works too. Good enough that you're wasting time testing them unless you have a big budget and lots of staff.
If developers resist unit testing, hint subtly that it is a convenient way to shift the blame to others. The unit test on YOUR code fails, so this i
i-name =twylite [http://public.xdi.org/=twylite], see idcommons.net
Whether you're writing C, assembly, or one of the many other languages, it helps to get critical review from other more experienced programmers. Most of the time when you're starting out it can be brutal. You may find you don't want to be a programmer/designer, but don't give up. That pain is just your mind expanding, and adapting to the thousands of patterns involved.
Becoming a good programmer is much more evolutionary, than revolutionary. It's about doing more with less, and making that less be correct. It's about testing, and interactive testing. It's about using graphs or generating images for code that isn't easily testable with a regression test suite. It's about leveraging the language features for your own benefit, and combining them in new ways.
Code should read like a novel...The comments should be in paragraph form. The part of the code that actually communicates to the computer should be like dialog.
You can't have too many comments. I like to place a photograph of someone attractive next to the monitor screen. I pretend that this person is somehow extraordinarily interested in the program and how it functions.
Then I use a speech-to-text program and talk about the code. Describe it from the beginning; what it does, why it is needed, and what is special about this code as opposed to the other programs out there that to more-or-less the same thing but not as well as your code. Talk to the photo. It's a fraud, it's a little pathetic but ignore this feeling. You are creating comments.
You end up with a lot of speech converted to text. Break it into paragraphs of a few sentences each. Place each paragraph between one or two of the actual lines of code. Try color coding the comment paragraphs differently from the code. Try recompiling the actual compiler so that the code must have a special character or pair instead of the comments. A double quote char for the actual code is good because it makes the code look like actual dialog.
Our coding style comes from the long-ago days fifty years ago when memory was extremely expensive and programming talent was relatively cheap. The opposite is true today. The great thing about speech-to-text is that it allows people who hate to type but love to talk to be able to create extensive and valuable documentation. Remember that it is easy for your 'reader' (that is, the next person who will be studying your code in order to modify or improve it) to read quickly or skip over the paragraphs of comments that are overly long. It's much easier to skip over excessive verbage than it is to try to understand what the previous coder was actually trying to do with dense code.
The more advanced and powerful the computer, the easier it should be to write programs for it. The computer should be doing the work, not the programmer.
C language is junk and obsolete. We only use it because we spent so much time learning it. We invest billions of dollars making an ARM microprocessor that runs at 80 MegaHertz, has 128K of Flash memory, and costs only $5. But we won't invest billions of dollars to make a simple programming language. So we're stuck with C. It's a trade off. Luckily for our grandchildren, they won't have to bother with it. Just like our children will never have to deal with typewriters or Morse code.
White space sucks. It's source code, not avant-garde poetry. It should read like a book. In the future, writing code by itself should seem as strange as adding long columns of numbers seems today. But 100 years ago, people made good money doing it. Probably better money than you make now writing code.
Thank you.
I'm proud of some of the code that I've written because it's modular and reusable, does something cool, or successfully implements a cool idea that I came up with. But sometimes I'm proud when I manage to write anything that doesn't crash immediately. At my work I mostly code alone, and there aren't any organization-wide best practices policies. Since it's a research institution, satisfying all the customers 100% isn't that vital to the bottom line.
I almost always have a good laugh after when I look at the code that I wrote some time ago. Which I guess is a good sign; it means that I've improved in the meantime. On the other hand, I've been in the happy situation to see most of my code go into use; some of it is still being used 8 years later.
Learning different languages seems to help me write better code in any given language. It's something I do as a hobby (this has the (un?)fortunate side effect of making me less and less fond of PHP, the language I use most at work).
At work we've recently switched to agile project managment (scrum), and now the first big (7 month) project using scrum is done. I have the feeling that the process really helped. We did change course a couple of times, and some pieces ended up being done with other applications than those originally planned. We demonstrated what we had working to the customer at the end of every three week period, and discussed what was most important to do in the upcoming three weeks. Because of this tight feedback cycle, we didn't go (too far) out on wild goose chases. And the customer was extremely happy because he knew what was going on. And because he knew what was going on, he understood when we said that implementing such-and-such feature or making such-and-such change is of course possible, but not without cutting some other feature or increasing the budget.
It's a bit of a change for the customer, and they will spend more of their time on the project than with a project using traditional project management, but the end result is better (from my experience and from what I've heard).
Am I proud of my code? Not necessarily. I can't tell you exactly what my baby is, but suffice to say it's the core scanning/routing logic of a Fortune 500 global transportation company. Part of it's an ugly piece of crap - well, actually a lot of it is. But it works and works reliably and is maintainable, as evidenced by the fact there have been two maintainers before me and two since.
What I am proud of is the architecture (compression algorithms, general data table design, etc.), as well as parts of the codebase, are approaching twenty years old and are still running in nearly 700,000 devices and performing some 120 million barcode scans each and every day. In that fifteen years, we've had only two days of total global outage, despite the fact we update and augment the data file monthly and there are dozens of legacy versions of the code running in production, with untold numbers of bug landmines just waiting to be stepped on by new data. I'm proud of what it enables my company to do, not of the code itself.