• 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 2005

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 (totalt 6 st).

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

a – Template ... Kvitteras ...

b – Factory ... Kvitteras ...

c – Composite ... Kvitteras ...

d – Observer ... Kvitteras ...

e – Adapter ... Kvitteras ...

(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ög- re nivå än tidigare och förhoppningsvis lösas snabbare och med säkrare resultat.

Det krävs dock en hel 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://www.patterndepot.com/put/8/JavaPatterns.htm http://hillside.net/patterns

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

Den sista är en on-line bok.

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 grundläggande förståelse för några vanliga designmönster.

JUnit

JUnit är ett färdigt ramverk för testning. Prova på Junit genom att använda det för testning åtminstone en gång under arbetet med designmönsterexemplen. Länkar till information finns på kurshemsidan, lite delas ut på papper. Exempel på användning av JUnit visas på en lektion.

(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.

(5)

b) 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 kompile- ra new Man (..) eller new Woman (..) i testprogrammet. Man och Woman får inte heller vara inre klasser i Human.

Tips: För att att få detta att fungera kan 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

(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. Ett objekt av Composite kan vara godtyckligt komplicerat fast följer träd- strukturen. Här exemplifierar 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 i sin tur 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.

(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. Namnen är valda för att markera att klienten ska använda metoderna i ClientInterface för att kommu- nicera oavsett vilket objekt som nås. 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 beskrivningen 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 lösa en annan uppgift med minst samma kompexitet om bara mönstret Strategy används.

(10)

g) Valfritt

Välj något annat mönster och skriv ett litet exempelprogram. Förslag: proxy, bridge, state, decorator.

h) Valfritt

Välj ytterligare ett mönster och skriv ett exempel!

(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 plan6ray.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ärmaste större tal som med stor sannolikhet (0.999) är ett primtal beräknas och skickas till utströmmen.

Servern anväder klassen BigInteger i paketet java.math (skall ej förväxlas med klassen java.Math) och dess metod isProbablePrime. För detaljer om detta, se dokumentationen! Om icke-heltal kommer på serverns inström returneras -1.

Uppgift

Välja ett av dessa serverprogram, skriv ett litet klientprogram som kommunicerar på

(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--;

}

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

References

Related documents

Båda grupperna svarade att lärarens syfte med laborationen var att de själva skulle komma fram till sambandet mellan tryck och volym.. Båda grupperna tyckte

Själva metoden de använder sig av går således att härleda till ett emancipatoriskt synsätt, då fokus blir att inte bara läsa böckerna utan även att samtala kring dem och

Examinatorer som även ska kunna rapportera resultat i Ladok måste också få rättighet i fliken Rapporteringsrättighet för kursen..

Om bara statistiskt signifikanta resultat publiceras och forskare väljer att avsluta projekt som inte leder till signifikans är det lätt att se att detta kan leda till

Förvaltningsärenden och bidrag som fördelar ekonomiskt stöd till arbetslivsmuseer och civila samhället samt ger bidrag till forskning och utveckling, Samlingar och utställningar

Granskaren har intervjuat chefer och medarbetare från fem enheter som alla bedömts vara särskilt utsatta för försök till otillåten påverkan. Granskningen visar att verksamheten

På detta sätt är de en viktig del i arbetet med att ta fram en modell för samhällsekonomiska analyser av olika sociala insatser som direkt eller indirekt syftar till att

Tillsammans med åkerier har ECOSTARS bidragit till en bättre luftkvalité med minskade utsläpp och dessutom har åkerier sparat tiotusentals kronor genom att öka energieffektiviteten