Varför designmönster?
Varför designmönster?
Varför designmönster?
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
2D1362: 2003 Designmönster<br />
previous<br />
next<br />
Innehåll<br />
Återanvändning<br />
Designmönster<br />
Problem<br />
Bakgrund<br />
Lösning<br />
Exempel<br />
Projektkursen 2003<br />
Designmönster<br />
Sammanfattning och slutsatser<br />
Återanvändning<br />
Designmönster<br />
• I alla tider har man försökt att återanvända och applicera<br />
känd kunskap och metoder på nya domäner<br />
– Till stora delar lär vi genom att härma och efterlikna<br />
• Vad kan återanvändas och hur?<br />
• <strong>Varför</strong> återanvända?<br />
• <strong>Varför</strong> är det svårt att återanvända?<br />
previous next 2<br />
1
2D1362: 2003 Designmönster<br />
...<br />
• Vad kan återanvändas och hur?<br />
– Arkitektur, tex frameworks<br />
Designmönster<br />
previous next 3<br />
...<br />
– Kod, tex komponenter<br />
– Design, tex lösningstekniker<br />
– Dokumentation, tex delar av manualer<br />
– Test, bla vissa standardtester<br />
– Metodiker, tex arbetssätt och organisation<br />
• <strong>Varför</strong> återanvända?<br />
–Vi spar tid<br />
– Mer tillförlitliga och uttestade produkter<br />
– Kortare tid från idé till produkt<br />
Designmönster<br />
– Utvecklare kan koncentrera sig mer på modulär design, vilket<br />
förenklar underhåll och liknande<br />
– Utvecklare behöver spendera mindre tid på rutinarbete och<br />
kan fundera mer på övergripande design, kundkrav, osv<br />
previous next 4<br />
2
2D1362: 2003 Designmönster<br />
Designmönster<br />
...<br />
• <strong>Varför</strong> är det svårt att återanvända?<br />
– Svårt att hitta i allt större bibliotek av komponenter<br />
(/lösningar) samt förstå hur en viss komponent skall kunna<br />
användas<br />
– Inte alltid helt klart vad en viss komponent eller modul gör<br />
– Inte säkert att en viss komponent (eller lösning) direkt går att<br />
applicera i den aktuella situationen. Smärre ändringar kan<br />
krävas<br />
– NIH-syndromet (Not Invented Here). Kan vi lita på någon<br />
annans komponent (/lösning). Ska vi inte göra det själva...<br />
previous next 5<br />
Designmönster<br />
Design Patterns: Problem<br />
• Hur kan vi dokumentera designlösningar på ett så lättillgängligt<br />
och överskådligt sätt som möjligt?<br />
• Hur kan vi återanvända tidigare gjorda lösningar och<br />
konstruktioner?<br />
• Hur kan experter dokumentera sina kunskaper på en form som är<br />
tillgänglig även för folk utanför deras "kunskapsdomän"?<br />
• Hur kan vi beskriva principer för en lösning istället för detaljer,<br />
så att den blir så oberoende av den aktuella kontexten som<br />
möjligt?<br />
• Hur kan vi skapa en kraftfull vokabulär för våra designlösningar?<br />
previous next 6<br />
3
2D1362: 2003 Designmönster<br />
Bakgrund och omgivning<br />
Designmönster<br />
• Som många andra komplexa strukturer skapas bra mjukvara ofta<br />
genom att imitera program som löser liknande problem på ett bra<br />
sätt (se tex [Ker] Kernighan, B. and Plauger, P.J. The Elements of<br />
Programming Style)<br />
• Vi behöver bra mekanismer att beskriva design- och<br />
mjukvarulösningar<br />
– Det går inte att beskriva övergripande, generella, lösningar på ett<br />
formalistiskt sätt<br />
• Det finns också ett behov av att sätta namn på konstruktioner så<br />
att vi får ett kraftfullare språk då vi diskuterar design<br />
previous next 7<br />
Krafter<br />
Designmönster<br />
• Vi önskar ett begripligt och lättillgängligt språk som är enkelt att<br />
lära sig.<br />
• Vi önskar namnge designlösningar så att vi får ett kraftfullt språk<br />
att diskutera olika möjligheter och konstruktioner.<br />
• Beskrivningarna måste vara så pass kraftfulla att vi kan uttrycka<br />
det vi vill.<br />
• Vi önskar lösningar som går att applicera på olika situationer.<br />
• Det skall vara möjligt att läsa delar av en beskrivning för att<br />
snabbt avgöra om den är av intresse i den aktuella situationen.<br />
• Vi vill ge den som beskriver en design frihet att anpassa<br />
beskrivningen till dom aktuella (specifika) behoven.<br />
• Det skall vara roligt att både läsa och skriva beskrivningar.<br />
previous next 8<br />
4
2D1362: 2003 Designmönster<br />
Designmönster<br />
Lösning<br />
• Beskriv en lösning på en standardiserad form<br />
• Utgå från en mall med följande rubriker:<br />
Namn<br />
ett så förklarande namn som möjligt<br />
Problem<br />
formulering av det problem som mönstret avser att lösa<br />
Kontext<br />
den omgivning med påverkande krafter i vilken mönstret skall verka<br />
Lösning<br />
en beskrivning av den design som löser problemet<br />
• Fler rubriker kan användas vid behov<br />
• Detta gör beskrivningen lättillgänglig och standardiserad (samt<br />
igenkännbar)<br />
• Den som läser kan läsa en delbeskrivning för att snabbt undersöka<br />
den aktuella designens avsikt och tillämpbarhet<br />
previous next 9<br />
Designmönster<br />
Exempel (kort-kort för att få plats på en sida)<br />
Namn<br />
Konstruera ett stort datorsystem (enligt traditionell metodik a la RUP)<br />
Problem<br />
Hur bör vi gå tillväga då vi konstruerar ett stort datorsystem med många<br />
inblandade utvecklare?<br />
Kontext<br />
Överensstämmelse med krav. Oberoende av nyckelpersoner. Spårbarhet.<br />
Anpassat för förändring. Dokumentation som kan valideras mot kund.<br />
Lösning<br />
1. Börja med att utgående från kravspecifikationen identifiera aktörer, upprätta<br />
användningsfall samt beskriva dem i textuell form (scenarier)<br />
2. Analysera systemet. Återgå vid behov till 1 och komplettera användningsfallen.<br />
3. Designa systemet. Återgå vid behov till 2 (och därmed kanske till 1).<br />
4. Konstruera systemet.<br />
5. Testa systemet. Iterera 1-5 tills systemet är klart.<br />
previous next 10<br />
5
2D1362: 2003 Designmönster<br />
Konsekvenser<br />
Designmönster<br />
+ Vi kan dokumentera designlösningar på ett lättillgängligt och överskådligt sätt.<br />
+ Vi kan återanvända tidigare gjorda lösningar och konstruktioner.<br />
+ Experter kan dokumentera sina kunskaper på en form som är tillgänglig även<br />
för folk utanför deras "kunskapsdomän”.<br />
+ Vi beskriver principer för en lösning istället för detaljer.<br />
+ Vi skapar en kraftfull vokabulär så att vi enkelt kan diskutera olika lösningar.<br />
− Risk att vi inte kritiskt granskar alla delar i en design, utan litar på att allt är<br />
frid och fröjd bara ett <strong>designmönster</strong> används.<br />
− Att många olika beskrivningar av egentligen synonyma mönster börjar florera<br />
(vilket kan skapa förvirring).<br />
± Friheten att justera mönsterbeskrivningarna efter aktuella behov gör dom<br />
anpassningsbara. Men samtidigt ökar risken att många format florerar, viken<br />
kan göra det en aning svårare att tränga in i en viss beskrivning<br />
previous next 11<br />
Historik<br />
• Bakgrund<br />
– Under 60-talet utvecklades automatiserad och datoriserad<br />
konstruktion av byggnader<br />
• arkitekter försökte rationalisera<br />
• man försökte separera design från produktion<br />
• detta hade stora fördelar gentemot traditionell "omedveten" design<br />
Designmönster<br />
• Christopher Alexander (idag professor i Arkitektur på Berkely)<br />
– Ändå noterade många att traditionellt konstruerade "saker" var<br />
bättre i fråga om kvalitet, användbarhet och anpassbarhet<br />
• Arkitekten Christopher Alexander försökte fånga varför och vad som var<br />
mer tilltalande i vissa byggnader än andra<br />
• han fann vissa återkommande teman<br />
• han konstruerade ett systematiskt sätt att dokumentera dessa mönster:<br />
<strong>designmönster</strong> (eng. design patterns)<br />
previous next 12<br />
6
2D1362: 2003 Designmönster<br />
... Alexander ...<br />
Designmönster<br />
– Som Alexander utrycker det i boken "A Pattern Language" (som består av 253<br />
mönster som beskriver allt ifrån hur gatunätet i städer bör utformas till hur<br />
rum bör inredas för att bli trivsamma, plus mycket mycket mer)<br />
"Each pattern describes a problem which occurs over and over again in<br />
our environment, and then describes the core of the solution to that<br />
problem, in such a way that you can use this solution a million times<br />
over, without ever doing it the same twice"<br />
Christopher Alexander 1977<br />
• Beck & Cunningham (samma par som också ligger bakom CRC-kort)<br />
– Började i mitten av 80-talet använda <strong>designmönster</strong> för att lära ut<br />
objektorientering och Smalltalkprogrammering<br />
• Även andra forskare inom datalogi diskuterade <strong>designmönster</strong> och<br />
relaterade till Alexander redan på 80-talet<br />
previous next 13<br />
Designmönster<br />
... MVC (Model-View-Controller) ...<br />
• En av dom största inspirationskällorna och ett exempel på<br />
ett mycket framgångsrikt mönster är MVC<br />
– Idén är att separera applikationslogik (model) från<br />
visualiseringen (view) och interaktionen (controller) med<br />
densamma<br />
– Konstruerades under andra hälften av 70-talet då en<br />
interaktionsmodell och ett framework för konstruktion av<br />
interaktiva användargränssnitt i Smalltalk skapades<br />
M<br />
Presenterar Interagerar<br />
V C<br />
Applikationslogiken<br />
previous next 14<br />
7
2D1362: 2003 Designmönster<br />
...<br />
Designmönster<br />
• MVC är i sig själv en design som (tidigt) använde många<br />
idag mer eller mindre omistliga <strong>designmönster</strong> som:<br />
– Template method, Observer och Factory method<br />
Men också lite mer indirekt mönster som:<br />
– Strategy, Composite och Decorator<br />
• MVC:s framgång, både i Smalltalk och på andra håll, har<br />
inspirerat många till att tränga djupare in i och utforska<br />
framgångsrika designlösningar<br />
previous next 15<br />
… Historik ...<br />
• Gang of Four<br />
– Fyra erkända forskare inom datalogi och objektorientering.<br />
– Skrev den klassiska "Design Patterns Elements of Reusable Software".<br />
• Konferenser och liknande<br />
Designmönster<br />
– Mängder av årliga konferenser, workshops, diskussionsgrupper och<br />
elektroniska möten.<br />
– Vanligt med rapporter som antingen behandlar <strong>designmönster</strong> eller är skriven<br />
på en "<strong>designmönster</strong>form" även på konferenser som inte explicit är<br />
dedicerade för ämnet.<br />
• UML<br />
– UML har tagit upp <strong>designmönster</strong> som en del av modelleringen.<br />
– Designmönstren har å sin sida länge använt notationer liknande UML för att i<br />
mer detalj beskriva lösningar.<br />
previous next 16<br />
8
2D1362: 2003 Designmönster<br />
Designmönster<br />
Exempel-1 Alexander: 136 A Couple's Realm*<br />
previous next 17<br />
…<br />
Designmönster<br />
previous next 18<br />
9
2D1362: 2003 Designmönster<br />
...<br />
Designmönster<br />
previous next 19<br />
Exempel-2 Alexander: 21 Four-Story Limit**<br />
• Ett mönster som författarna klassar högt och därmed<br />
allmänngiltigt<br />
• Dvs bygg inte hus högre än fyra våningar höga<br />
• <strong>Varför</strong>..... osv<br />
Designmönster<br />
previous next 20<br />
10
2D1362: 2003 Designmönster<br />
Designmönster<br />
Från Arkitektur till Programvara<br />
• Mjukvarukonstruktörer har under framförallt 90-talet<br />
funnit likheter mellan Alexanders mönster i<br />
arkitektursammanhang och mönster i mjukvara.<br />
• Problemet med att återanvända konstruktioner och<br />
komponenter har länge diskuterats och eftersträvats i<br />
mjukvaruindustrin.<br />
– Man har tex diskuterat legometaforen<br />
– Trott att objektorientering per automatik skulle vara lösningen<br />
–osv, osv<br />
• Ett centralt problem inom datalogin är att fånga<br />
övergripande designlösningar och inte "bara" beskriva<br />
algoritmer för vissa specifika problem.<br />
previous next 21<br />
<strong>Varför</strong> <strong>designmönster</strong>?<br />
1. Dom erbjuder expertkunskap<br />
2. Dom ger oss en kraftfull vokabulär<br />
Designmönster<br />
3. Vi förstår programsystem snabbare om dom är dokumenterade<br />
med <strong>designmönster</strong><br />
4. Dom förenklar omstrukturering av system (underhåll)<br />
previous next 22<br />
11
2D1362: 2003 Designmönster<br />
...<br />
Designmönster<br />
"A design pattern simply captures the salient characteristics of a<br />
solution to a problem that has been observed to occur repeatedly in<br />
many different problem domains"<br />
(Budd 1997)<br />
"A design pattern provides a scheme for refining the subsystems or<br />
components of a software system, or the relationships between<br />
them. It describes a commonly recurring structure of<br />
communicating components that solves a general design problem<br />
within a particular context"<br />
(Gamma & co 1995)<br />
previous next 23<br />
Designmönster<br />
När kan <strong>designmönster</strong> användas?<br />
• Analysera design<br />
– Ett schema för att göra olika typer av analyser av en viss lösning<br />
• Dokumentera<br />
– På olika nivåer och med olika metoder samtidigt<br />
• Kommunicera<br />
– Kraftfullt språk<br />
– Tekniker och lösningar kan kommuniceras på en hög nivå<br />
• Generalisera och jämföra<br />
– Hitta kärnan i problemen och ge en allmän beskrivning<br />
• Kunskapsbas<br />
– Samlingar med <strong>designmönster</strong> är en förträfflig lättåtkomlig bas av olika<br />
tekniker. Varje utvecklare bör ha åtminstone en översiktlig kännedom om<br />
dom grundläggande mönstren.<br />
previous next 24<br />
12
2D1362: 2003 Designmönster<br />
Formen för ett <strong>designmönster</strong><br />
• Det finns flera olika mallar för att skriva <strong>designmönster</strong>:<br />
– En välkänd är Gang of Four:s<br />
• Denna mall anses idag vara lite utkänt och för omfattande<br />
Designmönster<br />
• Idag försöker man skriva <strong>designmönster</strong> utgående från följande<br />
delar:<br />
– Titel<br />
Ett förklarande namn, som anger vem mönstret är.<br />
– Problem<br />
Vad mönstret avser att lösa.<br />
– Kontext<br />
Krafter och begränsande faktorer som demonstrerar varför problemet är<br />
svårt att lösa.<br />
– Lösning<br />
Hur löser man problemet i den givna kontexten.<br />
previous next 25<br />
... mall forts<br />
Designmönster<br />
• En utmärkt beskrivning av hur s.k. Pattern Languages, dvs system av<br />
sammanhängande mönster, skrivs finns i "A Pattern Language for<br />
Pattern Writing" [Mes]<br />
– Där diskuteras hur man i olika situationer och för olika syften kan använda<br />
olika rubriker med vidhängande beskrivningar<br />
– Beroende av den aktuella situationen behöver inte alla delar i mallen ha en<br />
lika framträdande roll, eller överhuvudtaget diskuteras i beskrivningen.<br />
– Som framgår av namnet på beskrivningen behandlar den Pattern Languages,<br />
dvs sätt att bryta ner ett större problem på mindre relaterade <strong>designmönster</strong><br />
previous next 26<br />
13
2D1362: 2003 Designmönster<br />
Designmönster<br />
Exempel: The Null Object Pattern (med anpassad mall)<br />
Namn<br />
Ett Ett minimalt konkret exempel<br />
Null Object (mönstret delvis efter Bruce Anderson, IBM Essex England)<br />
Avsikt<br />
Eliminera villkorsatser då ett objekt inte har något värde (Tex om<br />
ett objekt är null i Java eller nil i Smalltalk)<br />
Problem<br />
– ibland behöver vi testa om ett objekt antar ett värde innan vi<br />
skickar ett meddelande till det<br />
– detta ger ofta ful och oflexibel kod<br />
– Hur kan vi eliminera tester i klientkoden och därmed få mer<br />
flexibel kod och mindre beroende mellan olika kodavsnitt?<br />
previous next 27<br />
... forts<br />
Designmönster<br />
Exempel<br />
Ex-a) i ett telefonsamtal som började som ett trepartssamtal kan<br />
den uppringande redan ha kopplat ner då dom andra kopplar<br />
ner<br />
if(thisCall.callingParty != null) för detta fall<br />
thisCall.callingParty.close();<br />
Vi måste alltså i koden testa<br />
(kanske på massor av ställen)<br />
Ex-b) i ett system för löneutbetalning har vi ingen information<br />
om en viss persons lön en viss dag<br />
Float salaryOn(Date aDate){<br />
PersonInfo info = this.infoOn(aDate);<br />
return (info == null) ? null : info.salary();<br />
}<br />
previous next 28<br />
14
2D1362: 2003 Designmönster<br />
...Lösning...<br />
– Konstruera ett objekt som motsvarar ett null-värde i den<br />
aktuella kontexten, dvs med lämpligt protokoll och som<br />
"eliminerar" beteendet för metoder där "inget" skall ske<br />
Ex-a) konstruera klassen NullPhone med metoden<br />
void close(){/* do nothing */}<br />
Vid nedkoppling ersätts en Phone med en NullPhone<br />
medför att vi direkt kan utföra<br />
thisCall.callingParty.close();<br />
Designmönster<br />
dvs vi eliminerar testet!<br />
(samtidigt som det blir enkelt att ändra beteendet genom att tex byta klass.<br />
Kanske vill vi ha en tracutskrift eller liknande...)<br />
previous next 29<br />
... lösning forts ...<br />
Ex-b) konstruera klassen MissingInformation med följande<br />
beskrivning av metoden salary<br />
Float salary(){return null;}<br />
medför att vi direkt kan utföra<br />
Float salaryOn(Date aDate)<br />
{return this.infoOn(aDate).salary;}<br />
Designmönster<br />
– Så länge som vi inte har information om lön så skall en instans av<br />
MissingInformation returneras.<br />
• Antingen genom att varje person initieras med denna klass eller att<br />
inspektorn för lönen returnerar en sådan instans om inte informationen<br />
existerar<br />
previous next 30<br />
15
2D1362: 2003 Designmönster<br />
... forts<br />
Implementation<br />
– Typiskt med gemensam<br />
abstrakt superklass<br />
Null Object<br />
AbstractPhone<br />
NullPhone Phone<br />
AbstractInfo<br />
MissingInformation Information<br />
– Kan också implementeras mha mönstren State eller Strategy<br />
Designmönster<br />
previous next 31<br />
... Exempel forts<br />
Designmönster<br />
Konsekvenser<br />
• Ger flexibel struktur. Mer objektorienterad lösning än med villkor.<br />
• Inkapslingen ökar och beroendet mellan komponenter minskar.<br />
• Bra vid avlusning.<br />
• Vi flyttar bort ansvar från "klienter" till "servrar"<br />
Relaterade mönster<br />
– Mönstren State och Strategy , se [GOF]<br />
Känd användning<br />
– I Model-View-Controller använder en passiv vy (utan interaktion) en<br />
instans av NoController med följande metod som anger om objektet<br />
vill "ta över"<br />
boolean isControlWanted(){return false;}<br />
– I VisualAge Smalltalk används mönstret i asNullDragMode och<br />
NullInputManager<br />
previous next 32<br />
16
2D1362: 2003 Designmönster<br />
Designmönster<br />
En not om designmönstren i denna beskrivning<br />
• Av nödvändighet så är beskrivningarna och exemplen som<br />
följer på oh-bilderna kraftigt förkortade, i förhållande till<br />
fullständiga <strong>designmönster</strong>beskrivningar.<br />
• Den som är intresserad av fullständiga beskrivningar kan<br />
gärna konsultera någon av referenserna, som du hittar i<br />
slutet av dessa anteckningar.<br />
previous next 33<br />
Exempel: Template Method<br />
Designmönster<br />
Kontext<br />
Vi har en mogen och komplex objektorienterad omgivning till vilken<br />
programmerare kan lägga till egna klasser.<br />
Problem<br />
Hur kan vi beskriva så mycket som möjligt av en algoritm i en superklass och<br />
endast spara konkreta detaljer till subklasser?<br />
Krafter<br />
– Enkelhet, det skall vara enkelt att använda och förändra detaljer i dom<br />
konkreta klasserna.<br />
– Effektivitet, koden skall vara effektiv och det skall vara enkelt att optimera<br />
detaljer<br />
– Koppling och kohesion, beroendet mellan olika programdelar skall vara litet<br />
och sammanhållningen inom en programdel skall vara stor.<br />
– Sammansättningar skall kunna kan ändras under exekveringen.<br />
previous next 34<br />
17
2D1362: 2003 Designmönster<br />
... template method<br />
Designmönster<br />
Lösning<br />
Konstruera klasser som beskriver abstrakt beteende. Det skall finnas tydliga<br />
punkter i vilket konkreta klasser kan beskriva konkret beteende.<br />
Superklass<br />
templateMethod()<br />
methodX()<br />
methodY()<br />
Subklass<br />
methodX()<br />
methodY()<br />
return methodX() + methodY();<br />
return α;<br />
return β;<br />
previous next 35<br />
Designmönster<br />
...<br />
Exempel<br />
• Används i OO frameworks som Smalltalk-80 och Jawa AWT/Swing<br />
• Model-View-Controller i vilken konkreta användarklasser skriver över<br />
detaljer definierade i existerande superklasser<br />
Konsekvenser<br />
+ Effektiv och snabb implementation<br />
+ Enkelt och rättfram<br />
– Koppling som beror av arv som ger ett beroende mellan super och<br />
subklasser<br />
– Jo-jo-problemet<br />
Relaterade mönster<br />
– Factory Method implementeras ofta med Template Method.<br />
– Strategy: Template Method använder arv för att variera en del av en<br />
algoritm medan Strategy använder delegering för att byta ut en hel<br />
algoritm.<br />
previous next 36<br />
18
2D1362: 2003 Designmönster<br />
Exempel: Composite<br />
Designmönster<br />
Problem<br />
Hur kan vi skapa komplexa objekt som består av andra objekt<br />
men ändå behandla dem uniformt?<br />
Krafter<br />
– Sammansatta objekt skall se ut och bete sig som icke sammansatta objekt.<br />
– Objekt skall kunna nästlas på godtyckligt sätt i varandra.<br />
Lösning<br />
previous next 37<br />
… Composite<br />
Exempel<br />
Component<br />
Leaf1 Leaf2<br />
Shape<br />
Rectangle Ellipse<br />
Graphic<br />
Line Rect Text<br />
*<br />
Picture<br />
*<br />
Composite<br />
Group<br />
Designmönster<br />
previous next 38<br />
1..*<br />
Command<br />
Macro<br />
1..*<br />
19
2D1362: 2003 Designmönster<br />
Designmönster<br />
Kort-korta exempel<br />
Namn: Adapter<br />
Problem<br />
Hur kan vi använda ett objekt (server) som erbjuder lämplig<br />
funktionalitet men har ett annat gränssnitt än vad vi önskar?<br />
Kontext<br />
Vi kan inte ändra serverobjektet och av olika skäl måste det objekt som<br />
vi själva konstruerar ha ett visst gränssnitt.<br />
Lösning<br />
Konstruera en adapter-klass som översätter metoder hos ett server-objekt<br />
så att det passar klient-objektet.<br />
1:m 2:m'<br />
:klient :adapter :server<br />
4:r<br />
3:r'<br />
Exempel<br />
I Java bla Boolean och Integer som anpassar boolean och int. I GUI för<br />
att koppla grafiska komponenter till modeller.<br />
previous next 39<br />
Designmönster<br />
...kort-korta exempel...<br />
Namn: Strategy<br />
Problem<br />
Hur kan vi göra en algoritm som löser ett visst problem utbytbar så att den enkelt<br />
och dynamiskt kan ersättas av en annan?<br />
Kontext<br />
Vi vill undvika att göra flera parallella komplexa algoritmer i ett visst objekt.<br />
Lösning<br />
Objektifiera algoritmerna genom att definiera dem mha en grupp av klasser med<br />
gemensamt gränssnitt. Varje klass definierar en speciell strategi för att lösa det<br />
aktuella problemet.<br />
Context strategy<br />
AbstractStrategy<br />
StrategyA StrategyB StrategyC<br />
Exempel<br />
I Java används olika layoutmanagers,<br />
implementerade som olika strategier. I gränssnitt kan inmatning i inmatningsfält<br />
hanteras genom olika strategier för olika typer av data.<br />
previous next 40<br />
20
2D1362: 2003 Designmönster<br />
Designmönster<br />
...kommandotolk i meddelandesystem (ett exempel till)<br />
• Jag har med fördel använt Strategy i bla distribuerade system och system för att<br />
generera komponenter av olika format<br />
• Nyligen designade jag ett meddelandesystem baserat på TCP/IP och socketar<br />
där jag använde Strategy<br />
– Jag konstruerade en kommandohanterare som beroende av första ordet i<br />
överskickat data (kommandot) valde "strategi", dvs aktiverade ett objekt som tog<br />
över resten av tolkningen av indata och sedermera eventuell exekvering på servern<br />
• Var kommandot ej igenkännbart så använde jag först ett NullObject, vilket vid behov<br />
(enkelt) ersattes med ett mer sofistikerat felhanteringsobjekt.<br />
• Dess lösningar har givit mycket objektorienterad, flexibel och lättunderhållen<br />
struktur (med avseende på tex förändringsbarhet för att möta nya eller ändrade<br />
krav)<br />
• Vidare har det varit enkelt att bygga systemen baserat på kunskapen att<br />
Strategy är ett bra mönster i dom givna situationerna<br />
previous next 41<br />
Designmönster<br />
Hur hittas eller används mönster?<br />
• Via konventionell analys<br />
• Sök efter dokumenterade mönster<br />
• Sök efter mönster som med små modifieringar skulle lösa<br />
problemet<br />
• Försök att kombinera olika mönster<br />
• som sista utväg: konstruera nya mönster<br />
previous next 42<br />
21
2D1362: 2003 Designmönster<br />
Designmönster<br />
Hur omfattande är ett <strong>designmönster</strong>?<br />
• Typiskt är ett <strong>designmönster</strong> ca 10 sidor långt<br />
• Idag är trenden att mer komplicerade beskrivningar görs<br />
med Pattern Languages som består av ett flertal<br />
sammanhängande <strong>designmönster</strong> plus en inledande<br />
beskrivning samt en avslutande sammanfattning<br />
– I dessa fall är varje enskilt mönster typiskt beskrivet med 1-2<br />
sidor text med inledning och sammanfattning av samma<br />
omfattning<br />
• I både den enskilda <strong>designmönster</strong>beskrivningen och<br />
pattern language beskrivningen är en av poängerna att<br />
man ofta bara behöver läsa en eller par underrubriker för<br />
att förstå vad det går ut på och inte förrän man behöver<br />
alla detaljer behöver läsa resten.<br />
previous next 43<br />
Designmönster<br />
Exempel: Observer<br />
Problem<br />
Hur kan vi konstruera en mekanism som tillåter att<br />
vissa objekt meddelas om någon vital del förändras i<br />
andra objekt utan att objekten görs starkt knutna till<br />
varandra?<br />
Kontext<br />
– Vi vill undvika stark koppling och beroende mellan objekten<br />
– Intresserade objekt skall informeras om något förändras.<br />
Lösning<br />
Upprätthåll en lista av objekt som är beroende av ett visst objekt.<br />
Om objektet förändras skall dom beroende objekten meddelas.<br />
Dom beroende objekten skall vart och en själva avgöra hur dom<br />
skall reagera på förändringen.<br />
previous next 44<br />
22
2D1362: 2003 Designmönster<br />
...<br />
Subject<br />
attach(Observer)<br />
detach(Observer)<br />
notify()<br />
observers<br />
for all o in observers<br />
{<br />
o.update();<br />
}<br />
Designmönster<br />
previous next 45<br />
*<br />
Observer<br />
update()<br />
…ett sekvensdiagram som visar ett typiskt<br />
scenario<br />
Designmönster<br />
:subject o1 :observer o2 :observer o3 :observer :object<br />
attach(o1) attach(o2) attach(o3) notify()<br />
update()<br />
update()<br />
update()<br />
notify()<br />
update()<br />
update()<br />
detach(o 3)<br />
previous next 46<br />
23
2D1362: 2003 Designmönster<br />
previous next 47<br />
Lägg till<br />
observer<br />
Ta bort<br />
observer<br />
…Javalösning: observer...<br />
Javalösning med Observer och Observable.<br />
Designmönster<br />
I Java kan ett objekt som vill vara beroende av ett annat objekt implementera<br />
gränssnittet Observer medan det objekt som observeras görs till subklass<br />
till klassen Observable (eller möjligen använder ett fält som är subklass till<br />
denna typ).<br />
• Gränssnittet Observer:<br />
package java.util;<br />
public interface Observer {<br />
void update(Observable o, Object arg);<br />
}<br />
… klassen Observable ...<br />
package java.util;<br />
public class Observable {<br />
private boolean changed = false;<br />
private Vector obs;<br />
private Observer[] arr = new Observer[2];<br />
public Observable() {obs = new Vector();}<br />
public synchronized void addObserver(Observer o) {<br />
if (!obs.contains(o)) {obs.addElement(o);}<br />
}<br />
Designmönster<br />
public synchronized void deleteObserver(Observer o) {<br />
obs.removeElement(o);<br />
}<br />
previous next 48<br />
24
2D1362: 2003 Designmönster<br />
Metoder för<br />
att meddela<br />
att objektet<br />
ändrats<br />
Meddelandet<br />
update(…)<br />
skickas till<br />
alla observers<br />
… Observable forts...<br />
Designmönster<br />
public void notifyObservers() {notifyObservers(null);}<br />
public void notifyObservers(Object arg) {<br />
int size=0;<br />
}<br />
synchronized (this) {<br />
if (!hasChanged()) return;<br />
size = obs.size();<br />
if (size > arr.length) {<br />
arr = new Observer[size];<br />
}<br />
obs.copyInto(arr);<br />
clearChanged();<br />
}<br />
for (int i = size -1; i>=0; i--) {<br />
if (arr[i] != null) {<br />
arr[i].update(this, arg);<br />
}<br />
}<br />
Om vi inte anger<br />
argument så läggs null<br />
på som argument<br />
Från vem<br />
Argument till<br />
uppdateringen<br />
previous next 49<br />
Sätt eller ta bort<br />
changed-flagga<br />
Designmönster<br />
… klassen Observable forts ...<br />
}<br />
public synchronized void deleteObservers() {<br />
obs.removeAllElements();<br />
}<br />
protected synchronized void setChanged(){<br />
changed = true;<br />
}<br />
protected synchronized void clearChanged(){<br />
changed = false;<br />
}<br />
public synchronized boolean hasChanged() {<br />
return changed;<br />
}<br />
public synchronized int countObservers(){<br />
return obs.size();<br />
}<br />
previous next 50<br />
25
2D1362: 2003 Designmönster<br />
… observer ...<br />
Exempel: MessageBoard och beroende studenter<br />
import java.util.*;<br />
class MessageBoard extends Observable {<br />
private String message;<br />
}<br />
public String getMessage(){<br />
return message;<br />
}<br />
public void changeMessage(String aMessage){<br />
}<br />
message = aMessage;<br />
this.setChanged();<br />
this.notifyObservers(message);<br />
Designmönster<br />
previous next 51<br />
I update(…)<br />
definierar vi vad<br />
som skall göras<br />
då objektet<br />
får reda på att ett<br />
objekt som det är<br />
beroende av<br />
ändrats<br />
… observer: exempel ...<br />
import DB.*;<br />
import java.util.*;<br />
Subklassa Observable<br />
Vi sparar undan argumentet<br />
(om tex något beroende<br />
objekt vill läsa av det)<br />
Vi meddelar beroende objekt,<br />
med message som argument<br />
Implementera gränssnittet<br />
Observer<br />
Vi indikerar att<br />
objektet ändrats<br />
Designmönster<br />
class Student extends DB.Student implements Observer {<br />
public void update(Observable o , Object arg){<br />
System.out.println(this.christianName() +<br />
" tar emot meddelande: " + arg);<br />
}<br />
public Student(String christianName,<br />
String familyName, String pnr,<br />
String programme, String email) {<br />
super(christianName, familyName,<br />
pnr, programme, email);<br />
}<br />
}<br />
previous next 52<br />
26
2D1362: 2003 Designmönster<br />
… observer: exempel ...<br />
Designmönster<br />
public class TestObserver {<br />
public static void main(String [] args)<br />
{<br />
MessageBoard board = new MessageBoard();<br />
Student pers1 = new Student("Kalle", "Person", "133",<br />
"D99", "d99-xxx@nada.kth.se");<br />
pers1.addCourse("OOMPA00");<br />
pers1.addCourse(“FOOD00");<br />
Gör pers1 beroende av board<br />
board.addObserver(pers1);<br />
board.changeMessage("Ny person: " +<br />
pers1.christianName());<br />
Meddela att board ändrats<br />
/* Utskriften blir<br />
Kalle tar emot meddelande: Ny person: Kalle<br />
*/<br />
previous next 53<br />
… observer: exempel ...<br />
Designmönster<br />
Student pers2 = new Student("Olle", "Olsson", "113",<br />
"D96", "olle@hagalund.se");<br />
pers2.addCourse("OOMPA00");<br />
pers2.addCourse("ENGLISH-1"); Gör pers2 beroende av board<br />
board.addObserver(pers2);<br />
board.changeMessage("Ny person: " +<br />
pers2.christianName());<br />
Meddela att board ändrats<br />
/* Utskriften blir<br />
Olle tar emot meddelande: Ny person: Olle<br />
Kalle tar emot meddelande: Ny person: Olle<br />
*/<br />
previous next 54<br />
27
2D1362: 2003 Designmönster<br />
… observer: exempel<br />
}<br />
Student pers3 = new Student("Lotta", "Ason",<br />
"123", "F98", "ff@home.se");<br />
pers3.addCourse("OOMPA00");<br />
pers3.addCourse("GRIP2001");<br />
board.addObserver(pers3);<br />
board.changeMessage("Ny person: " +<br />
pers3.christianName());<br />
/* Utskriften blir<br />
Lotta tar emot meddelande: Ny person: Lotta<br />
Olle tar emot meddelande: Ny person: Lotta<br />
Kalle tar emot meddelande: Ny person: Lotta<br />
*/<br />
}<br />
Designmönster<br />
previous next 55<br />
… observer-exemplet i Smalltalk<br />
DB.Student subclass: #Student<br />
update: anAspectSymbol with: with: arg arg<br />
Transcript<br />
show: show: self self christianName,<br />
' tar tar emot emot meddelande: ', ',<br />
arg arg<br />
Designmönster<br />
Object Object subclass: subclass: #MessageBoard<br />
#MessageBoard<br />
instanceVariableNames: 'message'<br />
'message'<br />
getMessage<br />
getMessage<br />
^message ^message<br />
changeMessage: changeMessage: msg msg<br />
message message := := msg. msg.<br />
self self changed: changed: #newMessage<br />
#newMessage<br />
with: with: message message<br />
board board := := MessageBoard MessageBoard new. new.<br />
pers1 pers1 := := Student Student chName: chName: 'Kalle’ 'Kalle’ fname: fname: 'Person’ 'Person’ socNo: socNo: '133’ '133’<br />
status: status: 'd00’ 'd00’ email: email: 'd00-kpe@nada.kth.se'.<br />
board board addDependent: addDependent: pers1. pers1.<br />
board board changeMessage: changeMessage: 'Ny 'Ny person: person: ', ', pers1 pers1 christianName<br />
christianName<br />
“OSV…”<br />
“OSV…”<br />
previous next 56<br />
28
2D1362: 2003 Designmönster<br />
... Observerexemplet i UML<br />
I UML skulle exemplet se ut något i stil med<br />
MessageBoard<br />
Student<br />
Subject<br />
Observer<br />
Subject<br />
Observer<br />
Observer<br />
Designmönster<br />
previous next 57<br />
Kort-korta exempel: Abstract Factory<br />
Designmönster<br />
Problem<br />
Hur kan vi erbjuda mekanismer för att skapa familjer av relaterade objekt utan<br />
specificera deras konkreta klasser?<br />
Lösning<br />
Konstruera en abstrakt fabrik som ansvarar för att returnera en konkret fabrik som<br />
beror av kontext. Den konkreta fabriken konstruerar<br />
sedan konkreta produkter i aktuell kontext.<br />
Client<br />
AbstractProductA<br />
AbstractFactory<br />
ProductA2 ProductA1<br />
ConcreteFactory1 ConcreteFactory2<br />
AbstractProductB<br />
ProductB2 ProductB1<br />
Exempel<br />
I InterViews, ET++ och VisualWorks används tekniken för att anpassa systemet<br />
till aktuell plattform genom att en speciell gränssnittsfabrik används per<br />
plattformstyp.<br />
previous next 58<br />
29
2D1362: 2003 Designmönster<br />
Exempel: State<br />
Designmönster<br />
Problem<br />
Hur kan vi låta ett objekt ändra beteende beroende av sitt interna tillstånd så<br />
att det verkar som om det ändrar klass?<br />
Kontext<br />
Vi vill isolera beskrivningar av beteende. Vi vill göra övergångar explicita.<br />
Vi vill kunna dela på ”state”-objekt.<br />
Lösning<br />
Använd ett associerat objekt som implementerar aktuellt beteende.<br />
Context<br />
request()<br />
state.handle()<br />
state<br />
ConcreteStateA<br />
handle()<br />
State<br />
handle()<br />
ConcreteStateB<br />
handle()<br />
previous next 59<br />
En lista med några kända mönster (ur [GOF])<br />
• Abstract<br />
Factory<br />
• Adapter<br />
• Bridge<br />
• Builder<br />
• Command<br />
• Composite<br />
• Chain of<br />
Responsibility<br />
• Factory<br />
Method<br />
• Flyweight<br />
• Glue<br />
• Interpreter<br />
• Iterator<br />
• Mediator<br />
• Memento<br />
• Observer<br />
• Prototype<br />
Designmönster<br />
• Proxy<br />
• Singleton<br />
• State<br />
• Strategy<br />
• Template Method<br />
• Visitor<br />
• Wrapper<br />
previous next 60<br />
30
2D1362: 2003 Designmönster<br />
Till vad används <strong>designmönster</strong>?<br />
• Arkitektur<br />
• Beskriva metoder och designlösningar i mjukvara<br />
(framförallt i samband med objektorientering)<br />
• Processer<br />
– Hur skriver jag en rapport?<br />
– Hur genomförs en Writer's Workshop?<br />
– Hur leder jag projekt?<br />
–osv<br />
• Analys och design<br />
• Systemdesign<br />
Designmönster<br />
previous next 61<br />
Organisation av mönster<br />
• Man kan dela in mönster efter typ som<br />
– Design Patterns<br />
– Pattern Language<br />
– Catalogue<br />
– Idiom<br />
–Architectural<br />
• I UML skiljer man på<br />
– Mechanisms<br />
• ett annat ord för design patterns<br />
– Frameworks<br />
• ett arkitektoriskt mönster<br />
Designmönster<br />
previous next 62<br />
31
2D1362: 2003 Designmönster<br />
Designmönster<br />
... man kan också dela in designpatterns på följande sätt<br />
Class<br />
Object<br />
Creational<br />
Purpose<br />
Structural Behavioural<br />
Factory Method Adapter Interpreter<br />
Template Method<br />
Abstract Factory<br />
Builder<br />
Prototype<br />
Singleton<br />
Adapter<br />
Bridge<br />
Composite<br />
Decorator<br />
Facade<br />
Flyweight<br />
Glue<br />
Proxy<br />
Chain of responsibility<br />
Command<br />
Iterator<br />
Mediator<br />
Memento<br />
Publisher-Subscriber<br />
State<br />
Strategy<br />
Visitor<br />
previous next 63<br />
Designmönster<br />
Vart är mönstren på väg?<br />
• Används i allt fler projekt, både akademiska och industriella.<br />
• Det finns många <strong>designmönster</strong>grupper över hela världen, bla en<br />
på KTH.<br />
• Klassbibliotek utformas med influenser från <strong>designmönster</strong>.<br />
• Många konferenser, massor av böcker och flera tidskrifter.<br />
• Någon har tom sagt att design patterns är svaret på vad som<br />
kommer efter objektorientering. Men …<br />
• Alexander jobbar vidare och utvecklar nya idéer (fast det är inte<br />
säkert att detta påverkar grenen som sysslar med mjukvara)<br />
previous next 64<br />
32
2D1362: 2003 Designmönster<br />
Slutsatser<br />
Hjälper design patterns någon?<br />
Ja, dom<br />
1. fångar expertkunskap på ett lättillgängligt sätt<br />
Designmönster<br />
2. ger oss namn på designlösningar, vilket ger oss en kraftfull<br />
vokabulär då vi diskuterar design och implementation<br />
3. hjälper oss att förstå system snabbare<br />
4. förenklar omstrukturering av system.<br />
Vidare har dom medfört att lättillgängliga kataloger med<br />
designlösningar skapats<br />
previous next 65<br />
Referenser<br />
Designmönster<br />
[Al64] Alexander, C. Notes on the Synthesis of Form, Cambridge: Harvard University<br />
Press, 1964.<br />
[Al77] Alexander, C., Ishikawa, S., Silverstein, M., Jacobson, M., Fiksdahl-King, I.,<br />
and Angel, S. A Pattern Language, Oxford University Press, 1977.<br />
[Al79] Alexander, C. The Timeless Way of Building, Oxford University Press, 1979.<br />
[GOF] Gamma et al Design Patterns Elements of Reusable Software 1995<br />
[Ker] Kernighan, B. and Plauger, P.J. The Elements of Programming Style, 2nd<br />
edition, McGraw-Hill, 1978<br />
[Kra] Krasner, G.E. and Pope, S.T. Cookbook for using the Model-View-Controller<br />
User Interface Paradigm, JOOP, August 1988, pp. 26-49.<br />
[Mes] Meszaros & Doble A Pattern Language for Pattern Writing<br />
http://hillside.net/patterns/writing/patternwritingpaper.htm<br />
Design Patterns ”hemsida”<br />
http://hillside.net/patterns<br />
med länkar till massor av information<br />
previous next 66<br />
33