Klass och metoddesign Hur kan man jobba med kodkvalité? 1. Jobba strukturerat genom hela processen 170 171 Skapa en OO-design Bestäm klasser, objekt och metoder som behövs Vad finns redan? Bestäm algoritmer för problemlösningen I princip oberoende av programmeringsspråk Diagram Pseudokod Designa för återanvändning? Det är svårare att göra generella lösningar Kan löna sig i framtiden Återanvändning har varit en stor anledning till OOboomen 172 Implementation När man kommer till detta steg så har man ritning klar, det mesta av materialvalen är gjorda Översättning av design till källkod Implementationen fokuserar på kod-detaljer Alla viktiga beslut tas vid analys och design 173 Kodkonvention Klasser påbörjas med stor bokstav (i övrigt små utom om flera ord då Inledande bokstav i övriga ord också görs stor) AClass Metoder/attribut inleds med liten bokstav (i övrigt små utom om flera ord då inledande bokstav i övriga ord också görs stor) amethod(), avariable Konstanter Bara stora bokstäver. Ord åtskiljs med _ PI Följer man dessa konventioner så kommer ens egna klasser att se ut som javas inbyggda. 174 Bra klasser är grunden Bra namn som säger vad den gör eller är till för Hanterar undantag och fel på ett bra sätt Väldokumenterad Vad den gör Hur dess relation är till andra klasser Publika metoder är dokumenterad Minimera möjligheten att ändra tillstånden använd setter och getters för att jobba med tillståndsförändring tänk efter om det behövs setters, eller fungerar det utan Undvik statiska attribut och metoder i så stor utsträckning det bara går 175
Bra klasser är grunden Några olika typer av klasser Typer av klasser Actor-classes Utility-classes Oförändliga klasser, dvs man kan bara skapa objekt med värden och man har inga setters för att ändra tillståndet -String är en sådan klass Inte för stora ansvar för en klass -> avspeglar sig i det publika interfacet Synligheten ligger på rätt nivå Minska beroendet till andra klasser Tex. undvik att lägga in metoder för utskrift i klasser försök att lägga dom så högt upp i klasshierarkin som det bara går helst i main-klassen. System.out.println finns inte i alla miljöer 176 Actor-classes Gör saker med objekten, ändrar tillstånd, har ett beteende, mm Utility-classes Ofta statiska klasser som inte jobbar med att förändra objekts tillstånd, typ Math-klassen Oföränderliga klasser Klasser med ett fast tillstånd Man kan bara skapa objekt med värden och man har inga setters för att ändra tillståndet - String är en sådan klass 177 Vad kännetecknar en god klass Med andra ord En odelad, väldefinierad abstraktion Coupling Uppgiften kan beskrivas kort och tydlig Namnet är en substantiv eller adjektiv som beskriver abstraktionen på ett adekvat sätt Har ett koncist och sammanhängande gränssnitt Cohesion Har tillstånd och beteende 178 Coupling Klasserna ska vara så oberoende som möjligt av varandra Löst kopplade Coupling mäter hur starkt klasserna är kopplade Ju lösare klasserna är kopplade, desto enklare är det att förstå en enstaka klass enklare och förståeligare blir systemet som helhet Klasserna med lös koppling kan lättare ändras utan att andra klasser påverkas Systemet blir lättare att ändra Dvs, Mera flexibilitet 179 UML: Klassrelationer Klassdiagram svag koppling stark koppling 180 Johan Eliasson
Kategorier av metoder Konstruktorer Skapa instanser Selektor (get-metod) Returnerar information om objektets tillstånd Mutator (set-metod) Ändra objektets tillstånd Annat Gör någonting En metod ska tillhöra bara en kategori 182 Metoddesign Konsistens när det gäller parametrar och namn Följ en kodkonversion Undvik sidoeffekter i metoder om det går, beräknar och returnera ett värde Undvik att förändra objekten som parametrarna refererar till, returnera ett nytt objekt om det är görbart Ibland använder man returvärdet för att säga något om beräkningen hur den gick, trots att metoden inte returnerar något riktigt värda Exceptions så långt det går vi undantag att jobba med för att tala om att det har skett något som anroparen behöver veta för att hantera ev. konstigheter 183 package callbyvalue; Metoddesign Java jobbar med Call-By-Value på attributen, dvs värdet från anropssidan kopieras till attributen i metoden Undvik att förändra värdet på de anropade attributen, speciellt när de är av referenstyp. Vad händer på anropssidan om du ändrar på parametern/ attributet inne i en metod använd final i attribut-listan för att göra det omöjligt att ändra attributen inne i metoden Java kan inte förändra innehållet i variabeln som används för anropet Java förändrar objektet som variabeln refererar till inne i en metod 184 import figures.triangle; public class CallByValue { public static void main(string args[]){ int a = 42; System.out.println("a before somemethod(a): " + a); // a is copied and the copy is passed into the method somemethod(a); System.out.println("a after somemethod(a): " + a); Triangle triangle = new Triangle(); System.out.println("triangle before trianglemethod(triangle): " + triangle); // triangle ref is copied and the copy is passed into the method trianglemethod(triangle); System.out.println("triangle after trianglemethod(triangle): " + triangle); public static void somemethod(int a){ a = 23; System.out.println("a within somemethod(a) after changing it: " + a); public static void trianglemethod(triangle triangle){ triangle.changesize(10, 400); System.out.println("triangle within trianglemethod(triangle) after changing it: " + triangle); triangle = new Triangle(); System.out.println("a within trianglemethod(triangle) after created a new triagle: " + triangle); 185 Cohesion Varje metod ska vara ansvarig för bara en uppgift Cohesion mäter huruvida en metod uppfyller detta krav Ju mer en metod fokuserar på en enda uppgift, desto enklare är det att finna ett bra namn enklare och förståeligare blir koden Metoder med stark samhörighet kan lättare ändras utan att andra metoder påverkas Det ska vara möjligt att beskriva en metod med en enkel mening med ett verb och ett objekt 186 Exempel 1: Cohesion: Exempel 1 public void setnameandage (String name, int age); Bättre: public void setname (String name); public void setage (int age); Exempel 2: /* Anropas en gång om året */ public void calculateholidays(); { holidays += new Holidays(); age++; Bättre: public void calculateholidays(); public void incrementage(); 187
Exempel 3: Cohesion: Exempel 2 public void setfirstname (String name){ firstname = name; public void setlastname (String name){ lastname = name; fullname = firstname + + lastname; Filer och IO Bättre: public void setfirstname (String name) { firstname = name; fullname = firstname + + lastname; public void setlastname (String name){ lastname = name; fullname = firstname + + lastname; 188 189 Input/ output Utströmmar från programmet Inströmmar till programmet 190 Input/output Externa data kan tillhandahållas på många sätt i Java : Via GUI Läsas och skrivas direkt till och från tangentbord och bildskärm Läsas och skrivas till och från filer Läsas och skrivas till och från databaser Java API tillhandahåller paketet java.io Klasser som stöder input/output Klasser för att hantera när I/O-operationer går fel Typfel En fil som inte går att hitta/öppna 191 Filer Filer kan användas för att lagra data permanent mellan programkörningar eller för utbyte an information mellan program. Textfiler läsbara även för oss (med tex en texteditor) till skillnad från binära filer som lagrar datat mer som i datorns minne. Skriva och läsa textfiler Strömmarna betraktas som innehållande värden av typen char Klasser som hanterar textfiler kallas readers och writers Tre viktiga åtgärder Öppna filen Skriv/läs data Stäng filen Samtliga dessa kan misslyckas Man måste förutse undantag! 192 193
Öppna/Skriva/Stänga Skapa ett FileWriter objekt En konstruktor tar filnamnet som parameter (String) FileWriter writer = new FileWriter( testfil.txt ); Skriv med metoden write() Överlagrad, tex. med signaturen write(string str) writer.write("första raden\n"); Stäng filen med metoden close() writer.close(); //(Obs stäng ej System.in) 194 Läsa från filer Scanner har en konstruktor som tar ett Fileobjekt som parameter Alternativt kan man koppla ihop den med En Reader klass File f=new File( minfil.txt ); Scanner in=new Scanner(f); //Kastar ett kontrollerat undantag Scanner in2=new Scanner(new FileReader( minfil.txt )); String str=in2.next(); in2.close(); 195 import java.io.fileinputstream; import java.io.fileoutputstream; import java.io.ioexception; Exempel public class CopyBytes { public static void main(string[] args) throws IOException { FileInputStream in = null; FileOutputStream out = null; try { in = new FileInputStream("xanadu.txt"); out = new FileOutputStream("outagain.txt"); int c; while ((c = in.read())!= -1) { out.write(c); finally { if (in!= null) { in.close(); if (out!= null) { out.close(); Input/ output Java I/O baseras på streams (strömmar) En ström är en sekvens av bytes som flödar från en källa till ett mål Fördefinierade standardströmmar: ström System.in System.out syfte läsa input skriva output enhet tangentbord bildskärm System.err skriva fel bildskärm Standard strömmarna kan läggas om med System.setIn/Out/Err metoderna datatyp InputStream PrintStream PrintStream 196 197 InputStream Inputströmmar är mera komplicerade InputStream är en abstrakt klass InputStream har väldigt begränsad mängd metoder för att hantera inläsning System.in måste därför ofta kapslas in i en mer specifik ström med de egenskaper man vill ha Läsa in strängar Läsa in heltal Läsa in Vi kommer titta på några olika klasser vi kan använda till detta tex Scanner 198 Scanner Osmidigt att läsa in en hel rad som sträng! Bättre med ett ord i taget. Vad är ett ord? Tecknen måste grupperas till s.k. Tokens Tidigare mycket eget jobb Sedan Java 1.5 (5.0) finns klassen Scanner... Man kopplar en scanner till en ström Scanner myscan = new Scanner(System.in); Finns metoder för att läsa in heltal, flyttal, ord, rader etc. Se metoder i API:n https://docs.oracle.com/javase/7/docs/api/java/util/ Scanner.html 199
Koppla ihop strömmar För mer avancerat beteende kan de enkla strömmarna som läser/skriver från någon kopplas ihop med mer avancerade strömmar. Ex: PrintWriter out=new PrintWriter(new FileWriter( filnamn.txt )); out.println( hej ); out.close(); Strömmar finns tex för buffring, hantera radnummer, komprimering och kryptering https://docs.oracle.com/javase/7/docs/api/java/io/ PrintWriter.html 200 Exempel import java.io.filereader; import java.io.bufferedreader; import java.io.ioexception; import java.util.scanner; import java.util.locale; public class ScanSum { public static void main(string[] args) throws IOException { Scanner s = null; double sum = 0; try { s = new Scanner(new BufferedReader(new FileReader("usnumbers.txt"))); s.uselocale(locale.us); while (s.hasnext()) { if (s.hasnextdouble()) { sum += s.nextdouble(); else { s.next(); finally { s.close(); System.out.println(sum); 201 Input Output Data I/O Processing Character Byte Byte handle I/O of raw binary data. Character handle I/O of character data, automatically handling translation to and from the local character set. Buffered optimize input and output by reducing the number of calls to the native API. Scanning and Formatting allows a program to read and write formatted text. I/O from the Command Line describes the Standard and the Console object. Data handle binary I/O of primitive data type and String values. Object handle binary I/O of objects. 202