Præsentation er lastning. Vent venligst

Præsentation er lastning. Vent venligst

Blå gruppe: Søren, Alexander, Torben, Lasse. De 4 vigtige items: - Singelton - Override clone judiciously - Use interfaces only to define type - Prefer.

Lignende præsentationer


Præsentationer af emnet: "Blå gruppe: Søren, Alexander, Torben, Lasse. De 4 vigtige items: - Singelton - Override clone judiciously - Use interfaces only to define type - Prefer."— Præsentationens transcript:

1 Blå gruppe: Søren, Alexander, Torben, Lasse

2 De 4 vigtige items: - Singelton - Override clone judiciously - Use interfaces only to define type - Prefer annotations to naming patterns De 4 andre: - Favor generic method - Return empty arrays or collections, not null - Beware the performance of string concatenation - Avoid unnecessary use of checked exceptions

3 Af Lasse

4 Hovedpointen med en singleton er at den kun kan instantiseres EN gang i løbet af programmets køretid. Der er 3 måder at initialisere en singleton på De to første er baseret på en private konstruktor, hvilket medfører, at der kun kan lavet ET objekt i programmets køretid. Den tredje bruges der en ENUM i stedet.

5 Et public static final field holder referencen til objektet. public class Elvis { public static final Elvis INSTANCE = new Elvis(); private Elvis() {... } public void leaveTheBuilding() {... } } Dårlig version af singleton. AccessibleObject.setAccessible, gør det muligt at oprette flere instanser af objektet. Kan undgås ved at kaste exception, hvis der oprettes mere end 1 instans af objektet

6 Feltet laves private og man bruger en static getter til at hente referencen. public class Elvis { private static final Elvis INSTANCE = new Elvis(); private Elvis() {... } public static Elvis getInstance() { return INSTANCE;} public void leaveTheBuilding() {... } } Dårlig version af singleton. AccessibleObject.setAccessible, gør det muligt at oprette flere instanser af objektet. Kan undgås ved at kaste exception, hvis der oprettes mere end 1 instans af objektet

7 public static final field, har fordelen at det er nemmere at genkende at det er en singleton. Fordelen ved factory-metoden, er at den kan ændres fra en singleton til ikke at returnere et unikt objekt uden at ændre API'en. Men da det sjældent er nyttigt, er det ikke den store fordel.

8 Med et single-element enum kan der ikke findes andre instanser. Du kan endvidere ikke ændre eller skabe en ny instans: public enum Elvis { INSTANCE; public void leaveTheBuilding() {... } } Dette er derfor klart den fortrukne model at lave en singleton efter.

9 Af Alexander

10 x.clone() != x // En klon af et objekt er et andet objekt med en anden reference x.clone().getClass() == x.getClass() //Et klonet objekt er et objekt af samme klasse x.clone().equals(x) //Felter vil være de samme

11 Når man 'overrider' clone():  Man laver en klon af selve objektet  Man laver en ny klon af alle objekter objektet refererer til undtagen primitive typer og immutable objekter (f.eks. Strings)

12 public class MyClass implements Cloneable { private Objects[] elements; @Override public MyClass clone() { try { MyClass result = (MyClass) super.clone();//vi laver en klon result.elements = elements.clone(); //vi laver en return result; kopi af elementer } catch(CloneNotSupportedException e) { throw new AssertionError(); }}}

13 Et HashTable indeholder en hel masse objekter. Det giver derfor ikke rigtig mening at lave en klon af et HashTable objekt uden samtidig at lave en klon af de mange objekter i hver bucket. Ellers vil de hver bucket referere til de samme objekter.

14 Public class HashTable implements Cloneable { private Entry[] buckets = …; private static class Entry { final Object key; Object value; Entry next; Entry(Object key, Object value, Entry next) { this.key = key; this.value = value; this.next = next; } ….// Remainder omitted }

15 // metode kopiere hver single linked list Entry deepCopy() { return new Entry(key, value, next == null ? null : next.deepCopy()); } @Override public HashTable clone() { try { HashTable result = (HashTable) super.clone(); result.buckets = new Entry[buckets.length]; for (int i = 0; i < buckets.length; i++) if (buckets[i] != null) result.buckets[i] = buckets[i].deepCopy(); return result; } catch (CloneNotSupportedException e) { throw new AssertionError(); }}... // Remainder omitted

16 Det er en konvention for alle implementeringer af Collection og Map, at der er en copy konstruktur. En copy constructor kan tage et argument som er et interface implementeret af klassen selv. - Et Hashset s kan klones til et TreeSet: TreeSet( s ) - En ArrayList l kan klones til en List: List( l )

17 Af Torben

18 Hensigtsmæssigt: Interfaces fortæller noget om typen af klassen der implementerer interfacet, til f.eks. Polymorfisk anvendelse Uhensigtsmæssigt: De kan bruges til at indeholde konstanter man ønsker at bruge i flere klasser. Ingen funktionalitet Smitter ved ikke final klasser til subklasser. Forvirrer mere end det gavner.

19 Hensigtsmæssig løsning til konstanter: lav en klasse med statiske felter og metoder som så kan importeres. import FAAP.effectiveJava.ScrollBar; public class Test{ double beerPerMinut(int students) { return students*ScrollBar.theBeerConstant; }

20 //Brug static import for at kunne bruge konstanter uden klassens navn import staticFAAP.effectiveJava.ScrollBar.*; public class Test{ double beerPerMinut(int students) { return students*ScrollBar.theBeerConstant; } //Især brugbar hvis der skal bruges mange }//konstanter

21 Af Lasse

22 Ved at give metoder generics, sørger man får at der er typetjek hver gang de køres. Derved fjerner kompileren mængden af invalide input i metoden. Det er samtidig smart fordi du ikke behøver at specificere din generic: public static Set union(Set s1, Set s2) { Set result = new HashSet (s1); Reult.addAll(s2); Return result; Kompileren tjekker hvilken type argumenterne har, og sætter E til denne værdi.

23 Af Søren

24 Et navn man skriver foran en metode, f.eks. testGetNumber() Ulemper: Hvis man skriver forkert, f.eks. tsetGetNumber(), brokker compileren sig ikke. Man kan ikke skrive test foran en klasse og så regne med at JUnit kører alle metoder i klassen. Svært at tjekke hvilke parametre, der hører sammen med hvilke programelementer.

25 Når man bruger annotations, skal man først lave en den kan f.eks. se således ud: // Marker annotation type declaration import java.lang.annotation.*; /** * Indicates that the annotated method is a test *method. * Use only on parameterless static methods. */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Test { }

26 Derefter sætter man annotations på de metoder man vil have testet: // Program containing marker annotations public class Sample { @Test public static void m1() { } // Test should pass public static void m2() { } @Test public static void m3() { // Test Should fail throw new RuntimeException("Boom"); } public static void m4() {} @Test public void m5() {}//INVALID USE:nonstatic method public static void m6() {} @Test public static void m7() { // Test should fail throw new RuntimeException("Crash"); } public static void m8(){} }

27 Compileren brokker sig: stavefejl, annotationer placeret forkert. Annotationer har ikke indflydelse på programmets kørsel. Copy/paste fra bogen: There is simply no reason to use naming patterns now that we have annotations.

28 Af Torben

29 Det er meningsløst at returnere null i stedet for et tomt array. Giver ekstra kode. Gør det mere besværligt for programmøren. Fejl kan være skjult i flere år, da man sjældent har tomme arrays. Argumentet for at returnere null er, at det bruger mere plads, det er dog forkert i java, tomme arrays er nemlig immutable

30 //Den rigtige måde at returnere et array fra en collection private final List beersInStock =…; private static final Cheese[] EMPTY_BEER_ARRY = new Beer[0]; /** *@return et tomt array der indeholder alle beers i *butikken. */ public Beer[] getBeers() { return beersInStock.toArray(EMPTY_BEER_ARRAY); } toArray allokerer kun ny hukommelse hvis array’et er stort nok til at indeholde collectionen.

31 Af Torben

32 Strings er immutable => string concatenation har en running time på O(n^2)(string conatenation er + operationen mellem strings. Brug StringBuilder for at få en acceptabel running time: public String statement() { StringBuilder b = new StringBuilder(numItems()*LINE_WIDTH); for(int i = 0; i < numItems(); i++) b.append(lineForItem(i)); return b.toString } Append metoden’s running time er O(n).

33 Af Lasse

34 Checked exceptions er rigtig gode fordi de tvinger programmøren til at tage stilling til problemet. Dog er for mange en ulempe. Tommelfingerregler for brug af checked exceptions:  Hvis specifikke tilstand, der kaster exceptionen ikke kan forhindres.  Hvis programmøren kan gøre noget fornuftigt efter at have fanget exceptionen.


Download ppt "Blå gruppe: Søren, Alexander, Torben, Lasse. De 4 vigtige items: - Singelton - Override clone judiciously - Use interfaces only to define type - Prefer."

Lignende præsentationer


Annoncer fra Google