Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

ObservableListListener-grensesnittet er vist i klassediagrammet til venstre nedenfor og må implementers av alle klasser som ønsker å fungere som lyttere for ObservableHighscoreList-instanser. Lyttere registrerer seg med ObservableHighscoreList sin addObservableListListener-metode og vil siden få beskjed om nye resultater ved at listChanged-metoden kalles. Argumentene som tas inn er ObservableHighscoreList-objektet som ble endret og posisjonen i lista der endringen skjedde.

...

Klassediagram for HighscoreListListListener og ObservableList.:

PlantUML Macro
class ObservableList {
}

class ObservableHighscoreList {
	int maxSize
	Collection<Integer> results
	ObservableHighscoreList(int)
	int size()
	int getElement(int)
	void addResult(int)
	addObservableListListener(ListListener)
	removeObservableListListener(ListListener)
}

ObservableList <|-- ObservableHighscoreList

interface ObservableListListener {
	listChanged(ObservableList, int)
}
ObservableHighscoreList -right-> "*" ObservableListListener: observableListListeners


Testkode for denne oppgaven finner du her: patterns/observable/ObservableHighscoreListTest.java. Original-koden (jextest) finner du her: patterns/observable/ObservableHighscoreList.jextest.

Del 2: Hovedprogram ObservableHighscoreListProgram

...

ObservableHighscoreListProgram

Klassediagrammet viser hvordan klassene henger sammen, og vårt forslag til metoder.

Lag en hovedprogramklasse kalt ObservableHighscoreListProgram, som tester at ObservableHighscoreList-klassen din virker som den skal. La den opprette en ObservableHighscoreList-instans, lese inn tall fra konsollet (f.eks. med en Scanner og nextInt-metoden) og legge disse inn i lista. Sørg for at ObservableHighscoreListProgram implementerer ObservableListListener-grensesnittet og registrerer seg som lytter på HighscoreList-instansen. La lyttermetoden listChanged skrive ut informasjon og resultatene i HighscoreList-instansen og posisjonsargumentet, slik at du ser at alt virker som det skal.

Vi foreslår følgende metoder og oppførsel:

  • void init() - oppretter en ny ObservableHighscoreList og registrerer seg selv (altså ObservableHighscoreListProgram-instansen) som lytter
  • void run() - leser inn tall (resultater) fra konsollet og legger dem til i listen
  • void listChanged(ObservableList, int) - observerer endringer i ObservableHighscoreList-instansen og skriver ut posisjonsargumentet, samt selve listen, til konsollet

 

...

Klassediagrammet viser hvordan klassene henger sammen, og vårt forslag til metoder:

PlantUML Macro
class ObservableList {

...

}

class ObservableHighscoreList {
	int 

...

maxSize
	

...

Collection<Integer> results
	ObservableHighscoreList(int)
	

...

int size()
	

...

int

...

 

...

getElement(int)
	

...

void addResult(int)
	addObservableListListener(ObservableListListener)
	removeObservableListListener(ObservableListListener)
}

...

ObservableList <|-- ObservableHighscoreList

interface ObservableListListener {
	listChanged(ObservableList, int)
}

...

ObservableHighscoreList -right-> "*" ObservableListListener: observableListListeners

class ObservableHighscoreListProgram {
	ObservableHighscoreList 

...

observableHighscoreList
	void init()
	void run()
}
ObservableListListener <|.. ObservableHighscoreListProgram

...


Del 3: ObservableList

Den abstrakte superklassen ObservableList skal legges til som en generell superklasse for observerbare lister, som ObservableHighscoreList skal arve fra. Denne klassen skal både holde en liste med objekter (Object) og håndtere registrering av lyttere, altså en liste med ObservableListListener-instanse, som får beskjed om endringer i lista (slik at lista dermed er observerbar). Dette betyr at ObservableList overtar håndtering av både resultater og lyttere fra ObservableHighscoreList-klassen. For å gjøre ObservableList mer generell og gjenbrukbar, så lar vi den håndtere Object-instanser (heller enn Integer). Samtidig deklarerer den en abstrakt metode acceptsElement, som subklasser må redefinere for å bestemme hva slags objekter det skal være lov å legge inn. ObservableHighscoreList vil f.eks måtte redefinere den slik at bare Integer-objekter aksepteres.

ObservableList skal ha følgende metoder (noen er altså overtatt fra ObservableHighscoreList):

  • int size() - returnerer antall elementer i lista
  • Object getElement(int) - returnerer elementet i posisjonen angitt av argumentet
  • abstract boolean acceptsElement(Object) - returnerer hvorvidt subklassen aksepterer at objektet legges inn i lista (f.eks. aksepterer HighscoreList kun Integer-objekter).
  • void addElement(int, Object) - legger til et element på posisjonen angitt av argumentet, men bare dersom det aksepteres som element. Dersom elementet ikke aksepteres, så skal IllegalArgumentException utløses. Dersom posisjonen er ulovlig så skal IndexOutOfBoundsException utløses.
  • void addElement(Object) - legger til et element bakerst i lista, men bare dersom det aksepteres som element. Dersom elementet ikke aksepteres, så skal IllegalArgumentException utløses.
  • void removeElement(int) - fjerner elementet på posisjonen angitt av argumentet. Dersom posisjonen er ulovlig så skal IndexOutOfBoundsException utløses.

ObservableHighscoreList skal endres slik at den i størst mulig grad bruker metodene som arves fra ObservableList, men forøvrig ikke endrer oppførsel. Kjør hovedprogramklassen ObservableHighscoreListProgram for å sjekke at dette faktisk stemmer.

...


Klassediagrammet viser hvordan klassene henger sammen, og hvor metodene nå er deklarert/implementert. Merk at addElement- og removeElement-metodene er angitt som protected (ruter-symbolet), slik at kun subklasser skal kunne bruke dem.

PlantUML Macro
class ObservableList {
	Collection<Object> elements
	int size()
	Object getElement(int)
	{abstract} boolean acceptsElement(Object)
	#addElement(int, Object)
	#addElement(Object)
	#removeElement(int)
	addObservableListListener(ObservableListListener)
	removeObservableListListener(ObservableListListener)
}

class ObservableHighscoreList {
	int maxSize
	ObservableHighscoreList(int)
	boolean acceptsElement(Object)
	void addResult(int)
}

ObservableList <|-- ObservableHighscoreList

interface ObservableListListener {
	listChanged(ObservableList, int)
}
ObservableList -right-> "*" ObservableListListener: observableListListeners

class ObservableHighscoreListProgram {
	ObservableHighscoreList highscoreList
	void init()
	void run()
}
ObservableListListener <|.. ObservableHighscoreListProgram


Testkode for denne oppgaven finner du her: patterns/observable/ObservableListTest.java. Original-koden (jextest) finner du her: patterns/observable/ObservableList.jextest.

...