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.

Anto
  • 11,197

19 Answers19

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.

Dan McGrath
  • 11,181
  • 6
  • 57
  • 82
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.

Raphael
  • 2,234
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.

Nickz
  • 1,430
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.

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.

Joris Meys
  • 1,923
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.

richeym
  • 3,017
23

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

if (someCondition == true)
Corey
  • 1,822
19

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

l0b0
  • 11,547
18

Inheritance.

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

Kit
  • 193
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.

JB King
  • 16,775
13

Using the complier as a debugger.

Ignoring complier warnings or turning them off completely.

Global variables.

Pemdas
  • 5,395
  • 3
  • 23
  • 41
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.

umlcat
  • 2,206
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.

Bobby Tables
  • 20,616
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.

Vivart
  • 369
  • 1
  • 3
  • 10
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.

dsimcha
  • 17,284
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.

Jörg W Mittag
  • 104,619
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.

Peter Turner
  • 6,955
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.

configurator
  • 2,796