Cargo Cult Programming

Manche Entwickler halten Copy&Paste für das schlimmste Anti-Pattern in der Software Entwicklung. Leider muss man ihnen sagen, dass es noch schlimmer geht. Cargo Cult Programming ist die Verwendung von Pattern ohne sie zu verstehen. Dabei kopieren die Entwickler bestehenden Programmcode in der oft irrigen Annahme, dieser Programmcode wäre notwendig.

Der folgende Programmcode entstammt einer tatsächlichen existierenden Unit Test Klasse und wurde aus didaktischen Gründen ein wenig angepasst.

  protected void assertFolders(Path root, int expectedOrgs, int expectedSources) throws Exception {
    for (File file : root.toFile().listFiles()) {
      if (file.getName().startsWith("java")) {
        for (File file2 : file.listFiles()) {
          if (file2.getName().startsWith("src")) {
            int currentSources= 0; 
              for (File file3: file2.listFiles()) {
                currentSources++;
                if (file3.getName().equals("org")) {
                  Assert.assertEquals(expectedOrgs, file3.listFiles().length);
                }
              }
              Assert.assertEquals(expectedSrcs, currentSrcs);
            }
          }
        }
      }
    }
  }

Augenfällig ist insbesondere die tiefe Verschachtelung innerhalb dieser Methode. Hier wird innerhalb von Verzeichnissen nach einer speziell benannten Datei gesucht und das auf verschiedenen Ebenen. Woher auch immer das Grundmuster  stammt, hier wird es exzessiv durch Copy&Paste ausgelebt. Bevor wir aber etwas näher auf den Code und seine Schwachstellen eingehen, kommt hier erst einmal die korrigierte Version der Methode, an der man die gewollte Funktionalität ablesen kann.

  protected void assertFolders(Path root, int expectedOrgs, int expectedSources) throws IOException {
      Path src = root.resolve("java/src");
      Assert.assertEquals(expectedSources, src.toFile().listFiles().length);
      Path org = src.resolve("org");
      Assert.assertEquals(expectedOrgs, org.toFile().listFiles().length);
 }

In der ersten Zeile wird das Unterverzeichnis java/src bestimmt und dann die Anzahl der darin enthaltenen Dateien und Verzeichnisse geprüft. Danach wird sein Unterverzeichnis org bestimmt und die Anzahl der darin enthaltenen Dateien und Verzeichnisse geprüft. Es ist unschwer zu erkennen, dass diese Version kürzer und leichter zu lesen ist. Beide Methoden unterscheiden sich aber in einem sehr wichtigen Detail. Die korrigierte Version wirft einen Fehler, wenn kein Verzeichnis java/src existiert, während die ursprüngliche Version keinerlei Überprüfungen durchführt. Das in diesem Fall tatsächlich das Verhalten der korrigierten Methode erwünscht ist, basiert auf Insiderinformationen, kann aber im Allgemeinen mit Kaiser’s Razor abgeleitet werden.

Cargo Cult Programming äußert sich durch gedankenloses Verwenden von Vorgehensweisen, die nicht hinterfragt werden. Es werden keine APIs auf der Suche nach Alternativen durchsucht oder neue Ansätze erprobt. Durch das geringe Repertoire an Vorgehensweisen werden dann auch häufig schlechte und auch fehlerhafte Lösungen per Copy&Paste in den Code eingebaut. Gegen Cargo Cult Programming gibt es nur ein Heilmittel, das Gespräch unter Kollegen.