|
Nice, very nice... My apologies if this is the code that you are currently trying to deal with (and it does sound like that is the case).
As for me, I'm feeling kind of happy right now because I am in the midst of starting up a new project that will be all new development so I won't have to be dealing with this kind of nonsense. If I'm lucky, development will be controlled enough that none of this will crop in to the code base either (I'm probably not that lucky).
|
|
|
|
|
I think these came from using external consultants and no peer review to be honest. The only people evaluating anything the consultants did were non-techies so only new buttons in the UI, more pages, more lines of code, and ridiculously simplistic metrics like that were actually being observed. Hence we had effectively set up a system that was basically a trap, for ourselves! I want to point out I was not a part of this team at that time though...
|
|
|
|
|
dojohansen wrote: I want to point out I was not a part of this team at that time though...
That was also my excuse for the code I'd been involved in for the last two years.
It's still embarrassing when someone looks at the code for the first time, or notices the bugs in the code in runtime situations, and gives those not so nice glances in the direction of the current developers. It seems like the sins of those who originally wrote the stuff end up becoming the sins of those currently working in it - guilt by association.
|
|
|
|
|
Yes, the current developers always get the heat for things that may have been done years before they even started working at the company. Such is life
|
|
|
|
|
CIDev wrote: Yes, the current developers always get the heat for things that may have been done years before they even started working at the company. Such is life
Can anyone say "Refactoring"? I've spent a good deal of my career refactoring bad code, even when I had to do it on the sly to keep "if it ain't broke, don't fix it" bosses from burying me in manure. If it's bad code, it IS broken and needs to be fixed.
If your life sucks, you're working by the wrong set of rules.
|
|
|
|
|
I normally "tweak" or just plain replace old code that may work, but is really bad code. I don't always have enough time to replace as much bad code as I would like, but I do it whenever possible.
Bill W
|
|
|
|
|
CIDev wrote: I normally "tweak" or just plain replace old code that may work, but is really bad code. I don't always have enough time to replace as much bad code as I would like, but I do it whenever possible.
I know what you mean I'm in the process of finally, COMPLETELY refactoring an application created by an entry-level programmer in .NET 1.0. It's not terrible, considering her skill level and the state of Visual Studio.NET at that time, but it wasn't good. I'm guessing that the size of the code in both .aspx and .aspx.vb files has decreased by half. It only took me four years to get enough knowledge of .NET and ASP.NET, then to get permission to go for it
|
|
|
|
|
More lines of code is a bad thing in my mind. The fewer, the better if it's not sacrificing readability, performance, or functionality...which it rarely does.
|
|
|
|
|
That is just hideous
"The clue train passed his station without stopping." - John Simmons / outlaw programmer
"Real programmers just throw a bunch of 1s and 0s at the computer to see what sticks" - Pete O'Hanlon
"Not only do you continue to babble nonsense, you can't even correctly remember the nonsense you babbled just minutes ago." - Rob Graham
|
|
|
|
|
Yes.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
dojohansen wrote: the additional semi-colons
I used to do that with Pascal, so I could count them to know how many statements were in the program.
|
|
|
|
|
But here the semi-colon adds an empty statement!
This is a javascript function block with two statements:
function f()
{
a = 5;
++i;
}
The function itself is a declaration, not a statement, and adding a semicolon merely makes it a block with two statements followed by an empty statement.
Admittedly the difference between a declaration and a statement is a bit fuzzy in this case, since in js a function declaration is equivalent to an assignment statement, like this:
var f = function()
{
a = 5;
++i;
};
In which case it's correct to include the semicolon (because it ends a statement in this case).
Anyway, my real problem is the insane amount of reduncancy in the code. I declare war on copy-paste "programmers" the world over!
|
|
|
|
|
dojohansen wrote: I declare war on copy-paste "programmers" the world over!
To the death!!! ...alright, To the death or reform!! (I've been guilty of this occasionally as well, especially when I was in a screaming hurry...but it's VERY rare that I've left copy-and-paste stuff in my code longer than the first moment I could go back and revise it).
|
|
|
|
|
Whats wrong with the semi-colons; I put semi-colons everywhere; It is a C/C++ thing;
|
|
|
|
|
VentsyV wrote: Whats wrong with the semi-colons; I put semi-colons everywhere; It is a C/C++ thing;
Yeah semicolons are cool; aren't they;
Greetings - Gajatko;
Portable.NET is part of DotGNU; a project to build a complete Free Software replacement for .NET ; a system that truly belongs to the developers;
|
|
|
|
|
Perhaps it was more about all the try/catches with nothing really happening in the catch block.
"The clue train passed his station without stopping." - John Simmons / outlaw programmer
"Real programmers just throw a bunch of 1s and 0s at the computer to see what sticks" - Pete O'Hanlon
"Not only do you continue to babble nonsense, you can't even correctly remember the nonsense you babbled just minutes ago." - Rob Graham
|
|
|
|
|
He was trying to copy a subset of xml data from one document to another (how this can be useful beats me unless you unload the document containing the superset of data, but anyway that's what he tried to do) but the data would not have the same nodes in all cases. Apparently upon discovering this he figured he'd just wrap the code copying each node into a try-catch so it continues if a node doesn't exist.
This is a lazy approach and a coding horror in my book. First, the cost of catching exceptions instead of checking if nodes exist before trying to clone them is *huge*. Second, in most cases the try block can fail for other reasons than the one which "is ok" and means you should just go on. This project is plagued by that particular problem, people catch an exception because they want the program to "keep working" but of course all it does is make it fail in strange ways while leaving no useful debugging information. It's worse when they do this server-side since the client-side exceptions aren't so rich on information anyway but the principle is the same.
My real gripe however is the code redundancy. If you intend to perform the same operation 20 times over you should use the same implementation 20 times, so it's possible to change the darn thing without getting bored to death.
I also think that if the operation is of a fairly generic nature, say, copying a subset of xml nodes from one document to another, you should separate the logic from any particular bits of the systems such as, say, a specific web page in a complex application. The guy is now Chef de projet développements (not for my team thankfully) and continues to wreak havoc at undiminished speed.
An example of what he might have written instead:
function copyChildNodes(srcNode, destNode, nodeList, ignoreMissingNodes)
{
for (var i=0; i < nodeList.length; i++)
{
var node = srcNode.selectSingleNode(nodeList[i]);
if (!node)
{
if (ignoreMissingNodes)
continue;
else
throw {message: "No child node with name '" + nodeList[i] + "' exists in the source node."};
}
destNode.appendChild(node.cloneNode(true));
}
}
Put that in one of our several script files intended for code a little bit more general than the page-specfic stuff and put this in the page (instead of the twenty lines doing the same thing):
var nodes = ["block_name", "block_type", "title", "list_id", "you", "get", "the", "point"];
copyChildNodes(oXMLBlock, oXMLRecord, nodes, true);
Surely you can see how this second approach allows a long-term maintenance of the code that is completely incomparable to the copy-paste approach. I like to call it the "cut-and-paste" approach actually, because in practice it often starts with the realization that we're writing code in the wrong place, that a lot of what we're coding is not specific to the task and should be refactored to allow us to reuse it. This refactoring usually starts with cutting out part of the code and moving it somewhere else, then perhaps cleaning it up a bit or parameterizing some aspect of the behavior, such as "ignoreMissingNodes" in the above example. Reuse is extremely important, not just to save time (copy-paste achieves that, at first development, nearly as well), but to fix bugs and improve the QUALITY of the code base over time.
|
|
|
|
|
dojohansen wrote: My real gripe however is the code redundancy. If you intend to perform the same operation 20 times over you should use the same implementation 20 times, so it's possible to change the darn thing without getting bored to death.
What are you talking about, that just means you get to have fun writing an overly complex regex to update the code with.
Today's lesson is brought to you by the word "niggardly". Remember kids, don't attribute to racism what can be explained by Scandinavian language roots.
-- Robert Royall
|
|
|
|
|
Seen something very similar from a guy who sells the source code of his application for more than 2000 dollars. He said that using try catch blocks like it's going out of fashion is "covering every base".
...the horror.
|
|
|
|
|
Sadly, had a boss one time that changed my code from using an array and a loop_index to code that looks like the example. Perhaps we were being paid per line of source code generated?
|
|
|
|
|
Horror 1 :
if (strRet[0] == '0' && strRet[1] == '1' &&
strRet[2] == 'F' && strRet[3] == 'F' &&
strRet[4] == '2' && strRet[5] == '4')
A piece of code I just looked at had the preceding logic sprinkled through it around twenty times to examine the response from a piece of equipment with comparisons of varying lengths. Apparently this individual has never heard of strncmp or its TCHAR variant _tcsncmp.
Horror 2 :
They wrote their own function essentially equivalent to strtoul. I won't subject you all to it - you'll have to trust me when I say that it is a horror.
Horror 3 :
The function described in Horror 2 is called ConvertHEXASC(). Here's how it is used to convert the data from the equipment :
int iTmp = 0;
iTmp += ConvertHEXASC( strRet[7] ) * 1;
iTmp += ConvertHEXASC( strRet[6] ) * 16;
iTmp += ConvertHEXASC( strRet[5] ) * 256;
iTmp += ConvertHEXASC( strRet[4] ) * 4096;
Now imagine a similar sequence of code used a few dozen times with strings of varying lengths and positions.
Horror 4 :
There were sixteen buttons used to select a property for the equipment and, naturally, there were sixteen different functions made to handle the clicks of the buttons. ON_COMMAND_RANGE anyone ?
The word horror barely scratches the surface for these and the rest of the things I saw there.
It was staggering. Simply staggering.
|
|
|
|
|
What's the background of such champion-of-code-development?
Just curious.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
There were sixteen buttons used to select a property for the equipment and, naturally, there were sixteen different functions made to handle the clicks of the buttons. ON_COMMAND_RANGE anyone ?
And when you add another button, and the seventeenth ID is already used for something else, you have a whole heap of work to do.
|
|
|
|
|
Graham Bradshaw wrote: And when you add another button, and the seventeenth ID is already used for something else, you have a whole heap of work to do.
There's no problem pointing multiple ON_COMMAND_RANGE macros to the same function.
"Multithreading is just one damn thing after, before, or simultaneous with another." - Andrei Alexandrescu
|
|
|
|
|
I do not consider renumbering the values in Resource.h to be a whole heap of work. Besides, I always leave gaps around arrays of control identifiers just in case I have to add more so this is very rarely an issue for me and when it arises it is easy to deal with.
|
|
|
|