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

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

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

Observer Pa*ern och MVC. Objekt-orienterad programmering och design Alex Gerdes, 2018

Model View Controller. Objekt-orienterad programmering och design (DIT952) Niklas Broberg, 2016

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

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

Generics och polymorfism. Objekt-orienterad programmering och design (DIT953) Niklas Broberg / Johannes Åman Pohjola, 2018

Separation of Concern. Objekt-orienterad programmering och design (DIT953) Niklas Broberg / Johannes Åman Pohjola, 2018

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

Static vs Dynamic binding Polymorfism. Objekt-orienterad programmering och design (DIT953) Niklas Broberg, 2018

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

Mutability och State. Objekt-orienterad programmering och design (DIT953) Niklas Broberg / Johannes Åman Pohjola, 2018

Principles of subclasses Objekt-orienterad programmering och design (DIT953) Niklas Broberg, 2018

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

Principles of subclasses. Objekt-orienterad programmering och design Alex Gerdes, 2018

Separation of Concern. Objekt-orienterad programmering och design (DIT952) Niklas Broberg, 2016 Johannes Åman Pohjola, 2017

Design och konstruktion av grafiska gränssnitt

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

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

DAT043 - Föreläsning 7

Static vs Dynamic binding Polymorfism. Objekt-orienterad programmering och design Alex Gerdes, 2016

Lösningar till tentamen i EDAF25

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

Objektorienterad Programkonstruktion. Föreläsning 6 23 nov 2015

Classes och Interfaces, Objects och References, Initialization

Objektorienterad programmering med Java Swing: Händelser, lyssnare och applets

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

Objekt-orienterat vs funktionellt Objekt-orienterad programmering och design (DIT952) Niklas Broberg, 2016

Design och konstruktion av grafiska gränssnitt

Objekt-orienterad programmering och design. DIT953 Niklas Broberg, 2018

Modulär design. Objekt-orienterad programmering och design (DIT953) Niklas Broberg / Johannes Åman Pohjola, 2018

Designmönster/Design patterns

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

Classes och Interfaces, Objects och References Objekt-orienterad programmering och design (DIT952) Niklas Broberg, 2016

Design Patterns. Objekt-orienterad programmering och design Alex Gerdes, 2016

Objekt-orienterat vs funktionellt Objekt-orienterad programmering och design (DIT952) Niklas Broberg, 2017

DVGB05 Grafiska användargränssnitt. Mjukvarudesign med Model-View-Controller

Tentamen i Objektorienterad modellering och design

Principer, Patterns och Tekniker. Objekt-orienterad programmering och design (DIT953) Niklas Broberg / Johannes Åman Pohjola, 2018

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

Objektorienterad Programkonstruktion. Föreläsning jan 2016

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

TDDC30 Programmering i Java, Datastrukturer och Algoritmer Lektion 5. Laboration 4 Lådplanering Exempel på grafik, ett avancerat program Frågor

Programutvecklingsprojekt Projektgrupp Elvin. Detailed Design Document

Lab5 för prgmedcl04 Grafik

" «Observable» DataGenerator" betyder att klassen DataGenerator ärver från den abstrakta klassen Observable.

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

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

Fönstersystem. Objektorientering och händelsebaserad programmering. Applikation. Interaktionstoolkit. Händelsehanterare och grafiktoolkit

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

Lösningar till tentamen i EDAF25

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

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

Objekt-orienterat vs funktionellt Objekt-orienterad programmering och design (DIT953) Niklas Broberg, 2018

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

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

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

Tentamen i Objektorienterad programmering

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

Sammanfattning och Tentamensinfo Objekt-orienterad programmering och design (DIT953) Niklas Broberg, 2018

Projekt 2 XL. Observer-mönstret

Högskolan Dalarna sid 1 av 7 DI-institutionen Hans-Edy Mårtensson Sten Sundin

Principer, Patterns och Tekniker. Objekt-orienterad programmering och design (DIT952) Niklas Broberg, 2016

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

Objektorienterad Programkonstruktion, DD1346. Tentamen , kl

Swing. MER Java Foundation Classes (JFC) Hur lära sig? Vad är farorna. LayoutManagers. Exempel på några av komponenterna

Vad utmärker ett bra gränssnitt?

Swing. MER Java Foundation Classes (JFC) Vad är farorna. Hur lära sig? LayoutManagers. Exempel på några av komponenterna

UML Objektdiagram. Objektorienterad modellering och design (EDAF25) Föreläsning 3. UML Sekvensdiagram. UML Objektdiagram. Agenda

Föreläsning 15 (16) Historik (java.awt) Historik (javax.swing) Introduktion till Swing

Windows Forms Winstrand Development

Modulär design Objekt-orienterad programmering och design (DIT952) Niklas Broberg, 2016

Kort om klasser och objekt En introduktion till GUI-programmering i Java

Principer, Pa+erns och Tekniker. Objekt-orienterad programmering och design Alex Gerdes, 2018

Spelet i sig är inte avancerat men projektet ställer en del krav på implementationen bland annat:

Dependencies High cohesion, low coupling. Objekt-orienterad programmering och design Alex Gerdes, 2018

GUI-programmering. Gustav Taxén Martin Berglund DH2640 Grafik och Interaktionsprogrammering VT 2008

TDDC30 Programmering i Java, Datastrukturer och Algoritmer Lektion 3

Computer projekttid. Objektorienterad modellering och diskreta strukturer / design. Rapporter från verkligheten. EDAF10 i HT2

Vad utmärker ett bra användargränssnitt?

Objekt-orienterad Programmering och Design. TDA551 Alex Gerdes, HT-2016

Översikt Föreläsning 1. Trivicalc. Vad är trivicalc? En cell. Områden på skärmen. SMD168/SMD135 Fredrik Bengtsson

Det här dokumentet är till för att ge en översikt över ASP.NET MVC samt hur WCF Services används från.net applikationer.

Java: Utvecklingsverktyg, datatyper, kontrollstrukturer

Laboration 2: Designmönster

Javas Exceptions. DD2385 Programutvecklingsteknik Fler bilder till föreläsning 7 23/ Kort om Javas Exceptions Trådar i Java

Tentamen i Objektorienterad modellering och design Helsingborg

Laboration 3 GUI-programmering

Objekt-orienterad Programmering och Design. TDA552 Alex Gerdes, HT-2018

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

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

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

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

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

Lambdas. (och fler design patterns) Objekt-orienterad programmering och design (DIT952) Niklas Broberg, 2017

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

Lektion Händelsehanterare

Objektorienterad programmering

Objektorienterad Programmering (TDDC77)

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

Transkript:

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

Model View Controller Model View Controller (MVC) är ett design pattern (architectural pattern) som är väldigt vanligt förekommande för alla typer av program som innehåller någon form av grafisk representation. Grunden i MVC är att vi separerar: Koden för data-modellen (M) från användargränssnitt (V och C). Detta är den viktigaste uppdelningen. Inom användargränssnitt skiljer vi koden som visar upp (delar av) modellen för användaren (V) från koden som hanterar input från användaren (C).

Model Modellen (Model) är en representation av den domän som programmet arbetar över helt oberoende av användargränssnitt. Data, tillstånd, domänlogik. Modellen i singular vi har inte flera modeller för samma domän. Modellen kan dock internt bestå av flera olika delar som representerar olika aspekter av domänen (dvs ingen duplicering). Tumregel för avgränsning från V och C: Tänk The whole model and nothing but the model. Ska kunna presenteras för och kontrolleras av användaren på olika sett e.g. med 2D-grafik eller text utan att valet i sig påverkar e.g. modellens tillstånd. Nothing but the model Ska innehålla allt det som vore detsamma oavsett hur modellen presenteras eller kontrolleras. Ingenting ska behöva dupliceras mellan olika vy- eller kontroll-komponenter. The whole model

View En vy (View) presenterar (delar av) modellen för användaren. Olika tänkbara format: Text, grafik (2D, 3D, ), ljud, haptik, Vi pratar om vy, oavsett vilket format presentationen görs på. Vi kan ha många olika vyer (ofta samtidigt) för en och samma modell. Olika vyer kan visa upp olika aspekter av modellen. E.g. karta, inventory, synfält för ett dataspel. Olika vyer kan visa upp samma aspekt på olika format E.g. musik spelas upp, och visas samtidigt grafiskt som frekvens-amplitud-diagram. Allt i användargränssnittet är inte vy(er), även om det är saker som syns!

Controller En Controller styr modell och vy(er) utifrån input från användaren. Vi kan ha många controllers som styr olika aspekter av både modell och vy. Olika varianter av MVC använder controllers lite olika: alltifrån en enskild controller som styr alla aspekter av modell och vyer, till många separata controllers för varje del-vy. De flesta moderna grafik-gränssnitt (som Java Swing) innehåller stöd för att förenkla för controllers att hantera användar-inputs genom events och event listeners. En rent passiv applikation innehåller ingen controller!

Smart, Dumb, Thin Tumregel: SMART models, DUMB views, THIN controllers All domänlogik ska ligga i modellen därav SMART. En view ska inte göra egna beräkningar, bara visa utifrån direktiv därav DUMB. En controller ska enbart hantera yttre input, dvs (oftast) input från användare. Den ska bara vara ett tunt lager mellan användare och program därav THIN. Yttre input måste inte vara från användare direkt; det kan komma e.g. via nätverkskommunikation, från avläsning av sensorer, etc. Detta är vad vi strävar efter. Det är dock inte alltid helt självklart vad som bör ligga var.

View: Visar upp en del av världen View: Listar info om karaktärer i modellen Fler views View: Visar en logg över händelser

Controller: Interaktion med saker i världen Controller: Interagerar med karaktärer Fler Fler controllers views Controller: Får saker att hända

Var går gränsen? Ponera en grafisk widget som visar information från modellen. går att klicka på så att saker händer. Controller eller vy? Svar: Som regel lite av båda (men går att göra undantag): Själva widgeten (e.g. JPanel) är rimligen (en del av koden för) en vy. Widgeten/vyn kan hantera att och hur användaren interagerar med den men inte vad som ska hända som effekt av detta. Koden som avgör vad som ska hända hör till en controller.

Var går gränsen? Ponera en grafisk widget som inte visar information från modellen. går att klicka på så att saker händer. Controller eller vy? Pilarna är ren input påverkar vad som visas i vyn bredvid. Svar: Man kan resonera olika men är etiketterna verkligen viktiga? Det finns inget som säger att en Controller inte får ha en grafisk representation. Är detta då en vy som visar up controllern (istället för modellen som brukligt)? Eller är det en del av controllern? Who cares! Det viktiga är att förstå principerna för att separera koden för de olika delarna.

Applikation Alla applikationer har en main -metod som går att exekvera. Denna hör inte till någon av MVC, utan ligger separat ( A ). Applikationen skapar, sammanför, och startar de olika komponenter som tillsammans ska utföra jobbet. Flera olika applikationer kan använda sig av samma sorts komponenter, e.g. polygoner. Kan vara mer eller mindre avancerad, beroende på hur mycket som behöver konfigureras. Fönsterhanteringen på toppnivå kan ligga här. All data som är applikationsspecifik kan ligga här. (Ibland (som undantag) är det relevant att lägga viss applikationslogik här, istället för i M. E.g. i en simulering, hör tiden hemma i modellen, eller kan olika applikationer välja att hantera tiden olika?)

Hur bör M, V och C (och A) hänga ihop? Vilka beroenden bör vi ha? M får inte bero av V eller C. Punkt. Världen är vad den är, oavsett hur den presenteras eller styrs. Får V bero av M? Får V bero av C? Får C bero av M och/eller V? Svar: Det beror på Olika varianter kan vara relevanta i olika sammanhang. Lyssna inte på de som säger sig ha hittat den enda sanningen. Tumregel: Gör det som leder till högst cohesion och lägst coupling! A väljer vilka delar av M, V och C som ska utgöra programmet. Slutsats: A beror nästan alltid på samtliga delar. Om inte har du verkligen rätt uppdelning av M, V och C? A representerar ett topp-nivå-program inget ska någonsin bero på A!

Live code Signal

JPanel + paint(graphics) : void JFrame + paint(graphics) : void Speed <<enum>> SUPERFAST FAST NORMAL SLOW SUPERSLOW + up(): Speed + down() : Speed Signal - status : SignalStatus - speed : Speed - view : SignalView + run() : void + speedup() : void + slowdown() : void SignalApp + main(string[]) : void SignalView + update(signalstatus) : void SignalStatus <<enum>> RED TOGREEN GREEN TORED + next(): SignalStatus

Signal - status : SignalStatus - speed : Speed - view : SignalView + run() : void + speedup() : void + slowdown() : void SignalView + update(signalstatus) : void SignalApp + main(string[]) : void

Hur vänder vi på beroenden? Vi har ett dilemma. Om M inte får bero av V hur ska då V få veta när den ska uppdateras? Alternativ 1: V frågar M regelbundet ( polling ), och ritar ut status. Fungerar bra om M uppdateras ofta och mycket. Ex realtidsspel. Fungerar dåligt om M uppdateras sällan eller lite. Ex ritprogram. Alternativ 2: C uppdaterar både M och V samtidigt. Fungerar bra om M enbart uppdateras på grund av användarinput. Ex ritprogram. Fungerar dåligt om M uppdateras oberoende av användaren. Ex realtidsspel. Alternativ 3: M är smart, och meddelar alla förändringar högt, utan att veta vem (om någon) som lyssnar. OCP med hjälp av abstraktion.

Live code Signal

Signal - status : SignalStatus - speed : Speed - view : SignalObserver + run() : void + speedup() : void + slowdown() : void - notifystatuschange() : void SignalObserver <<interface>> + actonsignalchange(signalstatus) : void SignalView + actonsignalchange(signalstatus) : void SignalApp + main(string[]) : void

:Signal :SignalView Vårt Signal object kommunicerar direkt med ett SignalView object, som det känner till.

:Signal :SignalView Vårt Signal object kommunicerar indirekt med ett SignalView object, som det vet existerar men inte vad det är.

Multicasting Att tillåta många observers kallas ibland för multicasting information om events skickas till multiple klienter. Att möjliggöra multicasting per default är en bra princip. Väldigt låg kostnad om det bara utnyttjas av en klient. Följer automatiskt OCP: vi kan lätt lägga till fler klienter utan att modifiera koden. Kan dock hanteras separat, med hjälp av Composite Pattern (Hem-quiz: hur?)

Live code SignalLogger

Signal - status : SignalStatus - speed : Speed - view : SignalObserver + run() : void + speedup() : void - slowdown() : void - notifystatuschange() : void SignalObserver <<interface>> + actonsignalchange(signalstatus) : void SignalApp + main(string[]) : void SignalLogger + actonsignalchange(signalstatus) : void SignalView + actonsignalchange(signalstatus) : void

:Signal :SignalView :SignalLogger Vårt Signal object kommunicerar indirekt med alla lyssnare, och bryr sig inte alls om vilka de är eller (viktigt) ens om de finns.

Observer Pattern When an object needs to notify other objects of events, without directly depending on them: broadcast the events on an open channel, to which any interested object may register. DIP: Definiera ett interface enligt vilket objektet kommer att broadcasta sina events, och låt vem som vill implementera detta interface och registrera sig för att lyssna. Den som lyssnar kallas observer; den som skickar events kallas observable.

Observer Pattern Observer <<interface>> + notify( ) : void Observable - observers : List<Observer> + addobserver(observer) : void + removeobserver(observer) : void - notifyobservers() : void ExternalClient class ExternalClient implements Observer { public ExternalClient(Observable t){ t.addobserver(this); } } public void notify(){ // Do something clever on callback } private void notifyobservers{ for (Observer o : observers) o.notify; }

Observer Pattern i Signal SignalObserver <<interface>> + actonsignalchange(signalstatus) : void Signal - observers : List<SignalObserver> + addobserver(signalobserver) : void + removeobserver(signalobserver) : void - notifystatuschange(signalstatus) : void SignalView class SignalView implements SignalObserver { public SignalView(Signal signal){ signal.addobserver(this); } } public void actonsignalchange(signalstatus status){ // Do something clever with new status } private void notifystatuschange(signalstatus status) { for (SignalObserver o : observers) o.actonsignalchange(status); }

Observer pattern i Swing Hela Java Swing är uppbyggt med hjälp av Observer Pattern; observers kallas Event Listeners. Alla grafiska komponenter widgets vi ritar ut med Swing kan registrera och avfyra olika events, och tar emot observers för dessa. E.g. ActionListener, MouseListener, MouseWheelListener, FocusListener, Samma princip går igen i de flesta moderna GUI-bibliotek.

Aside: Observer Pattern i Java I Java finns interfacen java.util.observer och java.util.observable, med de metoder vi diskuterat. Dessa är dock så väldigt enkla att implementera själv, och vinsten med polymorfism mellan olika användningsfall är noll. Dessutom vill vi nästan alltid vara mer specifika, e.g.: Vilka events flaggas för, med vilka argument? Flaggas flera olika sorters events? Kan man registrera sig som observer för bara ett, eller alla? Mer konkreta namn än e.g. notify på metoderna hjälper läsförståelsen. Slutsats: Definiera som regel egna varianter för era observers och observables. (Java (i JavaBeans) har också java.beans.propertychangelistener m.m.. Dessa gör det möjligt att lyssna på property changes, där en property är ett internt attribut med getters och setters. Fördelen här är att e.g. NetBeans (en IDE) kan automatiskt generera kod för Observer Pattern. Jag går inte in på det vidare.)

Aside: Event-driven programming Event-driven programming brukar kallas för en paradigm, dvs ett sätt att på topp-nivå strukturera program. GUI-bibliotek som Swing sägs vara instanser av event-driven programming. Vanligt vid låg-nivå-programmering, t ex operativsystem, där man hela tiden lyssnar efter olika hardware interrupts. I grunden går event-driven programming ut på att använda Observer Pattern för hela system.

Live code SpeedController

SpeedController - signal : Signal + actionperformed(actionevent e) : void Signal - status : SignalStatus - speed : Speed - view : SignalObserver + run() : void + speedup() : void - slowdown() : void SignalObserver <<interface>> + actonsignalchange(signalstatus) : void SignalApp + main(string[]) : void SignalLogger + actonsignalchange(signalstatus) : void SignalView + actonsignalchange(signalstatus) : void

:SignalView :SpeedController :Signal :SignalLogger Vår SpeedController styr vårt Signal object med direkt kommunikation.

Vi har en Controller Allt innanför den lila linjen är vår Model SpeedController - signal : Signal + actionperformed(actionevent e) : void Signal - status : SignalStatus - speed : Speed - view : SignalObserver + run() : void + speedup() : void - slowdown() : void SignalObserver <<interface>> + actonsignalchange(signalstatus) : void SignalApp + main(string[]) : void SignalLogger + actonsignalchange(signalstatus) : void SignalView + actonsignalchange(signalstatus) : void SignalApp tillhör varken M, V eller C - den bara initierar dessa. Den representerar applikationen. och Vi har två en olika Controller Views.

Live code Add second Signal

:SignalView :SpeedController :Signal :SignalLogger Views och Controllers behöver inte vara kopplade till hela modellen. Vi kan ha flera olika controllers och views för olika delar av modellen, ibland överlappande. :Signal

Översikt SignalApp En modell (M) som inte beror på något annat men som är kodad med Observer Pattern (OCP!), i förväntningen att det kan komma komponenter som vill veta när den uppdateras. Flera olika vyer (V) som beror av M. Beror enbart på SignalStatus (A lägger till V som SignalObserver) En controller (C) som enbart beror av M men som har en grafisk widget. OBS: SpeedController kan med fördel delas upp i e.g. SpeedControlWidget (som är en dum frame med knappar) och SpeedController (som lägger till sig som observer hos SpeedControlWidget och hanterar knapptryckningarna). (Hem-uppgift) Vi kan lätt lägga till fler controllers, som beror (enbart) på de delar av M och/eller V som de uppdaterar, eller triggas av. En applikation (A) som skapar, sammanför och startar alla komponenter.

Slutsatser Förstå principerna för varför MVC ser ut som det gör. Extensibility, reusability, maintainability. Förstå vad som leder till reduktion av beroenden. Förstå Observer Pattern och hur det hjälper till att minska beroenden. Av samtliga designmönster vi kommer gå igenom är Observer Pattern det viktigaste att förstå. Arbeta med den struktur som ger högst cohesion och lägst coupling. Vilka beroenden som finns mellan M, V och C kan variera gör ett medvetet och initierat val! förutom att M aldrig ska bero på V och C. Punkt.

What s next Block 6-1: State och Immutability

Quiz: Design pattern? Define an object that encapsulates how other objects communicate. Definiera ett objekt som representerar och hanterar kommunikationen mellan andra objekt. Andra objekt kommunicerar aldrig direkt med varandra, utan bara via detta objekt. Svar: Mediator Pattern

Mediator Pattern Define an object that encapsulates how other objects communicate. Genom att definiera en Mediator som hanterar kommunikationen har vi åstadkommit lösare koppling (low coupling) mellan de kommunicerande objekten. Dessa kan nu varieras helt separat från varandra, och alla förändringar av dessa kan som mest påverka vår Mediator. (Vissa definierar Mediator Pattern snävare, och kräver att Mediator-objektet också känner till och aktivt styr de kommunicerande objekten (dvs inga observers). Jag använder den vidare beskrivningen.)

Publish-Subscribe Pattern Define an object that presents passive communication channels that other object may send and listen to. Publish-Subscribe Pattern (kallas även Pubsub) är en specifik form av Mediator Pattern, där Mediator-objektet är helt passivt, och inte bryr sig om vem som lyssnar. Det tillhandahåller ett gränssnitt för att skicka information på olika kanaler, och ett gränssnitt för att registrera sig för att lyssna (Observer Pattern) på olika kanaler, och skickar sen bara vidare inkommande meddelanden till alla registrerade lyssnare.

Quiz: Vems är ansvaret? Antag att vi har en applikation som är en musikspelare. I modellen håller vi reda på nuvarande inställning för volym, som en int. Vi har en vy som faktiskt spelar upp musiken (detta är fortfarande en View, även om den inte är grafisk utan ljud), som sätter volymen efter inställningen. Vi har en annan vy som grafiskt visar volyminställningen för användaren, med knappar för att öka eller minska värdet på volymen. Vi har en controller som hanterar input från volym-visarens knappar och uppdaterar modellen. Antag vidare att vi vill varna användaren när volymen är över 12, genom att e.g. göra bakgrunden på volymvisaren röd. I vilken av de fyra komponenterna bör koden ligga som kontrollerar om volymens värde överstiger 12, och agerar på detta?

Om ni svarade Model: Siffran 12 för volymen säger ingenting i domänen, olika ljud- vyer kan välja att tolka siffran på olika sätt. View (volymvisare): Vi strävar efter DUMB views, så inga beräkningar bör göras här. View (ljud): Vyer ska vara oberoende av varandra, så denna vy kan inte kontrollera den andra. Controller: Vi strävar efter THIN controllers, som bara hanterar input och uppdaterar modellen därefter. Beslutet att sätta volymen över 12 kanske inte ens kommer ifrån användaren, eller via en annan controller, eller

Model View Presenter Ett modernt alternativ till (eller variant av) MVC kallas MVP, där: Model (M) fungerar precis som i MVC, dvs data och domänlogik. View (V) gör det som V i MVC gör, men vi tar också hänsyn till att mycket av hanteringen av användar-input faktiskt sker via widgets, så (i vissa varianter) även mycket av det C i MVC gör (de bitar som direkt uppdaterar modellen). Presenter (P) sköter all presentations- och applikationslogik. Den tar emot en del input från V (kan ev välja själv via Observer Pattern vad den vill lyssna på), och står för mer avancerade beräkningar och uppdateringar i modellen. Den är också ansvarig för alla beräkningar som styr hur presentationen ska ske. I en specifik variant kallad Passive View MVP går all kommunikation genom P, och V och M kommunicerar aldrig med varandra.