Metodik för problemlösning Kursbok: “Objects First with Java - A Practical Introduction using BlueJ”, David J. Barnes & Michael Kölling Fredric Ragnar Telefon Andreas Hedrén Telefon Föreläsning Mañana
2 Idag S.T.R.E.A.M. & ”The Manãna Principle” Idéer om utveckling från Kölling & Caspersen (OOPSLA’06 October 22–26, 2006, Portland, Oregon, USA. ACM X/06/0010)
Ett recept för systemutveckling - S.T.R.E.A.M. Stubs Tests Representation Evaluation Attributes Methods
Stubs - Skelettkod Börja med att skapa skeletten för klasserna. Detta steg har föregåtts av analys och design. Fyll klassen med standard-konstruktor Lägg in metod-signaturer, men ingen implementation
Tests – Tester Koda tester för att testa klasserna som har definierats i kodskelett
Representation Finns det alternativa lösningar för algoritmer Finns det alternativa sätt att visa datat
Evaluation Utvärdera de olika varianterna av lösningar och välj den som ger minst implementations-arbete eller komplexitet
Attributes Lägg till fält (medlemsvariabler) i klasserna
Methods Fyll kodskelettet med implementationer
Exempel – Klassen Date Specifikation: Interfacet DateInterface Tänk på interface som bilnyckel och ratt när man kör bil. Hur sedan motorn fungerar och förbränning av bensin är något dolt under motorhuven och själva implementationen. Vi kommer att prata mer om interface längre fram ;) Interface DateInterface { /** * Advance the date to the next day */ public void setToNextDate(); /** * Return a string representation of this date in * the format yyyy-mm-dd */ public String toString(); }
Stubs – Skelettkod till klassen Date public class Date1 implements DateInterface { /** * Advance the date to the next day */ public void setToNextDate() { } /** * Return a string representation of this date in * the format yyyy-mm-dd */ public String toString() { return ””; }
Tests – Testa den nya klassen... /** * Test method for se.hgo.oopmj2.Date1#setToNextDate()}. */ public void testSetToNextDate() { fail("Not yet implemented"); // TODO } /** * Test method for se.hgo.oopmj2.Date1#toString()}. */ public void testToString() { fail("Not yet implemented"); // TODO }...
Representation – Alternativa lösningar Datum kan uttryckas på olika sätt. R1: Uttrycka datum med tre heltal för dag, månad och år R2: Uttrycka datum med utgångspunkt från ett start-datum, exempelvis
Evaluation – Utvärdering av alternativa lösningar Utifrån de alternativa lösningarna görs en utvärdering hur mycket implementations-arbete de olika lösningarna medför Skala: ”Trivial” – ”Challenging” – ”Hard” IMPL. EFFORTR1R2 setToNextDate()ChallengingTrivial toString()TrivialHard
Attributes – Fält (Medlemsvariabler)... // Member variables private int mDay;// 1 <= day <= daysInMonth private int mMonth;// 1 <= month <= 12 private int mYear; // Constructor public Date1() { mDay = 1; mMonth = 1; mYear = 2001; }...
Methods – Implementera metoder Fylla klassen med beteende Nyttja ”The Mañana Principle”
”The Mañana Principle” ”When – during implementation of a method – you wish you had a certain support method, write your code as if you had it. Implement it later.” En variation av stegvis förbättring av kod. När man stöter på ett ställe i koden där man önskar man hade en metod – anropa den metoden. När man implementerat den aktuella metoden går man till Mañana-metoden och fortsätter med den. Fast man väntar inte till nästa dag ;)
När behöver man använda Mañana-principen? Specialfall: Om man behöver hantera ett specialfall i koden så hanteras detta i en separat metod Nästlade loopar: Om har man en nästlad loop så flyttar man ut den inre loopen i en separat metod Kod-duplicering: Om samma kod-segment dyker upp på flera ställen så läggs den i en separat metod Svårlöst problem: Om ett komplext problem dyker upp som behöver lösning, men som det inte finns en omedelbar lösning till flytta ut den i en separat metod Omständiga problem: Om en sats blir lång eller komplicerad så flyttas den in i en separat metod
Methods – Implementera metoder - Startpunkt... /* (non-Javadoc) se.hgo.oopmj2.DateInterface#setToNextDate() */ public void setToNextDate() { mDay = mDay + 1; } /** * Return a string representation of this date in * the format yyyy-mm-dd */ public String toString() { return mYear + "-" + mMonth + "-" + mDay; }...
Methods – Kontroll av antalet dagar /* (non-Javadoc) se.hgo.oopmj2.DateInterface#setToNextDate() */ public void setToNextDate() { mDay = mDay + 1; checkDayOverflow(); // Mañana }
Methods – Ny månad /** * Check for special case where day > daysInMonth; * in that case, set day to 1 and add 1 to the month */ private void checkDayOverflow() { if(mDay > 30) { mDay = 1; mMonth = mMonth + 1; }
Methods – Nytt år /** * Check for special case where day > daysInMonth; * in that case, set day to 1 and add 1 to the month */ private void checkDayOverflow() { if(mDay > 30) { mDay = 1; mMonth = mMonth + 1; checkMonthOverflow(); // Mañana }
Methods - Månadskontrollen /** * Check for special case where day > daysInMonth; * in that case, set day to 1 and add 1 to the month */ private void checkDayOverflow() { if(mDay > daysInMonth()) { mDay = 1; mMonth = mMonth + 1; checkMonthOverflow(); }
Methods – Dagar i månaden /** * Return the number of days in the current month */ private int daysInMonth() { int[] daysInMonth = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; int result = daysInMonth[mMonth -1]; return result; }
Methods - Skottår /** * Return the number of days in the current month */ private int daysInMonth() { int[] daysInMonth = {31, 28, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30}; int result = daysInMonth[mMonth -1]; // Special case: February in a leap year if( mMonth == 2 && isLeapYear()) { result = result + 1; } return result; }
Methods – De sista Mañana-metoderna /** * Return true if the current year is a leap year */ private boolean isLeapYear() { return (divides(4, mYear) && !divides(100, mYear)) || divides(400, mYear); } /** * Return true if a divides b */ private boolean divides(int a, int b) { return b % a == 0; }
Summering Det är viktigt att fundera över alternativa lösningar Testa funktionaliteten Identifiera svåra delar i koden och tänk att du har en metod som löser den Bryt ner stora problem i flera mindre delar