Granskningsprotokoll förklaringarUppfyller kraven i uppgiftenProgrammet måste uppfylla kraven i uppgiftslydelsen. Det är inte tillåtet att förenkla uppgiften. AnvändarvänlighetInformativa utskrifterProgrammet ska tala om för användaren vad programmet gör i varje steg och vilken inmatningen som förväntas. Ett dåligt exempel kan se ut så här. Ge tal1 : 26 och tal2 : 54 29 31 37 41 43 47 53 Man ska inte behöva titta i en manual, eller ännu värre själva programkoden, för att förstå vad som händer. Att köra programmet måste vara självinstruerande. Hej och välkommen till primtalsprogrammet. Programmet skriver ut alla primtal i ett intervall du definierar. Ange lägre gränsen i intervallet: 26 Ange högre gränsen i intervallet: 54 De primtal som finns mellan 26 och 54 är: 29 31 37 41 43 47 53 Det senare exemplet är mycket lättare att förstå när man kör programmet. Enkel inmatningAnmärk på programmet om inmatningen onödigt krånglig. ... Vill du boka en biljett? ja Varifrån åker du? Arlanda Vart ska du åka? Kastrup Vilken månad ska du åka? Mars Vilken dag ska du åka? 25 Vill du boka returbiljett? ja Vilken månad ska du tillbaka? April Vilken dag ska du tillbaka? 5 Det går tyvärr inget flyg den 25 mars. Försök igen Förutom att vara väldigt sen med att kläcka ur sig att det inte finns något flyg den önskade resdagen så verkar det inte finnas något sätt att boka en mängd biljetter. Att boka en klassresa med det systemet skulle vara väldigt frustrerande. ProgrammerarvänlighetVettiga namnProgrammet ska ha intuitiva namn på klasser, metoder och variabler. För den som skrivit programmet är allt ofta självklart, men inte för den som granskar. Nedanstående programkod är ganska svår att tyda int namn = 0; for (int kalle = 0; kalle < pelle.length; kalle++) { if (pelle[kalle] > namn) { namn = pelle[kalle]; } } Här följer samma kod med andra namn på identifierarna. int max = 0; for (int i = 0; i < vektor.length; i++) { if (vektor[i] > max) { max = vektor[i]; } } Man ser nu lättare vad koden gör. Fortfarande är det inte optimalt bra namn på vektorn. Vad för slags värden innehåller den? Är det löner, skottstatistik eller vad? Dessutom kan man i det här fallet göra koden tydligare med en "for each"-sats: for (int n: vektor) Bra namn på metoder är oftast verb som beskriver vad metoder gör. Klasser och variabler är ofta substantiv som beskriver vad klassen/variabeln är. Det krävs ofta mycket jobb för att komma på riktigt bra namn. KommentarerAlla klasser, instansvariabler och metoder måste kommenteras. Berätta syftet med klassen/instansvariabeln. Det ska räcka att läsa kommentar och metodhuvud för att förstå hur en metod ska användas; man ska alltså inte behöva titta i koden. In och utdata till metoder måste kommenteras. Det gäller både returvärden och parametrar. Kommentarer ska inte förklara hur Java fungerar. Förutsättningen är att den som läser källkoden redan vet hur man programmerar. Konsekvent språkVar konsekvent i ditt språkval: alla identifierare ska vara på ett språk, alla kommentarer på ett språk. Det är OK att ha engelska identifierare och kommentera på svenska. Undvik svengelska (sejva svenska språket). Konsekvent formatteringSkriv ihop ord genom att inleda med stor bokstav, därefter små. Variabel- och metodnamn inleds med med liten bokstav och klasser inleds med stor bokstav. class EnBraKlass class EnTillBraKlass void enMetodSomTarTreParametrar(int x, int y, int z) int ettHeltal FelhanteringDet krävs att programmet kan hantera fel som uppstår. Ibland kan man behövs en slinga, t.ex. vid inmatning för att programmet ska kunna gå vidare. Ange täljare: 1000 Ange nämnare: 0 Oj då, nämnare får inte vara noll. Försök igen. Ange nämnare: 10 1000 delat med 10 blir 100. StruktureringLämplig uppdelning i klasserUndvik att ha all kod i en enda klass. Försök ha en klass för varje sak i programmet. Lämplig uppdelning av metoderSträva efter att ha definiera metoder som bara gör en sak. int [] lasFranFil() throws IOException { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); System.out.print("Vad heter filen?"); String filnamn = in.readLine(); in = new BufferedReader(new FileReader(filnamn)); List list = new ArrayList(); String row = in.readLine(); while (row != null) { list.add(row); row = in.readLine(); } int [] vek = new int [list.size()]; for (int i = 0; i < list.size(); i++) { vek [i] = Integer.parseInt((String) list.get(i)); } return vek; } Koden ovan gör flera saker; frågar efter en fil, läser data från filen, gör om datat till heltal, stoppar in heltalen i en heltalsvektor och returnerar denna. Det är bättre att dela upp dessa uppgifter på flera metoder så att metodanropen blir: String filNamn = frågaFil(); String [] fildata = läsFrånFil(filnamn); int [] intressantaTal = konvertera(fildata);
Programmet blir mer flexibelt. Metoden Temporära variabler så lokalt som möjligt
Deklarera tillfälliga variabler så lokalt som möjligt. Det
är ett grovt fel att ha loop-variabler som instansvariabler.
I koden nedan antas List lasFranFil() throws IOException { in = new BufferedReader(new InputStreamReader(System.in)); System.out.print("Vad heter filen?"); String filnamn = in.readLine(); in = new BufferedReader(new FileReader(filnamn)); row = in.readLine(); while (row != null) { list.add(row); row = in.readLine(); } return list; }
Notera att metoden sätter om instansvariabel Återanvändbara metoder/klasserIbland kan man dela upp programmet i klasser som kan återanvändas i andra program. Specialicerade metoder kan man använda i andra sammanhang. Jämför med avsnittet om metoder ovan. In- och utdata till metoderVar noga med in och utdata till metoderna. En del metoder som t.ex. bara skriver ut på skärmen kan vara parameterlösa void-metoder. Övriga metoder har in- och utdata. Flexibelt/utbyggbart programSkriv ditt program så att det är lätt att modifiera och bygga ut. Ingen kodupprepningEtt vanligt nybörjarfel när man programmerar är att använda taktiken klippa och klistra. Det leder dock till kod som är väldigt svår att underhålla. Om man ändrar på ett ställe måste man göra samma ändring på flera parallellställen. Använd istället en metod som gör jobbet. Ingen hårdkodningUndvik att hårdkoda värden. Om du behöver använda siffervärden kan du deklarera dessa som konstanter. final static int ANTAL_SPELARE = 4; final static double E = 2.718281828; |