• No results found

Laborationer, moment 4 5

N/A
N/A
Protected

Academic year: 2022

Share "Laborationer, moment 4 5"

Copied!
12
0
0

Loading.... (view fulltext now)

Full text

(1)

2D4135 Objektorienterad programmering, analys och design med Java, 5p, vt 2004

Laborationer, moment 4–5

Detta är andra delen av labkursen. Tag med denna sida till varje redovisning och se till att du får kvittens från din lärare. För din egen skull, spara sidan tills du sett att dina resultat är inrapporterade till Ladok!

Namn ... Personnr ...

Moment 4 – Designmönster

För betyg 3 gör man uppgifterna a, b, c, en av {d, e} samt f (5 st).

För betyg 4 gör man en uppgift till av d, e, g och h (6 st).

För betyg 5 gör man ytterligare en (7 st).

a – Template ... Kvitteras ...

b – Abstract Factory ... Kvitteras ...

c – Composite ... Kvitteras ...

d – Observer ... Kvitteras ...

e – Adapter ... Kvitteras ...

f – Strategy ... Kvitteras ...

g – Strategy – extra ... Kvitteras ...

h – Valfritt mönster ... Kvitteras ...

Moment 5 – Enkel Klient

Godkänt den ... Kvitteras ...

Betyg 4–5 ... Kvitteras ...

1

(2)

En tom sida!

(3)

Moment 4: Designmönster

Innehåll

Genom designmönster beskriver man beprövade lösningar på vanliga problem som återkommer i olika sammanhang. Varje mönster ges ett (ibland flera) namn. Med hjälp av designmönster i ”verktygslådan” kan designproblem diskuteras på en högre nivå än tidigare och förhoppningsvis lösas snabbare och med säkrare resultat. Det krävs dock en del övning för att bli duktig på designmönster. Vissa är komplicerade och tar tid att bli förtrogen med.

Länkar

Här är några länkar till information om designmönster. Finns också direkt på kurs- hemsidan.

http://patterndigest.tripod.com http://hillside.net/patterns

http://www.mindview.net/Books/TIPatterns/

Den sista är en on-line bok som tyvärr inte innehåller några UML-diagram.

Uppgifter

I den här uppgiften ska några enkla, grundläggande och vanliga designmönster stu- deras i detalj. De ska implementeras och tillämpas på mycket små stiliserade pro- blem. Själva mönstret skall vara i fokus i varje övning och inte få skymmas av detaljer i en komplicerad tillämpning. Till varje mönster ska minst ett testprogram skrivas som visar att det fungerar. Målet med labmomentet är förståelse för design- mönstren!

3

(4)

a) Template Method

I en superklass definieras ett algoritmskelett där detaljer ”sparas” till subklasserna.

Skelett-metoden (eller metoderna) anropar metoder som definieras om i subklasser- na. Se t.ex. Jia, avsnitt 7.2.2. Animeringsappleten som vi gör i labmoment 1 är ett lite större exempel på detta mönster.

Subklass

methodX() methodY()

Superklass

templateMethod() methodX() methodY()

templateMethod anväder methodX och methodY

Tilläpma Template Method på följade:

• En engelsk gallon är 4.546 liter och en amerikansk gallon är 3.785 liter. I båda systemen definieras en pint som 1/8 gallon. Skriv en abstrakt klass SIConverter som superklass till de två konkreta klasserna ImperialConverter och USConverter. Skriv metoden pint() som en template method i den ab- strakta klassen. pint() får returnera gallon()/8. Metoden gallon() är ab- strakt i superklassen men implementeras i respektive subklass och svarar med hur många liter en gallon är i det aktuella systemet. Skriv ett program som skapar objekt av båda konkreta klasserna och demonstrerar i ett testprogram att det fungerar. Obs! Metoderna ska göra mycket lite, bara returnera ett tal.

Endast mönstret ska visas.

(5)

b) Abstract Factory

Implementera en abstrakt klass Human med två konkreta subklasser Man respektive Woman. Använd en abstract factory – teknik där instanser skapas enligt följande i Human:

public static Human create (String pnr) {/* metodkropp */}

pnr är ett personnummer som förutsätts riktigt, ni behöver inte kolla det. Om näst sista siffran i personnumret är udda så ska en instans av Man returneras och annars en instans av Woman. Se också till att det enda sättet att instansiera någon av de konkreta klasserna är via den ovan angivna metoden. Det ska inte gå att kompilera new Man (..) eller new Woman (..) i testprogrammet.

Tips: För att att få detta att fungera bör man göra ett eget paket för Human och dess subklasser. Skapa en underkatalog human som också är det paket där de tre klasserna Human, Man och Woman ligger. Inled varje klass med package human; Med hjälp av rätta modifierare på metoder och konstruktorer kan man få den begärda strukturen.

Låt testprogrammet ligga på nivån ovanför human. Se också till att testprogrammet på något sätt bekräftar att objekt av rätt typ skapas, t.ex. genom att personer har en String-representation som skrivs ut i testprogrammet.

Human

Human create(String pnr)

Man Woman

5

(6)

c) Composite

Idén med mönstret Composite är att grupper av objekt ordnade hierarkiskt i en trädstruktur och enstaka konkreta objekt skall kunna behandlas lika. Klassen för grupper Composite och klassen för ett enstaka objekt SomeProduct ärver båda från Product. En objekt av Composite kan vara godtyckligt komplicerat. Här exempli- fierar vi med produkter med pris. Priet för ett Composite – objekt beräknas som summan av priserna för delarna där varje del i sin tur kan vara en grupp av objekt.

Observera att inga rekursiva metoder ska skrivas, trots att ett Composite – objekt blir rekursivt till sin natur. Det rekursiva byggs in i definitionerna av klasser och metoder. Inför redovisningen, rita gärna en bild av den Composite – struktur ni skapat. Composite –objektet måste bestå av minst 3 objekt, varav minst två av dem består av flera objekt.

Product

float price()

SomeProduct float price float price()

Composite

float price() parts

0..*

(7)

Om du är nöjd med betyg 3 på labkursen, hoppa över en av d och e d) Observer

Implementera en klass Publisher som publicerar trycksaker och en Subscriber som prenumererar på trycksaker. Det räcker att Publisher har en lista (t.ex. ArrayList) där trycksaker representeras av strängar. Använd mönstret Observer för att låta prenumeranter prenumerera på informationen att nya trycksaker tillkommit i pub- licistens utbud. Alltså, den metod som lägger till nya strängar i trycksakslistan ska också underrätta alla beroende objekt, dvs alla objekt som registrerats som Observers. Detta mönster finns implementerat i Java som standardgränssnittet Observer och standardklassen Observable. Dessa ska användas i uppgiften.

7

(8)

e) Adapter

En adapter är ett objekt som anpassar gränssnittet mellan två objekt så att det pas- sar båda. Tänk er följande situation: En Client kommunicerar genom gränssnittet ClientInterface med ett Target – objekt. Target – objektet måste bytas ut mot ett objekt av Adaptee som tillhandahåller samma tjänster som Target men via ett annat gränssnitt, nämligen AdapteeInterface. Inget av gränssnitten får ändras, de används i andra sammanhang.

Client Target

request()

<<Interface>>

ClientInterface

Adapter Adaptee adaptee request()

Adaptee

specificRequest()

<<Interface>>

AdapteeInterface

Client Adapter Adaptee

I en minimal demo–implementation av detta kan gränssnitten se ut så här:

public interface ClientInterface { public int value (); // Läs värde

public void value (int v); // Ändra värde }

och

public interface AdapteeInterface { public int getValue (); // Läs värde

public void setValue (int v); // Ändra värde }

Skriv klassen Adaptee som innehåller ett värde som kan sättas och läsas av, klassen Client som sätter och läser värden i sitt target-objekt via gränssnittet ClientInterface.

(Obs! Client ska inte implementera ClientInterface). Skriv klassen Adapter som ser till klienten kan använda Adaptee – objektet. Observera att klienten inte får känna till klassen Adaptee utan endast gränssnittet ClientInterface. Se även be- skrivningen i Jia, avsnitt 10.4.1.

Skriv ett testprogram till det hela.

(9)

f ) Strategy

Använd mönstret Strategy för att konstruera en räknare till vilken man kan ge ett objekt som definierar startvärde, slutvärde, steg och uppräkningsfunktion. I ett test- program kan följande rader stå:

Incrementor plusEtt = new ArithmeticIncrementor(1,5,1);

Incrementor gångerTvå = new GeometricIncrementor(1,1024,2);

Counter c1 = new Counter(plusEtt);

Counter c2 = new Counter(gångerTvå);

c1.count();

c2.count();

Utskrifter kan bli:

1 2 3 4 5

1 2 4 8 16 32 64 128 256 512 1024

I klassen Counter finns en variabel, t.ex. myInc som bundits till det aktuella Incrementor – objektet. Metoden count kan då innehålla ungefär

while (!myInc.atEnd()) {

System.out.print(myInc.getValue() + " ");

myInc.next();

}

System.out.print(myInc.getValue() + "\n");

Skriv den abstrakta klassen Incrementor, de konkreta klasserna för aritmetisk (+/-) respektive geometrisk (*) uppräkning, klassen Counter samt ett testprogram. Det är tillåtet att ändra detaljer i uppgiften, bara mönstret Strategy används.

9

(10)

g) Strategy – extra

I den föregående uppgiften föreslås att räknarna ska sluta då det aktuella värdet är lika med stopp–värdet. Då måste man räkna ut det exakta slutvärdet då man skapar en räknare, räknar man fel så ger count en oändlig repetition. Bättre är att avsluta count då aktuellt värde passerat slutvärdet. Men vad betyder ”passera” ? Jo, att värde >= slutvärde om steget är > 0− och att värde <=slutvärde om steget är <0.

Ett sätt att lösa detta är förstås att låta metoden atEnd testa värdet av steget och använda olika tester beroende på stegets tecken. Detta är en lösning som inte är särskilt ”objektorienterad”. En OO-lösning får man om man tillhandahåller jämfö- relsefunktionen också i ett objekt enligt mönstret Command. Varje Incrementor–

objekt ska då ha ett Comparator – objekt där det finns en funktion som jämför värde och slutvärde och talar om ifall räknaren är färdig eller ej.

Ändra Incrementor – klassen så att den har ytterligare en konstruktor, där man utöver de tre talen kan ge ett objekt med en jämförelsefunktion. Låt den tidigare konstruktorn vara kvar men utöka den så att den som default använder ett objekt med jämförelsefunktion som fungerar som den enklare jämförelsen, som bara testar om värde == slutvärde.

För att lösa denna uppgift måste alltså ytterligare ett interface skrivas och im- plementeras av tre olika klasser. Incrementor och dess implementationer måste ändras men inte Counter klassen (om man följt instruktionerna). Testprogrammet bör kunna köras igen men bör sedan utökas för att testa det nya.

h) Alternativ extrauppgift

Välj något annat designmönster om implementera ett demonstrationsexempel.

(11)

Moment 5: En enkel klient

– Välj Uppmuntran eller Primtal

Två serverprogram

Två serverprogram finns tillgängliga på en dator på Nada. Det ena ger uppmunt- rande kommentarer till ditt programmerande och det andra serverar primtal. Båda programmen kör på datorn nada28.nada.kth.se, uppmuntranprogrammet i port 4712 och primtalen i port 4713. Båda programmen börjar med att läsa på sin in- ström, tolka det första kom kommer där som klientens namn och skriver sedan två rader meddelanden på sin utström, ungefär så här:

Hej Anna! Välkommen till PrimeServern. Just nu finns 3 användare.

Sedan starten av servern har vi haft 9 besökare.

Programmen övergår sedan till att omväxlande läsa på sin inström och skriva på sin utström. När det på inströmmen kommer null, q eller Q så avslutas tråden.

Programmen kan ha flera klienter uppkopplade samtidigt genom att varje klient får ett eget trådobjekt med en run-metod. När runmetoden kör klart avslutas trå- den och klienten kopplas ned. Det mesta av koden till Muntra–servern finns på sid 12, dock lite "hoptryckt" för att få plats på en sida. Prime–servern är mycket lik Muntra–servern. Vi går (har gått) igenom dem på en lektion. Se lektionsmate- rialet!

Uppmuntran

Varje gång något som ej är ett avslutningskommando läses av servern från inström- men kommer en uppmuntrande kommentar att skickas ut på utströmmen.

Primtal

Varje rad som läses av servern tolkas som ett heltal och närmast följande primtal beräknas och skickas till utströmmen. Servern använder enklast möjliga metod för beräkning av primtalen så det kan ta lång tid för stora tal. Upp till åtminstone ca 1010 är det inga problem. Om man skickar in data som ej kan tolkas som hel- tal eller om man ger ett för stort heltal så ges svaret -1. Primeservern översätter inkommande text till heltal av typ long.

Uppgift

Välja ett av dessa serverprogram, skriv ett litet klientprogram som så länge använ- daren vill upprepar att hämta indata från användaren, skicka till servern, hämta data från servern och presentera för användaren.

För betyg 3

Gör textgränssnitt (det räcker inte att koppla sig till servern med telnet, det kan man faktiskt göra utan att skriva något program!)

För betyg 4-5

Gör ett grafiskt gränssnitt till klienten.

Extra

Använd primeservern för att hitta primtalstvillingar.

11

(12)

import java.net.*; import java.io.*; import java.util.*;

public class Muntra {

public static void main(String[] args){

try {

ServerSocket sock = new ServerSocket(4712);

while (true) {

new Tråd(sock.accept()).start(); } } catch(IOException e){System.err.println(e);}

} }

class Tråd extends Thread {

static int antalTrådar=0, antalBesökare=0;

BufferedReader in; PrintWriter ut; Socket socket;

public Tråd(Socket socket) { this.socket = socket;

try {

in = new BufferedReader

(new InputStreamReader(socket.getInputStream()));

ut= new PrintWriter(socket.getOutputStream());

}

catch(IOException e) {System.err.println(e);}

}

public void run() {

Random random=new Random();

String[] hand={...}; // Här ligger alla uppmuntrande uttalanden.

int n = hand.length;

try {

String namn=in.readLine().trim();

ut.println("Hej "+ namn + ", välkommen till MuntraServern." +

" Just nu finns " + (++antalTrådar) + " användare");

ut.flush();

ut.println("Sedan starten av servern har vi haft " + (++antalBesökare) + " besökare\n");

ut.flush();

while(true) {

String inrad = in.readLine();

if(inrad==null || inrad.trim().equalsIgnoreCase("q")) break;

ut.println(hand[random.nextInt(n)] + " " + namn);

ut.flush();

}

socket.close();

System.out.println("Nu slutade "+namn);

antalTrådar--;

References

Related documents

Bibliotekarie 4 beskriver en morgon då sex skolklasser kom till biblioteket samtidigt klockan tio: ”Alltså det är ju flera hundra barn som bara ru- sar in och alla är ju

Skatten avseende diesel föreslås höjas med 3,3 öre per liter, istället för 12,7 öre per liter, till totalt 4,74 kr per liter..

Den här uppsatsen handlar även om vad några av pedagogernas åsikter om det engelska språket och att implementera den via estetisk läroprocess samt en inblick om

Detta uttrycks under ett flertal intervjuer, vilket även styrks i Läroplanen (Skolverket, 2010): ”Förskolan skall komplettera hemmet genom att skapa bästa

1 § Den som genom misshandel eller annars med våld eller genom hot om brottslig gärning tvingar en person till samlag eller till att företa eller tåla en annan sexuell handling

Som infoenhet är vi beroende av att kunna åka till de olika SAK-projekten för att kunna berätta om dessa, vare sig mottagarna är SAKs medlem- mar hemma i Sverige eller de 5 500

Anm: Observera att om årtalet slutar på 00 är året ett skottår bara om hela årtalet är delbart med 400.. Delbarhet med 5: Den sista siffran ska vara 0

Resultaten visar att de professionella har erfarenheter av att ju längre en hemmasittande elev har varit borta från skolan desto svårare blir det för eleven att komma tillbaka.. Den