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