Target beskriver gränssnittet såsom Client vill ha det. I klassen Adapter sker konverteringen av anropen, till gränsnittet som klassen

Relevanta dokument
Föreläsning 9. Designmönstrer

Föreläsning 9. Designmönstrer

Föreläsning 9. Designmönstrer

Properties. Användbara metoder som kan anropas i propertychanged:

Föreläsning 10. Designmönstrer

DAT043 - Föreläsning 7

Två designmönster, MVC och Observer/Observable. Objektorienterad programvaruutveckling GU (DIT011)

Designmönster/Design patterns

Lösningar till tentamen i EDAF25

Subklasser och arv Inledning till grafik (JFrame och JPanel). Något om interface. Objektorienterad programvaruutveckling GU (DIT011) Subklasser

Programmeringsteknik II - HT18. Föreläsning 6: Grafik och händelsestyrda program med användargränssnitt (och Java-interface) Johan Öfverstedt

Lösningar till tentamen i EDAF25

Föreläsnings 11 - GUI, Händelsestyrda program, MVC

Dagens program. Objektorienterad modellering och diskreta strukturer / design. Model/View/Control-implementering. Model/View/Control-arkitektur

ITK:P1 Föreläsning 4. Grafiska gränssnitt i Java. AWT-komponenter

Laboration 2: Designmönster

Lösningsförslag till tentamen

Tentamen LÖSNINGSFÖRSLAG

MVC-mönstret. model-view-control i Swing

Övning 5. TDA550 - Objektorienterad programvaruutveckling, fk

Tentamen i EDAF25. 1 juni Skrivtid: Skriv inte med färgpenna enda tillåtna färg är svart/blyerts.

DUGGA: Objektorienterade applikationer. Läs detta! Uppgifterna är inte avsiktligt ordnade efter svårighetsgrad.

Laboration 2: Designmönster

Detta dokument är ett exempel, cirka andra hälften av en tentamen för TDA545 Objektorienterad programvaruutveckling

Observer Pattern och MVC. Objekt-orienterad programmering och design Alex Gerdes, 2016

Föreläsning 10. Mer om grafiska komponenter Händelsestyrda program. Layout Managers. Exempel: FlowLayout. Klassen FlowLayout

Föreläsning 10. Mer om grafiska komponenter Händelsestyrda program. Layout Managers

Föreläsning 3: Händelsestyrda program och användargränssnitt

Observer Pattern och MVC. Objekt-orienterad programmering och design (DIT953) Niklas Broberg, 2018

Mer om grafiska komponenter. Händelsestyrda program

ITK:P1 Lektion 4. Lektion 4. Lektion 4. Att implementera en spelidé i Java. DSV Peter Mozelius

Mediator. DD2385 Programutvecklingsteknik Några bilder till föreläsning 10 6/ Designmönster: Mediator Facade State Decorator

PROG2 Tenta Gäller SP:PROG2, DSK2:PROG2, FK:PROG2, FK:OOP, DSV1:P2 och ITK:P2

2I1049 Föreläsning 8. Grafiska gränssnitt i Java. AWT-komponenter. Grafiska gränssnitt, Java interface och händelsehantering

DI-institutionen Sid 1 av 6 Hans-Edy Mårtensson Sten Sundin

Dagens föreläsning. Arrayer och klasser. Medan ni väntar: Gå till m.voto.se/prog11 och svara på några gamla tentamensfrågor! (26 januari 2018 F3 1 )

Objektorienterad Programkonstruktion. Föreläsning 3 9 nov 2015

Observer Pattern och MVC. Objekt-orienterad programmering och design (DIT952) Niklas Broberg, 2017

Föreläsning 8 - del 2: Objektorienterad programmering - avancerat

Lösningar till Fiktiv Tentamen på kursen. 2D4135 Objektorienterad programmering, design och analys med Java vt2004. Teoridel

Projekt 2 XL. Observer-mönstret

4.7 Observatörsmönstret

DUGGA: Objektorienterade applikationer. Läs detta! Uppgifterna är inte avsiktligt ordnade efter svårighetsgrad.

Institutionen för TENTAMEN CTH VT-15 Datavetenskap TDA550 DAG: TID: 8:30 12:30

Lektion Händelsehanterare

Lycka till! TENTAMEN: Objektorienterade applikationer. Läs detta! 1 (6) Tentamen

Föreläsning 12. Föreläsning 12. Rörliga figurer Klassen Timer Undantag Något om applets. Rörliga appletsfigurer Klassen Timer Undantag

Objektorienterad Programkonstruktion. Föreläsning 3 7 nov 2016

Laborationer, moment 4 5

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 11 Jonas Lindgren, Institutionen för Datavetenskap, LiU

Tentamen LÖSNINGSFÖRSLAG

Tentamen LÖSNINGSFÖRSLAG. c) Tilldelningen C x = new D() ger kompileringsfel eftersom klassen D är abstrakt.

Svaret kan ges i Javakod (eller i UML-klassdiagram). public class A { B minb;... } public class B { <B:s många variabler och metoder> } Lösning:

TDDE10 m.fl. Objektorienterad programmering i Java Föreläsning 7 Erik Nilsson, Institutionen för Datavetenskap, LiU

Objektorienterad Programmering DAT043. Föreläsning 5 29/1-18 Moa Johansson (delvis baserat på Fredrik Lindblads material)

OOP Objekt-orienterad programmering

Lösningsförslag till tentamen

HT2 2015, FÖRELÄSNING 15 (XL-PROJEKTET)

Laborationer, moment 4 5

Denna vecka. Idag. Grafiskt användarsnitt. Vi kommer att se

2I1049 Föreläsning 5. Objektorientering. Objektorientering. Klasserna ordnas i en hierarki som motsvarar deras inbördes ordning

UML. Objekt-orienterad programmering och design (DIT952) Niklas Broberg, 2016

12 Metaprogrammering i Java

Objektorienterad Programkonstruktion. Föreläsning 7 24 nov 2015

TENTAMEN. Objektorienterade applikationer CHALMERS. 2018/2019, lp 3 DAT055. Uno Holmer

Tentamen FYTA11 Javaprogrammering

PROG2 Tenta Gäller SP:PROG2, DSK2:PROG2, FK:PROG2, FK:OOP, DSV1:P2 och ITK:P2

Dagens program. Programmeringsteknik och Matlab. Vad är arv? Vi ärver från GregorianCalendar. Kan vi bygga vidare på existerande klasser?

The Last Adventure. Innehåll. Objektorientering. Språket Java. Java - Paket. Java - synlighet. Den sista lektionen. Repetition.

OOP Objekt-orienterad programmering

Arv. Fundamental objekt-orienterad teknik. arv i Java modifieraren protected Lägga till och modifiera metoder med hjälp av arv Klass hierarkier

Tentamen i Objektorienterad programmering

Kungliga Tekniska Högskolan Ämneskod 2D4134 Nada Tentamensdag maj - 19 Tentamen i Objektorientering och Java Skrivtid 5 h

Lösningar för tenta 3 DAT043,

Instuderingsuppgifter läsvecka 6 - LÖSNINGAR

Tentamen i Objektorienterad programmering E

Tentamen. 2D4135 vt 2005 Objektorienterad programmering, design och analys med Java Lördagen den 28 maj 2005 kl

Laboration 15 Grafiskt användargränssnitt

Modelsvar för Tentamen för Objektorienterad programvaruutveckling, TDA545

HT1 2013, FÖRELÄSNING 5

Lösningsförslag till tentamen i EDAF25 Objektorienterad modellering och design Helsingborg

LULEÅ TEKNISKA UNIVERSITET

Tentamen i Objektorienterad modellering och diskreta strukturer

Grundläggande programmering, STS 1, VT Sven Sandberg. Föreläsning 18

lgammal2.txt // Lösningar till gammal tentamen // Uppgift 1 a

Objektorienterad programutveckling, fk

LÖSNINGSFÖRSLAG Programmeringsteknik För Ing. - Java, 5p

SI-pass 4. Johan Brook och Jesper Persson. 25 september Diskutera och svara på om påståendena nedan är äkta sanningar eller listiga lögner.

Tentamen. DD2385 Programutvecklingsteknik vt 2013 Onsdagen den 22 maj 2013 kl Hjälpmedel: penna, suddgummi, linjal

Fakulteten för ekonomi, kommunikation och IT. Corba. Datum: Mathias Andersson

Institutionen för TENTAMEN CTH VT-15 Datavetenskap TDA550 DAG: TID: 8:30 12:30

Design Patterns. En kort introduktion

F8 - Arv. ID1004 Objektorienterad programmering Fredrik Kilander

Outline. Objektorienterad Programmering (TDDC77) Signatur. Klassen calculator. Överlagring (overloading) Arv (inheritance) Ahmed Rezine

Outline. Objektorienterad Programmering (TDDC77) Åsidosättning. Signatur. Åsidosättning. Abstrakta klasser. Ahmed Rezine.

Föreläsning 6. Designmönstret Decorator I/O-ramverket

Föreläsning 8. Arv. Arv (forts) Arv och abstrakta klasser

Frivillig Java-swing-Graphics-lab Programmeringsteknik MN1 vt02

Lösningsförslag till tentamen

Objektorienterad Programmering (TDDC77)

Transkript:

Designmönstret Adapter Föreläsning 10 Fler Design Patterns PegAdapter implements SquarePeg RoundPeg Adapter, FactoryroundPeg; Method PegAdapter(RoundPeg peg) Decorator, Observer this.roundpeg = peg; Model-- //constructor Bridge, Composite insert(string str) Command roundpeg.insertintohole(str); //insert //PegAdapter Designmönstret Adapter Designmönstret Adapter Pattern konverterar gränsnittet hos en klass till ett annat gränssnitt så att inkomplatibla klasser kan samarbeta. Client Target +request(): Adapter Adaptee +request(): +otherrequest():... adaptee.otherrequest();... Target beskriver gränssnittet såsom Client vill ha det. I klassen Adapter sker konverteringen av anropen, till gränsnittet som klassen 2 Adaptee tillhandahåller Designmönstret Adapter PegAdapter implements SquarePeg RoundPeg roundpeg; PegAdapter(RoundPeg peg) this.roundpeg = peg; //constructor insert(string str) roundpeg.insertintohole(str); //insert TestPegs //PegAdapter static main(string[] args) RoundPeg roundpeg = new RoundPeg(); SquarePeg squarepeg = new ConcreteSquarePeg(); SquarePeg adapter = new PegAdapter(roundPeg); squarepeg.insert("inserting square peg!"); adapter.insert("inserting round peg!"); //main //TestPegs interface SquarePeg insert(string str); //SquarePeg ConcreteSquarePeg implements SquarePeg insert(string str) System.out.println("SquarePeg insert: " + str); //insert //ConcreteSquarePeg RoundPeg insertintohole(string msg) System.out.println("RoundPeg insertintohole: " + msg); //InsertIntoHole //RoundPeg 3 Utskrift: Utskrift: SquarePeg insert: Inserting square peg! RoundPeg insertintohole: Inserting round peg! 4

Designmönstret Factory Method Designmönstret Factory Method Produkter Factory method används när man interface Product abstract String shipfrom(); ProductA implements Product String shipfrom () return " from South Africa"; ProductB implements Product String shipfrom () return " from Spain"; ProductC implements Product först vid exekveringen kan avgöra vilken typ av objekt som skall skapas vill undvika beroenden av konkreta klasser. interface Product abstract String shipfrom(); Main ProductA Product interface Creator implements static main(string[] args) String shipfrom () return " "; String shipfrom () abstract Product factorymethod(int month); Creator c = new ConcreteCreatorA(); return " from South Africa"; System.out.println("From ConcreteCreatorA:"); DefaultProduct implements Product String shipfrom () ConcreteCreatorA implements Creator printyearlydeliver(c); return " not available"; ConcreteCreatorB(); Product factorymethod(int month) c = new ProductB implements Product 5 6 if (month >= 4 ConcreteCreatorB:"); && month <=11) System.out.println("From String shipfrom () return new ProductA(); printyearlydeliver(c); return " from Spain"; else if (month == 1 month == 2 month == 12) return new ProductB(); staticelse printyearlydeliver(creator c) Product ProductC implements Designmönstret Factory Method Designmönstret Factory Method for (int i = 1;return i <= 12; i++) shipfrom () String new DefaultProduct(); Körningsexempel: Client Product = c.factorymethod(i); Fabriker " "; product return From ConcreteCreatorA: from Spain System.out.println(" " + product.shipfrom()); Main from Spain ConcreteCreatorB implements interface Creator Creator static main(string[] args) not available from South Africa abstract Product factorymethod(int month); Creator c = new ConcreteCreatorA(); from South Africa Product factorymethod(int month) System.out.println("From ConcreteCreatorA:"); DefaultProduct implements Product from South Africa ConcreteCreatorA implements Creator printyearlydeliver(c); from South Africa Product factorymethod(int month) c = new ConcreteCreatorB(); return new ProductC(); String shipfrom () from South Africa //Main from South Africa if (month >= 4 && month <=11) System.out.println("From ConcreteCreatorB:"); from South Africa return new ProductA(); printyearlydeliver(c); return " not available"; from South Africa else if (month == 1 month == 2 month == 12) from Spain return new ProductB(); static printyearlydeliver(creator c) From ConcreteCreatorB: else for (int i = 1; i <= 12; i++) return new DefaultProduct(); Product product = c.factorymethod(i); Creator Client +factorymethod() Product ConcreteProductA ConcreteProductB ConcreteCreatorA ConcreteCreatorB +factorymethod() +factorymethod() System.out.println(" " + product.shipfrom()); ConcreteCreatorB implements Creator Product factorymethod(int month) Klie return new ProductC(); nt //Main 7 8

Designmönstret Decorator Designmönstret Decorator används för att lägga till funktionalitet på individuella objekt utan att använda arv. Mönstret används ofta då arv skulle ge alldeles för många nivåer i arvshierarkin, eller då arv inte är möjligt. Rekommenderad struktur för Decorator-mönstret är enligt: Component abstract Component: En klass som definierar gränssnittet för de objekt som dynamiskt kan ges ytterligare funktionalitet. 1 operation() ConcreteComponent Decorator abstract operation() operation() ConcreteComponent: En klass som definierar objekt till vilka ytterligare funktionalitet kan ges. component.operation(); ConcreteDecoratorA ConcreteDecoratorB addedstate operation() addedbehavior() super.operation(); addedbehavior(); Antag att vi har en smörgåsbutik. Det finns ett antal brödsorter att välja mellan och ett antal olika pålägg. operation() addedbehavior() Decorator: Har en referens till ett Component-objekt och definierar ett gränssnitt som överensstämmer med gränssnittet för Component. Kunden skall kunna kombinera sin smörgås efter eget önskemål. ConcreteDecorator: Lägger till funktionalitet på objektet. 9 10 Antag att vi har en smörgåsbutik. Kunden kan kombinera sin smörgås efter eget önskemål. Det finns ett antal brödsorter att välja mellan och ett antal olika pålägg. Vi startar med att skapa en abstrakt klass Sandwich enligt: Sandwich Baguette Panini SandwichDecorator abstract interface Sandwich String ; double ; //Sandwich Salami Ham Cheese Tomato 11 12

Sedan inför vi vår Decorator-klass, SandwichDecorator, vilken är en abstrakt klass som ärver från Sandwich-klassen och som har en instansvariabel av klassen Sandwich: Sedan skapar vi en klass för var och en av de brödsorter vi har. Dessa klasser ärver klassen Sandwich. Säg att vi har panini och baguetter: abstract SandwichDecorator implements Sandwich protected Sandwich decoratedsandwich; SandwichDecorator(Sandwich sandwich) decoratedsandwich = sandwich; //constructor String return decoratedsandwich.; //getname double return decoratedsandwich.; //getprice //SandwichDecorator Panini implements Sandwich String return "Panini"; Baguette implements Sandwich //getname String double return "Baguette"; return 10.5; //getname //getprice double //Panini return 8.5; //getprice //Baguette Nu kan vi skapa konkreta klasser, t.ex. för att lägga ost, skinka, salami eller tomater på smörgåsen. 13 14 Nu kan vi skapa konkreta klasser, t.ex. för att lägga ost, skinka, salami eller tomater på smörgåsen: Salami extends SandwichDecorator Salami (Sandwich sandwich) super(sandwich); //constructor Tomato extends SandwichDecorator String Tomato (Sandwich sandwich) return super. + " + Salami"; super(sandwich); //getnam //constructor double chargesalami() String return 8.5; return super. + " + Tomato"; //getname double double chargetomato() return decoratedsandwich. return 2.5; + chargesalami(); //getprice double //Salami return decoratedsandwich. + chargetomato(); //getprice //Tomato Cheese extends SandwichDecorator Cheese (Sandwich sandwich) super(sandwich); Ham extends SandwichDecorator //constructor Ham (Sandwich sandwich) String super(sandwich); return super. + " + Cheese"; //constructor //getnam String double chargecheese() return super. + " + Ham"; return 5.5; //getname double chargeham() double return 7.5; return decoratedsandwich. + chargecheese(); double //getprice return decoratedsandwich. //Cheese + chargeham(); //getprice //Ham 15 16

Designmönstret Observer TestSandwich static main (String[] args) //lets create a baguette with cheese, ham and tomato Sandwich ourbaguette= new Baguette(); ourbaguette = new Cheese(ourBaguette); ourbaguette = new Ham(ourBaguette); ourbaguette = new Tomato(ourBaguette); System.out.println(ourBaguette. + " = " + ourbaguette. + " kronor"); //lets create a panini with salami and tomato. Sandwich ourpanini = new Panini(); ourpanini = new Salami(ourPanini); ourpanini = new Tomato(ourPanini); System.out.println(ourPanini. + " = " + ourpanini. + " kronor"); //main //TestSandwich När programmet körs erhålls utskriften: Baguette + Cheese + Ham + Tomato = 24.0 kronor Panini + Salami + Tomato = 21.5 kronor Designmönstret Observer är en teknik som tillåter ett objekt som ändrat sitt tillstånd att rapportera detta till andra berörda objekt så att de kan vidta lämpliga åtgärder. Designmönstret Observer definierar en-till-många relation minskar kopplingen mellan objekt Java stöder designmönstret Observer genom: klassen Observable och interfacet Observer klassen PropertyChangeSupport och interfacet PropertyChangeListener 17 Designmönstret Observer Observable +addobserver(o : Observer): +deleteobserver(o :Observer): #setchanged(): +notifyobservers(): Designmönstret Observer * Klassen Observable i Java har bl.a följande metoder: addobserver(observer o) lägger till en ny observatör o. Observer +update(o : Observable; arg: Object): deleteobserver(observer o) tar bort observatören o. ConcreteObserver Publisher +modifystate(): +getvalue(): Value 18 notifyobservers() meddelar alla observatörer att tillståndet har förändrats. protected setchanged() markerar att tillståndet har ändrats. Måste anropas för att notifyobservers() verkligen kommer att meddela observatörerna. +update(o: Observable; arg: Object): Det objekt som tillkännager att det ändrat sitt tillstånd är alltså observerbart (observable) och kallas ofta publisher. De objekt som underrättas om tillståndsförändringen kallas vanligtvis observers eller subscribers. Ovanstående klassdigarm överensstämmer med interfacet Observer och klassen Observable i Java. Interfacet Observer i Java har metoden: update(observable o, Object arg) som anropas av det observerbara objektet o när detta har förändrats. 19 20

Designmönstret Observer :Publisher Exempel Datorintrång :ConcreteObserverA java.util.observable; IntrusionDetector extends Observable someonetriestobreakin() //Denna metod anropas när någon försöker hacka sig in // i datorn. Detta meddelas alla som är intresserade setchanged(); java.util.observer; notifyobservers(); java.util.observable; //someonetriestobreakin SysAdm implements Observer //IntrusionDetector String name; IntrusionDetector dectector; SysAdm( String name, IntrusionDetector dectector) this.name = name; this.dectector = dectector; //constructor subscribe( ) dectector.addobserver(this); //subscriber update(observable server, Object err ) System.out.println( name + " got the message!" ); //update //SysAdm :ConcreteObserverB addobserver(this) addobserver(this) modifystate() notifyobservers() update(this, obj) getvalue() update(this, obj) getvalue() 21 Exempel Datorintrång 22 Designmönstret Composite Designmönstret Composite används för att sätter samman objekt till trädstrukturer för att representera part-whole hierarkier. Composite låter klienter hantera individuella objekt och grupper av kopplade objekt på ett likformigt sätt. Main static main( String[] argv ) IntrusionDetector id = new IntrusionDetector(); SysAdm kalle = new SysAdm( "Kalle", id ); SysAdm sven = new SysAdm( "Sven", id ); SysAdm rune = new SysAdm( "Rune", id ); kalle.subscribe(); rune.subscribe(); // Nu låtsas vi att någon försöker ta sig in id.someonetriestobreakin(); //main //Main Component * +operation() +add() +remove() +getchildren() Rune got the message! Kalle got the message! 23 Leaf Composite +operation() +operation() +add() +remove() +getchildren() forall g in children g.operation(); 24

Designmönstret Composite Designmönstret Composite Exempel: Exempel: En folder kan innehålla filer och andra foldrar. Antag att vi i en applikation behöver en metod som när den anropas på en fil skriver filens namn och när den anropar på en folder skriver ut namnet på foldern samt innehållet i foldern och innehållet i alla underfoldlar: :Folder "TDA550" :File "t.txt" :File "a.pdf" :Folder "Java" :File :File "D.java" "C.java" Data * +list(string) TDA550 t.txt a.pdf Java D.java C.java File Folder +list(string) +list(string) +add() +remove() 25 TDA550 Folder 1 t.txt File 1 Composite a.pdf Folder Designmönstret 3 Java Folder 2 //Client Program File 2 CompositePatternD.java static main(string[] args) Folder f1 = new Folder();C.java f1.setname("folder 1"); File 3 Folder f2 = new Folder(); f2.setname("folder 2"); Folder f3 = new Folder(); f3.setname("folder 3"); File 4 File file1 = new File(); file1.setname("file 1"); Designmönstret Composite interface Data list(string str); File implements Data String name; String return name; setname(string name) this.name = name; list(string str) System.out.println(str + this.); //File 26 java.util.*; Folder implements Data String name; List<Data> folder = new ArrayList<Data>(); String return name; setname(string name) this.name = name; list(string str) System.out.println(str + this.); for(data data : folder) data.list(" " + str); add(data data) folder.add(data); remove(data data) folder.remove(data); //Folder File file2 = new File(); File file3 = new File(); File file4 = new File(); f1.add(file1); f1.add(f3); f2.add(file2); f3.add(f2); f3.add(file3); f3.add(file4); f1.list(); //CompositePattern 27 file2.setname("file 2"); file3.setname("file 3"); file4.setname("file 4"); Folder 1 File 1 Folder 3 Folder 2 File 2 File 3 File 4 28

Designmönstret Model - Control Model--Control Designmönstret Model--Control (MVC) frikopplar (det grafiska) användargränssnittet från den underliggande modellen. MVC delar upp en applikation i tre olika typer av klasser: Model: Den datamodell som används en abstrakt representation av den information som bearbetas i programmet. Utgörs av de klasser som ansvarar för tillståndet i applikationen. : De klasser som ansvarar för att presentera modellen (som grafiska användargränssnitt). Genom att separera modellen och vyn kan förändringar göras i vyn och flera vyer skapas utan att behöva ändra koden i den underliggande modellen. Control: De klasser som handhar de händelsers som påverkar modellens tillstånd. Model När tillståndet i modellen förändras skall vyerna uppdateras, vi har alltså designmönstret Observer, mellan modellen och vyn. 29 Model--Control 30 MVC och Java Observable +addobserver Observer): #setchanged(): +notifyobservers(): klassen PropertyChangeSupport och +update(observable; Object): +modify(): ** När man implementerar MVC-modellen i Java rekommenderas (numera) att använda Observer ** interfacet PropertyChangeListener Model +somemethod(): +update( Observable; Object): istället för Observable och Observer. Flera andra varianter på MVC-mönstret är möjliga och finns beskrivna i litteraturen. 31 32

PropertyChangeSupport och PropertyChangeListener MVC och Java PropertyChangeListener Serializable I klassen PropertyChangeSupport finns bl.a följande metoder: +propertychange(propertychangeevent) IModel +addpropertychangelistener(...) +removepropertychangelistener(...) +modify(): addpropertychangelistener(propertychangelistener li) lägger till lyssnaren li java.beans.*; removepropertychangelistener(propertychangelistener li) Model implements IModel tar bort lyssnaren li final PropertyChangeSupport pcs = new PropertyChangeSupport(this); firepropertychange(string propertyname, Object oldvalue, Object newvalue) int degreecelsius; meddelar alla lyssnare att något har hänt genom att generera en händelse av typen PropertyChangeEvent. oldvalue och newvalue måste vara Model() olika för att verkligen skall genereras. degreecelsius = 0; I interfacet PropertyChangeListener finns endast en metod //constructor specificerad: addpropertychangelistener(propertychangelistener l) I design ovan är inte Model en subklass till PropertyChangeSupport, propertychange(propertychangeevent evt) utan istället har delegering används för att möjliggöra att Model skall Denna metod anropas när en PropertyChangeEvent inträffar. pcs.addpropertychangelistener(l); kunna ärva från någon annan klass. 33 //addpropertychangelistener removepropertychangelistener(propertychangelistener l) pcs.removepropertychangelistener(l); //removepropertychangelistener MVC ett enkelt exempel Modell: int getvalue() java.beans.*; return degreecelsius; Vi visar hur MVC-mönstret kan användas genom att skriva ett mycket Model implements IModel final PropertyChangeSupport pcs = new PropertyChangeSupport(this); enkelt program som konverterar temperaturer angivna i Celsius till Kelvin //getvalue int degreecelsius; respektive till Farenheit. Model() setvalue(int newvalue) degreecelsius = 0; //constructor int oldvalue = degreecelsius; addpropertychangelistener(propertychangelistener l) pcs.addpropertychangelistener(l); degreecelsius = newvalue; //addpropertychangelistener removepropertychangelistener(propertychangelistener l) pcs.firepropertychange("value", oldvalue, newvalue); pcs.removepropertychangelistener(l); //removepropertychangelistener IModell: //setvalue int getvalue() Avfyras endast om return degreecelsius; java.beans.*; //Model oldvalue!= newvalue //getvalue * abstract +propertychange(propertychangeevent) * Model Concrete -pcs: PropertyChangeSupport paintcomponent(graphic) +addpropertychangelistener(...) +removepropertychangelistener(...) //accessors PropertyChangeSupport +addpropertychangelistener(...) +removepropertychangelistener(...) +firepropertychange(...) //more methods java.io.*; interface IModel extends Serializable addpropertychangelistener(propertychangelistener l); removepropertychangelistener(propertychangelistener l); //IModel 34 setvalue(int newvalue) int oldvalue = degreecelsius; degreecelsius = newvalue; pcs.firepropertychange("value", oldvalue, newvalue); //setvalue //Model 35 36

: Konkreta vyer Kelvin: java.awt.*; javax.swing.*; java.beans.*; Kelvin extends JLabel k = new JLabel(); Kelvin(Model m) super(m); setpreferredsize(new Dimension(100,100)); k.setforeground(color.blue); setbackground(color.white); add(new JLabel("Kelvin: ")); add(k); //constructor propertychange(propertychangeevent e) double tok = model.getvalue()+273.15; k.settext(string.format("%.2f", tok)); //propertychange //Kelvin java.beans.*; javax.swing.*; abstract extends JPanel implements PropertyChangeListener protected Model model; (Model m) model = m; model.addpropertychangelistener(this); //setmodel java.awt.*; java.awt.*; javax.swing.*; java.beans.*; javax.swing.*; javax.swing.*; java.beans.*; javax.swing.*; java.beans.*; abstract propertychange(propertychangeevent e); java.awt.event.*; // Fahrenheit extends Kelvin extends abstract extends JPanel implements PropertyChangeListener extends JPanel implements ActionListener JLabel = new JLabel(); JLabel k model; =f new JLabel(); protected Model model; Model Fahrenheit(Model m) Kelvin(Model m) JTextField(5); (Model m) f = new JTextField super(m); model =super(m); m; setpreferredsize(new (Model Dimension(100,100)); m)37 setpreferredsize(new Dimension(100,100)); model.addpropertychangelistener(this); f.setforeground(color.blue); model = m; k.setforeground(color.blue); //setmodel setbackground(color.white); add(f); setbackground(color.white); add(new JLabel("Fahrenheit: abstract propertychange(propertychangeevent e); add(new JLabel("Kelvin: ")); ")); f.addactionlistener(this); add(f); // //constructor add(k); Konkreta vyer Farhenheit: : //constructor //constructor java.awt.*; actionperformed(actionevent e) propertychange(propertychangeevent javax.swing.*; propertychange(propertychangeevent e) e) javax.swing.*; java.beans.*; model.setvalue(integer.parseint(f.gettext())); java.awt.event.*; double tof = model.getvalue()*9.0/5.0+32; Fahrenheit extends = model.getvalue()+273.15; double tok extends JPanel implements ActionListener JLabel f = new JLabel(); //actionperformed Model model; f.settext(string.format("%.2f", tof)); Fahrenheit(Model m) k.settext(string.format("%.2f", tok)); JTextField f = new JTextField(5); super(m); //propertychange // setpreferredsize(new //propertychange Dimension(100,100)); (Model m) f.setforeground(color.blue); model = m; //Fahrenheit setbackground(color.white); //Kelvin add(f); add(new JLabel("Fahrenheit: ")); add(f); //constructor propertychange(propertychangeevent e) double tof = model.getvalue()*9.0/5.0+32; f.settext(string.format("%.2f", tof)); //propertychange //Fahrenheit 38 f.addactionlistener(this); //constructor actionperformed(actionevent e) model.setvalue(integer.parseint(f.gettext())); //actionperformed // 39 40

Hopkoppling av komponenterna: Designmönstret Bridge java.awt.*; javax.swing.*; MVCDemo extends JFrame MVCDemo() Model m = new Model(); kv = new Kelvin(m); fv = new Fahrenheit(m); c = new (m); setlayout(new FlowLayout()); add(c); add(kv); add(fv); pack(); setvisible(true); setdefaultcloseoperation(exit_on_close); //constructor static main(string[] arg) MVCDemo demo = new MVCDemo(); //main //MVCDemo Bridge Abstraction abstract #impl: Implementor Implementor abstract Vehicle java.awt.*; protected Engine engine; javax.swing.*; int weightinkilos; MVCDemo extends JFrame Vehicle(int weightinkilos, MVCDemo() Engine engine) this.weightinkilos weightinkilos; Model m ==new Model(); this.engine = engine; kv = new Kelvin(m); Att frigöra en abstraktion från sin implementering så att båda kan variera fv = new Fahrenheit(m); oberoende. abstract drive(); c = newengine) (m); 41 setengine(engine setlayout(new FlowLayout()); this.engine = engine; add(c); add(kv); reportonspeed(int horsepower) int ratioadd(fv); = weightinkilos / horsepower; Designmönstret Bridge Designmönstret Bridge if (ratio pack(); < 3) abstract Vehicle System.out.println("The speed."); setvisible(true); vehicle is going at a fast protected Engine engine; int weightinkilos; else if ((ratio >= 3) && (ratio <= 8)) setdefaultcloseoperation(exit_on_close); Vehicle(int weightinkilos, Engine engine) this.weightinkilos System.out.println("The vehicle is going an average speed."); = weightinkilos; //constructor this.engine = engine; else abstract drive(); static main(string[] arg) setengine(engine engine) System.out.println("The vehicle is going at a slow speed."); this.engine = engine; MVCDemo demo = new MVCDemo(); reportonspeed(int horsepower) //main int ratio = weightinkilos / horsepower; //Vehicle Med användning av if (ratio < 3) +implementation() +function() RefinedAbstractionA +function() ConcreteImplementorA ConcreteImplementorB +implementation() +implementation() RefinedAbstractionB +function() function() impl.implementation(); 42 Vehicle Car CarWithBigEngine Bus CarWithSmallEngine BusWithBigEngine BusWithSmallEngine //MVCDemo Vehicle abstract <<interface> Engine +drive(): +go(): designmönstret Bridge Car Bus SamllEngine BigEngine +drive(): +drive(): +go(): +go(): System.out.println("The vehicle is going at a fast speed."); else if ((ratio >= 3) && (ratio <= 8)) System.out.println("The vehicle is going an average speed."); else System.out.println("The vehicle is going at a slow speed."); //Vehicle 43 44

Designmönstret Bridge Designmönstret Bridge interface Engine int go(); //Engine SmallEngine implements Engine int horsepower; SmallEngine() horsepower = 100; int go() System.out.println("The small engine is running"); return horsepower; BigEngine implements Engine int horsepower; //SmallEngine BigEngine() horsepower = 350; int go() System.out.println("The big engine is running"); return horsepower; //BigEngine Car extends Vehicle Car(Engine engine) super(600, engine); drive() System.out.println("\nThe car is driving"); int horsepower = engine.go(); reportonspeed(horsepower); Bus extends Vehicle Bus(Engine engine) //Car super(3000, engine); drive() System.out.println("\nThe bus is driving"); int horsepower = engine.go(); reportonspeed(horsepower); //Bus interface Engine Car extends Vehicle int go(); BridgeDemo engine) //Engine Car(Engine static main(string[] args) SmallEngine implements Engine super(600, engine); Vehicle vehicle = new Bus(new SmallEngine()); int horsepower; vehicle.drive(); SmallEngine() vehicle.setengine(new BigEngine()); The bus is driving horsepower = 100; drive() vehicle.drive(); The small engine is running System.out.println("\nThe car is driving"); The vehicle is going at a slow speed. = engine.go(); int horsepower vehicle = new Car(new SmallEngine()); 45 int go() reportonspeed(horsepower); TheBus busextends is driving Vehicle vehicle.drive(); System.out.println("The small engine is running"); The big engine is running vehicle.setengine(new BigEngine()); Bus(Engine engine) return horsepower; The vehicle is going atengine a average super(3000, BigEngine implements speed. //Carvehicle.drive(); engine); int horsepower; Designmönstret Bridge //SmallEngine TheDesignmönstret caris driving Command BigEngine() //BridgeDemo The small engine horsepower = 350; drive() is running BridgeDemo static main(string[] args) The vehicle is going an average speed. Designmönstret Command kapslar in kommandon som objekt och låter System.out.println("\nThe bus is driving"); Vehicle vehicle = new Bus(new SmallEngine()); klienter få tillgång till olika uppsättningar med kommandon. vehicle.drive(); int horsepower = engine.go(); vehicle.setengine(new BigEngine()); The bus is driving The car is driving vehicle.drive(); The small engine is running go() The vehicle is going at a slow speed. int reportonspeed(horsepower); The big engine is running vehicle = new Car(new SmallEngine()); System.out.println("The big engine is running"); The bus is driving vehicle.drive(); The vehicle is going at a fast speed. The big engine is running vehicle.setengine(new BigEngine()); The vehicle is going at a average speed. return //Bus horsepower; vehicle.drive(); The car is driving //BridgeDemo The small engine is running The vehicle is going an average //BigEngine speed. Invoker Client 46 Command +execute(): <create> Receiver ConcreteCommand action() -receiver: Receiver +execute(): The car is driving The big engine is running The vehicle is going at a fast speed. receiver.action() 47 48

Designmönstret Command //Command interface Order abstract execute ( ); //Order Designmönstret Command // Invoker. Agent Agent() placeorder(order order) order.execute(); //placeorder //Agent SubsystemA String A1() // Receiver.return "Subsystem A, Method A1\n"; StockTrade buy() System.out.println("You want to buy stocks"); //buy String A2() sell() return want "Subsystem System.out.println("You to sell stocks "); A, Method A2\n"; //sell //StockTrade SubsystemB String B1() return "Subsystem B, Method B1\n"; Designmönstret Façade Designmönstret Façade används för att dölja komplexitet för användarna. SubsystemC lättare att använda fasaden än det ursprungliga systemet String C1() kan byta implementation av det som fasaden gömmer return "Subsystem C, Method mindre beroenden C1\n"; Client -facade: Facade Libary SubsystemA Facade SubsystemB -a: SubsystemA -b: SybsystemB -c: SubsystemC //ConcreteCommand. BuyStockOrder implements Order StockTrade stock; BuyStockOrder(StockTrade st) stock = st; //constructor execute( ) stock.buy( ); //execute //BuyStockOrder //ConcreteCommand. SellStockOrder implements Order StockTrade stock; SellStockOrder(StockTrade st) stock = st; //constructor execute( ) stock.sell( ); //execute //SellStockOrder Facade SubsystemA a = new SubsystemA(); // Client SubsystemB b = new SubsystemB(); Client main(string[] args) SubsystemC c =static new SubsystemC(); StockTrade stock = new StockTrade(); BuyStockOrder operation1() bsc = new BuyStockOrder (stock); SellStockOrder ssc = new SellStockOrder (stock); Agent agent = new Agent(); System.out.println("Operation 1\n" + agent.placeorder(bsc); // Buy Shares agent.placeorder(ssc); + a.a1() // Sell Shares //main //Client + a.a2() 49 + b.b1()); operation2() System.out.println("Operation 2\n" Designmönstret Façade + b.b1() + c.c1()); SubsystemA String A1() Facade return "Subsystem A, Method A1\n"; SubsystemA a = new SubsystemA(); Client SubsystemB b = new SubsystemB(); String A2() SubsystemC static main (String[] arg)c= new SubsystemC(); return "Subsystem A, Method A2\n"; operation1() Facade facade = new Facade(); System.out.println("Operation 1\n" + + a.a1() + a.a2() facade.operation1(); SubsystemB + b.b1()); String B1() facade.operation2(); return "Subsystem B, Method B1\n"; operation2() System.out.println("Operation 2\n" + b.b1() + c.c1()); SubsystemC String C1() return "Subsystem C, Method C1\n"; +operation1() +operation2() SubsystemC 51 50 Client static main (String[] arg) Facade facade = new Facade(); facade.operation1(); facade.operation2(); 52