38

Are there any techniques in programming that you find to be overused (I.E. used way more excessively than what they should be) or abused, or used a bit for everything, while not being a really good solution to many of the problems which people attempt to solve with it.

It could be regular expressions, some kind of design pattern or maybe an algorithm, or something completely different. Maybe you think people abuse multiple inheritance etc.

6
  • 33
    I agree that IE is used way more excessively than it should be, but that is primarily by non-programmers . . . Commented Jan 11, 2011 at 21:09
  • 7
    @FarmBoy - I think he meant I.E. : "I.e." stands simply for "that is," which written out fully in Latin is 'id est'.
    – Raphael
    Commented Jan 11, 2011 at 21:29
  • Fixed it now :)
    – Anto
    Commented Jan 11, 2011 at 21:32
  • 4
    Any technique can (and often is abused), it just has to be presented as the next silver bullet and you'll find someone who treats every problem as a nail (to mix metaphors).
    – ChrisF
    Commented Jan 11, 2011 at 21:46
  • 8
    @Rapheal - I was joking, of course. Thanks for the education. Commented Jan 12, 2011 at 2:04

19 Answers 19

72

Comments in Code

I just wish the University Professors would understand they don't need to teach their students to write 10 lines of comments saying the following code is a for loop, iterating from 1 to number of x. I can see that in the code!

Teach them to write self-documenting code first then appropriate commenting on what cannot be adequately self-documenting second. The software world would be a better place.

22
  • 26
    Self-documenting code isn't . Also professors do this to teach students to conceptualize the problem and how to approach it. Additionally I have never seen anyone complain about too much documentation. Caveat being the documentation is correct.
    – Woot4Moo
    Commented Jan 11, 2011 at 21:04
  • 24
    @Woot4Moo: if you read Clean Code, Fowler clearly states that out-of-date documentation is worse than no documentation, and that all comments have a tendency to become stale and to migrate away from the code they document. That whole book is all about how to write self-documenting code. Commented Jan 11, 2011 at 21:35
  • 12
    Teaching them to replace comments with code would be a good start...
    – Shog9
    Commented Jan 11, 2011 at 21:37
  • 15
    +1. I've actually seen the following in real world code: "loopVar++; // increment loopVar". AAAAAAAAAAAAARRRRRGH! Commented Jan 11, 2011 at 21:38
  • 7
    @Bill: My take on it is that you shouldn't need to document generic logic and control structures, even if they are relatively complex. Basically, anything that a good developer who knows the language should be able to work out by analysing the code shouldn't need to be commented. eg. A set of nested for loops with some breaks inside them, etc. But what SHOULD be commented is the application-specific reasoning of why the code makes those decisions: eg. "If a new programmer starts at the company tomorrow and looks at the code, will what it does make sense without the comment hints?" Commented Jan 11, 2011 at 21:56
56

The singleton design pattern.

Sure, it's a useful pattern but every time a new programmer learns about this pattern he starts trying to apply it on every single class he creates.

10
  • I use this poorly designed excuse for a framework every day. codeigniter.com/user_guide/libraries/email.html They think OOP is prefixing functions with $this->. PHP is a rotten language so I can't expect the frameworks to be excellent.
    – Benbob
    Commented Jan 11, 2011 at 23:14
  • 7
    I think any programmer who implements a singleton and does not repent will burn in a fiery hell for the sin(s) he (or she) has committed.
    – user2528
    Commented Jan 12, 2011 at 6:27
  • 2
    I implemented a singleton once in my professional career (in a multitasking context) and I had to repent for my sin by rewriting it.
    – Spoike
    Commented Jan 12, 2011 at 9:31
  • 3
    Singletons can be useful for a few things, but are almost always used when they shouldn't be. That doesn't mean singletons should never be used - just because something is abused doesn't mean it can't be used correctly. Commented Aug 31, 2011 at 16:21
  • 2
    @Rapahel: That's exactly why I don't believe studying design patterns is a good thing. Commented Sep 1, 2011 at 12:58
53

The most evil thing to protect dumb programming. putting everything in a try catch and doing nothing with the catch

        try
        {
            int total = 1;
            int avg = 0;
            var answer = total/avg;
        }
        catch (Exception)
        {

        }

I shudder when I see a try catch that does nothing and is designed to handle dumb logic. In general try catches are over used, however in some cases are very useful.

15
  • 4
    Funny thing - I've just been editing a file that does that hundreds of times, and with good reason. It's a unit test file, testing that various methods throw an exception when expected. The try block contains a call and an "expected throw didn't happen" report. The exception is expected and correct, so there is no corrective action. Obviously unit tests are a special case, but I have had similar cases in real code. Red flag, yes, but not an absolute rule.
    – user8709
    Commented Jan 12, 2011 at 2:44
  • 5
    @Steve the case you described is an rare edge condition. Another one I can think of is logging code -- if logging itself fails, there's no point trying to log the exception, or interrupting the app.
    – dbkk
    Commented Jan 12, 2011 at 6:19
  • 1
    @dbkk - agreed on the edge condition, and I'd add that when you genuinely need to catch an exception but don't need a corrective action, adding a comment in the catch block to explain that is essential if only to calm down the maintainers. It's not so rare in unit tests, so I'd drop the comment thing in that case.
    – user8709
    Commented Jan 12, 2011 at 11:51
  • 5
    on error resume next
    – jk.
    Commented Jan 12, 2011 at 13:26
  • 2
    @jk01 - an exception isn't (necessarily) an error. Whether any condition is an error or not depends on context. For example, "file not found" isn't an error if you don't need the file. Perhaps it's just an optional settings file that may or may not be present, and you can just leave your defaults in place if the file isn't there (so no corrective action is needed after the catch).
    – user8709
    Commented Jan 16, 2011 at 19:16
47

Reliance on StackOverflow to solve your problems instead of figuring it out the hard way.

New programmers that find the wealth of knowledge on SO (too often) post before thinking and trying stuff out.

In my day we had to code from books, no internet, no SO. Now get off my lawn.

13
  • 29
    I must admit, I do flinch at the audacity of some questions on SO. Either because they are asked many times every day and they have obviously not searched at all; or worse still, they treat the community as a free outsourcing service.
    – Orbling
    Commented Jan 12, 2011 at 3:27
  • 2
    @dbkk: stackoverflow.com/questions/4665778/… --> first comment "did you ever try this ?" Commented Jan 12, 2011 at 7:44
  • 5
    I started learning from books but once I had a fundament I learned almost everything else from online forum discussions. Not by asking, but mainly (and at first, exclusively) by reading. This method has taught me several programming languages in excruciating depth (with lots of nooks and crannies), and I think it’s not a bad method at all. Commented Jan 12, 2011 at 8:54
  • 1
    @Konrad Rudolph: That method is good and wise, reading questions, searching well. The asking is best done when the asker has a framework with which to understand the answers. Too often people ask questions which they do not (yet) have the capacity to understand.
    – Orbling
    Commented Jan 12, 2011 at 12:41
  • 3
    the problem is that SO encourage this by giving a lot of rep for asking/answering very easy question that can be answered with simple google search. very hard question people answer only because they really want to.
    – IAdapter
    Commented Jan 14, 2011 at 10:37
36

OOP evidently. It is very valuable, but when misused it can obscure otherwise clear code pretty easily (some examples of S4 programming in R come to mind), and can give a tremendous overhead that is unnecessary and can cost you big time on performance.

Another thing is that (in eg Perl) OOP often comes down to writing the same thing the other way around : result = $object ->function(pars) instead of result = function(object, pars) This sometimes makes sense, but when mixed with procedural programming it can make reading the code pretty confusing. And apart from that, you just introduce more overhead where it doesn't improve the design. It comes down to what is said about the singleton pattern as well: Should be used, but not on everything.

I do use OOP myself, but in my field (scientific computing) performance is a big deal, and OOP is often abused there as all students get Java nowadays. It's great for dealing with larger problems, for conceptualizing and so on. But if you work with eg DNA sequences in BioPerl, using the objects every time and working consistently with getters and setters can increase the calculation time a tenfold. When your code is running a few days instead of a few hours, that difference really matters.

20
  • 6
    @Craige : I do use OOP myself, but in my field (scientific computing) performance is a big deal, and OOP is often abused there as all students get Java nowadays. It's great for dealing with larger problems, for conceptualizing and so on. But if you work with eg DNA sequences in BioPerl, using the objects every time and working consistently with getters and setters can increase the calculation time a tenfold. When your code is running a few days instead of a few hours, that difference really matters.
    – Joris Meys
    Commented Jan 11, 2011 at 21:35
  • 1
    @Craige: Method chaining (like Foo.DoX().DoY().DoZ()) is nice, but, but it's definitely not the only way to go about something. Function composition (like doZ . doY . doX $ foo is a perfectly valid alternative.
    – Anon.
    Commented Jan 11, 2011 at 21:39
  • 1
    @Joris: something I have wondered about for a long time (myself a bioinformatician): if performance matters that much, why use Perl in the first place instead of C++? If you’re worried about shaving off a factor 10 from the runtime (valid concern!) then switching to C++ gives you instant gratification. Of course, the language sucks … but then, so does Perl … and there are good bioinformatics libraries for C++. Commented Jan 12, 2011 at 8:48
  • 1
    @Konrad : It depends. BioPerl has arguably the most packages for bioinformaticians from all languages (I reckon Python is catching up though). Plus, a lot of work has been done in Perl and adapting a script is more easy than rewriting everything in C++ . Lastly, it doesn't serve to write a complete application when a script will do. Guess that's why Perl is still around that much. And honestly, I don't mind, I like the language. It's still the best I know for string and file work. The calculations are obviously done in other languages and linked back (which goes pretty easy).
    – Joris Meys
    Commented Jan 12, 2011 at 10:10
  • 1
    @Konrad : it depends on how one does it. It is possible to do all in Perl, but Perl can be easily linked to other tools, especially on Linux. I use Perl often as an advanced bash-script with strong string-manipulation and easy construction of datasets to be dropped into other applications.
    – Joris Meys
    Commented Jan 12, 2011 at 11:38
27

Having spent several years in ASP.NET Webforms, i'd have to say unequivocally:

The Smart UI

While it's entirely possible to create layered, testable applications in webforms, Visual Studio makes it too easy for developers to one-click their way to forms tightly bound to their data-source, with application logic littered around all the UI code.

Steve Sanderson explains this anti-pattern much better than I could in his Pro ASP.NET MVC book:

To build a Smart UI application, a developer first constructs a UI,usually by dragging a series of UI widgets onto a canvas, and then fills in event handler code for each possible button click or other UI event. All application logic resides in these event handlers: logic to accept and validate user input, to perform data access and storage, and to provide feedback by updating the UI. The whole application consists of these event handlers. Essentially, this is what tends to come out by default when you put a novice in front of Visual Studio. In this design, there’s no separation of concerns whatsoever. Everything is fused together, arranged only in terms of the different UI events that may occur. When logic or business rules need to be applied in more than one handler, the code is usually copied and pasted, or certain randomly chosen segments are factored out into static utility classes. For so many obvious reasons, this kind of design pattern is often called an anti-pattern.

4
  • 1
    A GUI is at least some sort of specification code must adhere to. I don't think the programmers he describes would do any better if presented with a blank text file instead.
    – user2582
    Commented Jan 12, 2011 at 13:41
  • 4
    @qpr, I don't know about that. If they had a blank text file they might not be able to do anything (which might just be a bonus). Commented Jan 12, 2011 at 14:05
  • One of the many benefits of using WPF is that implementing MVVM smashes this anti-pattern into smithereens. Commented Jan 12, 2011 at 18:55
  • 2
    A thousand times this. I even see experienced .NET developers relying on this "pattern" because it's easier than understanding or caring about Separation of Concerns. Even if they don't use the drag-and-drop wizards, the most common "pattern" in .NET WebForms development is to do everything in code-behind events and copy/paste code as needed. Commented Aug 31, 2011 at 16:22
23

I see this occasionally and it usually results from not fully understanding boolean expressions.

if (someCondition == true)
13
  • 16
    It does have the advantage of making code more explicit
    – Pemdas
    Commented Jan 11, 2011 at 21:03
  • 7
    I think a look at this question is in order: programmers.stackexchange.com/questions/12807/…
    – gablin
    Commented Jan 11, 2011 at 21:17
  • 5
    I don't do that but, seriously, get over it. There's a hell of a lot worse out there. :) Commented Jan 11, 2011 at 22:56
  • 4
    If you named your variables properly, for example bool s beginning with is or has, you don't need to make your code more explicit with = true.
    – Nobody
    Commented Jan 12, 2011 at 10:52
  • 3
    @DisgruntledGoat because it shouldn't be in use at all
    – Corey
    Commented Jan 14, 2011 at 15:59
19

Reimplementing core (or otherwise provided) functionality, either because of ignorance of its existence or because of a perceived need for customizations.

4
  • 3
    Learning is an exception. When studying anything, it's often beneficial to "reinvent the wheel."
    – Maxpm
    Commented Jan 19, 2011 at 5:17
  • For sure - I should have specified that it's relevant only when creating production software.
    – l0b0
    Commented Jan 19, 2011 at 8:02
  • 1
    This is particularly bad when implementing anything related to security. Good security software prevents attacks that most people never even think of. Commented Jan 19, 2011 at 20:44
  • I see this way too common. We need X, let's write our own! But what about open-source package Y? No, we need custom software for our super-secret trade secrets that are the same as everyone else in our industry, we can't use common rubbish software! Commented Aug 31, 2011 at 20:08
18

Inheritance.

Don't enforce is-a where it doesn't make sense.

3
  • 6
    The problem is that intuitively “is-a” appears very often to make sense (in particular since every implementation/contract relationship can colloquially be expressed as “is-a”). It requires a solid understanding of OOP to realize that this is in fact a mistake, and that inheritance and interface implementation are fundamentally different. Commented Jan 12, 2011 at 8:56
  • @Konrad - agree absolutely. I try to encourage people to start with composition, move on to interfaces and consider inheritance last. (As a rule of thumb, of course). But maybe that's my VB background talking... ;-) Commented Jan 12, 2011 at 9:26
  • 1
    This is largely a language design question, though. The reason why you should "prefer composition over (implementation) inheritance" in languages like Java or C#, is because implementation inheritance sucks in those languages. Some people criticize Bertrand Meyer's Object-Oriented Software Construction for overuse of inheritance, but when you actually look at Eiffel (the language used in the book), you realize that it was designed for implementation inheritance, and thus it's actually okay to use inheritance over composition. In that case, at least. Commented Jan 16, 2011 at 8:08
14

Customizing off-the-shelf software.

While I can acknowledge this can be useful, I do wonder how much money is spent on getting little things done for questionable gains. This is where a company may spend hundreds of thousands if not millions of dollars on licenses for some software that then gets customized because it is so configurable, editable, and flexible that it really doesn't do much by default. In the end it is a custom application because of all the new code added what was initially bought.

1
  • Isn't this more likely to be the case with a custom application?
    – JeffO
    Commented Jan 11, 2011 at 22:02
13

Using the complier as a debugger.

Ignoring complier warnings or turning them off completely.

Global variables.

9
  • 18
    What's wrong with "using the compiler as a debugger"? Having a compiler that's able to point out errors in your code before they become an issue at runtime is a tremendous advantage. Commented Jan 11, 2011 at 21:00
  • 3
    I rely on the compiler catching my syntax errors and incorrect type-matching mistakes. For behavioural errors, I rely on test cases.
    – gablin
    Commented Jan 11, 2011 at 21:16
  • 5
    The problem is when you start to depend on the compiler to ensure program correctness. Did this compile? No, let me munge this little section and see if that fixed it. Did it compile? No, let me add a * here and there and see if compiles. ...ect. Obviously, it useful for correcting typos
    – Pemdas
    Commented Jan 11, 2011 at 21:23
  • 2
    You say that as if the coder is poking around blindly in the dark trying to do something--anything--to get the code to somehow compile. That's not how it works IME; the compiler gives you a useful error message and points you at the location of the error, and usually if something's not compiling it's new code that you wrote yourself, so you have a pretty good idea what's wrong and how to fix it once it's been pointed out. (Although if you're tossing random *s around, you might be working in C++, where compiler errors are known to be supremely unhelpful, so what I said may not apply.) Commented Jan 11, 2011 at 21:35
  • 3
    Relying on the compiler works very well, given a strong enough type system and a well-typed code base. Often, the type system can model important constraints that you’d otherwise have to write tests for (e.g. in weakly typed systems). So used judiciously, the compiler (and particularly its type checker) is a great asset for testing and debugging, and there’s nothing wrong with relying on it. In particular, it’s wrong to say that a compiler can only show syntax errors. Commented Jan 12, 2011 at 8:39
12

All Design Patterns.

They are like salt or sugar. Some of them on your food make it great, a lot of them, make your food sucks.

Don't get me wrong. Design Patterns are wonderful techniques. I used them a lot. But sometimes, I find programmers, (some of them my ex-bosses), who had these "you have to use a design pattern", even if doesn't match the problem !!!

One example is the "Visitor Pattern" who is more directed for "Lineal / Sequential Collections". I had to work with a tree data structure, once. In order to "visit" each item, I code a non design pattern method, and a former boss insist to use or adapt the "Visitor Pattern". Then, I browse the net, for a second opinion. Well, others programmers had the same situation, and the same solution. And call it the "Tree / Hierarchical Visitor Pattern"., as a NEW Design Pattern

I hope its added as a new pattern to the existing ones, in a new version of the "Design Patterns" book.

3
  • 3
    I never use design patterns, although they sometimes emerge naturally in my code. Commented Aug 31, 2011 at 16:31
  • How does the saying go? You start using patterns without knowing you're using them, then you learn about them and use them everywhere, then they become second nature so you starting using them without knowing you're using them? Commented Aug 31, 2011 at 20:18
  • 2
    @configurator When I read about the design patterns; I also discover that me and others developers where already using some of them ;-)
    – umlcat
    Commented Sep 1, 2011 at 15:14
9

Using exceptions as flow control. Sort of similar to this answer, but different.

Swallowing exceptions is bad form because it introduces mysterious, hard to find bugs in code. Using exceptions as flow control, on the other hand, is bad because it makes the code far more inefficient than it could be, and is conceptually sloppy.

Exception handling should only be used to handle truly exceptional (duh), unforeseen scenarios, not things like a user typing in an alphabetic character where a number is expected. This kind of exception abuse is extremely common among bad programmers in the Java world.

3
  • Exceptions making for inefficient code depends on your language - creating a stack frame etc etc. In Squeak, your stack's fully reified, so there's no difference between using exceptions or not. (In other words, exceptions are part of the library, not the language.) However, it is confusing working with exception-controlled control flow: lshift.net/blog/2011/01/04/try-again-with-exceptions shows a loop-using-exceptions that I recently found. Commented Jan 16, 2011 at 12:26
  • Regarding the last paragraph, again, it depends on your language. Exceptions ("conditions") in Common Lisp are a strict superset of most languages' ideas of exceptions. See examples here: gigamonkeys.com/book/… As with everything, you can go too far! Commented Jan 16, 2011 at 12:28
  • Readability and maintainability outweighs performance. The cases where I'll use exceptions for success (what I assume you mean by "flow control") are very rare, but they can give cleaner code in e.g. a complex recursive search. Broadly, I agree though. For example, I have containers with iterator methods that return false for going out of range (common at the end of an iteration), but throw an exception if the iterator is "null" (a probable sign of some kind of internal inconsistency)
    – user8709
    Commented Jan 26, 2011 at 15:50
8

I'm going to go with inflexibility through excessive data hiding.

We all know that abstraction and hiding the implementation are good, but more is not always better. Overdone, you can get an inflexible result that can't cope with changes in requirements. To handle the change, you not only have to modify the class that needs to handle that change, but you also have to create a way for the information it never needed before to be accessible despite layers of data hiding.

The trouble is, as with all finding-the-right-balance-for-every-context issues, it takes experience.

7

Exposing internal arrays

    public class Data {
    int[] x;

    public void setArray(int[] x) {

        this.x = x;
    }

    public int[] getArray() {

        return x;
    }
}

According to http://www.oracle.com/technetwork/java/seccodeguide-139067.html

copy mutable objects before returning, unless the intention is to share state.

6

Mutable state and loops. You almost never need them, and you almost always get better code without them.

For example, this is taken directly from a StackOverflow thread:

// ECMAScript
var thing, things_by_type = {};
for (var i = 0; i < things.length; i++) {
    thing = things[i];
    if(things_by_type[thing.type]) {
        things_by_type[thing.type].push(thing);
    } else {
        things_by_type[thing.type] = [thing];
    }
}

# Ruby
things_by_type = {}
things.each do |thing|
  (things_by_type[thing.type] ||= []) << thing
end

They are both doing the same thing. But I have no idea what they are doing. Fortunately, the question actually explains what they are doing, so I was able to rewrite them as follows:

// ECMAScript
things.reduce(function (acc, thing) {
    (acc[thing.type] || (acc[thing.type] = [])).push(thing);
    return acc;
}, {});

# Ruby
things.group_by(&:type)

// Scala
things groupBy(_.type)

// C#
from thing in things group thing by thing.Type // or
things.GroupBy(thing => thing.Type);

There's no loops, and no mutable state. Well, okay, no explicit loops and no loop counters.

The code has become much shorter, much simpler, much more like a description of what the code is supposed to do (especially in the Ruby case it pretty much directly says "group the things by type"), and much less error-prone. There's no danger of running off the end of the array, fencepost errors or off-by-one errors with the loop indices and termination conditions, because there are no loop indices and termination conditions.

3
  • I do believe that in the second line of your "fixed" ECMAScript should read (acc[thing.type] || (acc[thing.type] = [])), as opposed to ` = [thing], unless you want to add thing` to the list twice... Or am I missing something? Commented Jan 19, 2011 at 5:04
  • @Austin Hyde: You're right. Commented Jan 19, 2011 at 15:43
  • 1
    That ecmascript example is incomprehensible to many programmers. It relies on too many syntactic tricks. The loop has the advantage of obviousness for junior developers. Commented Aug 31, 2011 at 19:07
6

Mocking. It introduces too many artificial requirements for excessive decoupling into your code, leads to overengineered ravioli code and forces OO-style design down your throat when a more procedural or functional design might be a simpler solution to your problem.

2
  • Agreed in theory; mocks are useful but you don't have to have them. Commented Aug 31, 2011 at 20:22
  • The invasiveness of mocking depends on the language you use. In C#, it can be very invasive and adds rafts of unneeded interfaces. Commented Sep 4, 2014 at 15:12
3

Delphi programmers the world over have been finding out over the past two years how bad it is to use character arrays to store bytes due to the wholescale Unicode conversion

And, "soon" we'll learn how bad it is to store integers in lists when we want to make the change to 64-bits.

1
  • 2
    I think a huge fraction of the Unicode issues would have never come up if Borland had declared a DataString type that was basically the same as AnsiString but specifically for use with blobs, and then made sure people knew about it. Commented Jan 11, 2011 at 21:03
2

Properties. I know this is controversial, but I feel that properties are vastly overused in .net.

What's the difference between these two lines?

public string Property { get; set; }

public string Field;

TO the developer, the difference is: absolutely nothing. The compiled form is a tiny bit different, so if you are writing a library, and that library is going to be upgraded in programs, and you can't recompile the programs themselves (for example if you're writing an interface for plugins that should work across versions of your software), then you shouldn't use public fields because you can't replace them with properties. In any other case, there's absolutely no difference between using a field or an auto-property without modifiers.

3
  • 1
    Agreed; if you know 100% you will never need to do anything with getting/setting a "property" then there's no reason whatsoever to have a property. However, if there's a chance you will need to do something (logging that a value was changed, for instance) then you should use a property. Personally I don't see a big enough difference to not use the property, just in case you do need to modify it later (I know, I know YAGNI but I feel deviating in this case doesn't cost anything) Commented Aug 31, 2011 at 20:24
  • 2
    @Wayne: How is changing ; to { get { ... } set { ... } } any more work than changing { get; set; } to { get { ... } set { ... } }? Commented Sep 1, 2011 at 12:57
  • Now that I think of it, that's a fair point. Commented Sep 1, 2011 at 13:01

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