Genvejsmenu:
S - Indhold
1 - Forside
2 - Aktuelt
3 - Oversigt
4 - Søg

03.03.10   |   kl. 08:17   |   Aktuelt, Prosabladet

Christian Horsdals gode eksempel i Java

Koden nedenfor er fra "Principles, Patterns and Practices of Agile Software Development" af Robert C. Martin. Christian Horsdal, softwareudvikler og -arkitekt, Mjølner Informatics, synes, det er et godt eksempel på god kode, fordi:

  • Eneste kommentar er i toppen, hvor algoritmen beskrives helt kort
  • Eneste public metode er den første, man møder
  • Private metoder kommer i den rækkefølge, de bruges
  • Metoderne er korte
  • Metoder og variable har forklarende navne
  • Metoderne holder sig til ét abstraktionsniveau hver

PrimeGenerator.java (final)

/* This class Generates prime numbers up to a user specified maximum. The algorithm used is the Sieve of Eratosthenes. Given an array of integers starting at 2: Find the first uncrossed integer, and cross out all its multiples. Repeat until there are no more multiples in the array.*/


public class PrimeGenerator

{

  private static boolean[] crossedOut;
  private static int[] result;

  public static int[] generatePrimes(int maxValue)
  {

    if (maxValue < 2)
      return new int[0];
    else
    {

      uncrossIntegersUpTo(maxValue);
      crossOutMultiples();
      putUncrossedIntegersIntoResult();
      return result;
    }
  }

  private static void uncrossIntegersUpTo(int maxValue)

  {

    crossedOut = new boolean[maxValue + 1];

    for (int i = 2; i < crossedOut.length; i++)

      crossedOut[i] = false;

  }

  private static void crossOutMultiples()

  {

  int limit = determineIterationLimit();

  for (int i = 2; i <= limit; i++)

    if (notCrossed(i))

      crossOutMultiplesOf(i);

  }

  private static int determineIterationLimit()

  {

    // Every multiple in the array has a prime factor that is less than or equal to the sqrt of the array size, so we don't have to cross out multiples of numbers larger than that root. //

    double iterationLimit = Math.sqrt(crossedOut.length);

    return (int) iterationLimit;

  }

  private static void crossOutMultiplesOf(int i)

  {

    for (int multiple = 2*i;

         multiple < crossedOut.length;

         multiple += i)

      crossedOut[multiple] = true;

  }

  private static boolean notCrossed(int i)

  {

    return crossedOut[i] == false;

  }

  private static void putUncrossedIntegersIntoResult()

  {

    result = new int[numberOfUncrossedIntegers()];

    for (int j = 0, i = 2; i < crossedOut.length; i++)

      if (notCrossed(i))

        result[j++] = i;

  }

  private static int numberOfUncrossedIntegers()

  {

    int count = 0;

    for (int i = 2; i < crossedOut.length; i++)

      if (notCrossed(i))

        count++;

    return count;

  }

}

PRINT

Kommentarer

1

16.03.10   |   kl.17:00   |   Anders

Koden i eksemplet er da pæn, men er den solid? Dens brug af globale variabler (med lokalt scope) virker overflødig og ugennemtænkt:

- Det er ugennemsigtigt hvilke data hvilke funktioner afhænger af og hvilke data de producerer.

- Levetiden af de allokerede data er uklar. Sandsynligvis vil de blive liggende i hukommelsen længe efter at brugeren er holdt op med at interessere sig for sine primtal. Måske er det en tanketorsk, måske er forfatteren bare ligeglad.

- Generatoren kan producere forkerte resultater eller crashe, hvis den bruges i et multithreaded program.

God tone i debatten

Deltag i debatten

CAPTCHA billede for SPAM beskyttelse

Relevante links

 

Skrevet af:

Kommenter artiklen

 

Relaterede artikler