1 / 64

Programmering og systemudvikling

Programmering og systemudvikling. Lektion 8 Designmønstre. Observer – en starter. Ur. Clock Hour: 11 Min: 38 Sek: 25 MSek:. is presented as. depends on. depends on. Regneark. Celler D7: 25 D8: 10 D9: 65. is presented as. depends on. depends on. Lagkage- diagram.

mostyn
Download Presentation

Programmering og systemudvikling

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Programmering og systemudvikling Lektion 8 Designmønstre Designmønstre

  2. Observer – en starter Designmønstre

  3. Ur Clock Hour: 11 Min: 38 Sek: 25 MSek: .. is presented as depends on depends on Designmønstre

  4. Regneark Celler D7: 25 D8: 10 D9: 65 is presented as depends on depends on Lagkage- diagram Designmønstre

  5. CAD-system Browser ... House DoorA Roof1 Window3 is presented as depends on depends on Designmønstre

  6. CASE-værktøj Browser ... AST is presented as depends on depends on class Account { public void deposit(...); public void withdraw(...); }; class ChequeAccount extends Account { ... }; ... Designmønstre

  7. Generelt: Subject-Observers depends on Subject is presented as Observer 1 Observer 2 ... Observer n Designmønstre

  8. Problem • Ændring af den interne tilstand i en komponent kan bevirke inkonsistens i andre eller på tværs af komponenter. • Hvordan kan vi reetablere konsistens således at: • informationsudbyderen (subject) ikke afhænger af forbrugerne (observers) • forbrugerne (observers) ikke skal være kendt på forhånd. Designmønstre

  9. Løsning • Implementer en “change propagation mechanism” mellem informationsudbyder (Subject) og forbrugere (Observers). • Subject vedligeholder et register over Observers og gør alle Observers opmærksomme på ændringer af tilstand-en. • Observer erklærer en (virtuel) update-funktion som kaldes af Subjects “change propagation mechanism”. • Konkrete Observers implementerer update-metoden... Designmønstre

  10. abstract (videre-)binding Løsning, struktur Designmønstre

  11. attach(this) attach(this) Løsning, dynamik Subject Observer 1 Observer 2 setData notify update getData update getData Designmønstre

  12. Om mønstre Abstraktioner og sprogmekanismer Gang of Four (GoF) En skabelon for mønstre (eks. Observer) Designmønstre

  13. Abstraktioner og sprogmekanismer Sprogmekanismer Tid ... Arkitektoniske abstraktioner Designmønstre

  14. Eksempler goto call return record array class object Tid Kræver stor disciplin og systematik af udvikleren. Ingen sprog- understøttelse. goto sr a:... s:... goto a Simulering af abstrakte datatyper (ADT) ? Manuel allokering og administration af lagerblokke; manuel adresse- beregning ved indeksering, ... Designmønstre

  15. ... Eksempler goto call return record array class object Tid goto sr a:... s:... goto a Simulering af abstrakte datatyper (ADT) Mønstre Manuel allokering og administration af lagerblokke; manuel adresse- beregning ved indeksering, ... Designmønstre

  16. Gang of Four (GoF) Erich Gamma, Richard Helm Ralph Johnson & John Vlissides Design Patterns – Elements of Reusable Object-Oriented Software Addison-Wesley, 1995. (Også udgivet som CD, 1998) Første systematiske fremstilling af designmønstre. Designmønstre

  17. Designmønstre Et designmønster - navngiver, - abstraherer og - identificerer de centrale aspekter ved en gængs designstruktur. Et designmønster identificerer deltagende klasser (og instanser) deres rolle og samarbejde samt ansvarsfordelingen mellem dem. The Pattern Community: Aggresive disregard of originality Designmønstre

  18. Designmønstre i GoF (23) Creational (5) Structural (7) Behavioral (11) Abstract Factory Adapter Chain of Responsibility Builder Bridge Command Factory MethodComposite Interpreter Prototype Decorator Iterator Singleton Facade Mediator Flyweight Memento Proxy Observer State Strategy Template Method Visitor Designmønstre

  19. Designmønstre á la PiJ 1. Introduction 2. A Case Study 3. Fundemental Patterns (4) 4. Creational Patterns (5) 5. Partitioning Patterns (6) 6. Structural Patterns (7) 7. Behavioral Parrerns (8) 8. Concurrency Patterns (9) 6. Conclusion - synopsis - context - forces - solution - consequences - implementation - Java API usage - code example - related patterns Designmønstre

  20. Observer Intent Definerer en en-til-mange sammenhæng mellem objekter så ændringer af tilstanden i et objekt automatisk reflekteres i alle de andre objekter (Publish-Subscribe). Motivation Designmønstre

  21. Observer (2) Structure Designmønstre

  22. Observer (3) Participants Subject, kender sine (abstrakte) observere; et vilkårligt antal observere kan knyttes til et subject; giver gennem sit interface mulighed for at tilknytte og fjerne observere Observer, definerer et interface til at opdatere objekter der skal bekendtgøres om ændringer i et subject ConcreteSubject, indkapsler tilstand for konkrete subjects; bekendtgør tilstandsændringer til observere ConcreteObserver, vedligeholder en reference til et ConcreteSubject objekt; indkapsler tilstand der skal være konsistent med subject Designmønstre

  23. Observer (4) Collaboration Designmønstre

  24. Observer, Sample Code (1) interface Observer { public abstract void update(Subject theChangedSubject); }; abstract class Subject { public void attach(Observer o){observers.add(o);} public void Detach(Observer o) {observers.remove(o);} public void notify() {…}; protected Subject(); private List observers; }; Designmønstre

  25. Observer, Sample Code (2) public void notify() { iterator i = observers.iterator(); while (i.hasNext()) (Observer)(i.next()).update(this); } Designmønstre

  26. Observer, Sample Code (3) class ClockTimer extends Subject { public ClockTimer(); public int getHour(); public int getMinute(); public int getSecond(); void tick(); // Tick kaldes jævnligt af en intern timer }; void ClockTimer::tick() { // opdatér intern repræsentation // ... notify(); } Designmønstre

  27. Observer, Sample Code (4) class DigitalClock implements Widget extends Observer { public DigitalClock(ClockTimer); public void update(Subject) // (re-)definerer Observer::update public void draw(); // (re-)definerer Widget::draw private ClockTimer _subject; }; Designmønstre

  28. Observer, Sample Code (5) DigitalClock::DigitalClock(ClockTimer s) { _subject = s; _subject.attach(this); } DigitalClock::finalize() { _subject.detach(this); } void DigitalClock::Update(Subject ChangedSubject) { if (ChangedSubject == _subject) draw(); } void DigitalClock::Draw() { // skaf de nye værdier fra _subject int hour = _subject.getHour(); int minute = _subject.getMinute(); // etc. // tegn det digitale ur } Designmønstre

  29. Iterator Intent Giver sekventiel tilgang til elementerne i en container (et aggregat) uden at afsløre containerens underliggende repræsentation. Motivation Problemstillingen og et bud på en løsning er velkendt: Designmønstre

  30. Iterator (2) Motivation, fortsat Imidlertid er det ufleksibelt at en klient skal vide at det er en liste der itereres på, men det kan undgås: Designmønstre

  31. Iterator (3) Structure CreateIterator er et eksempel på en Factory Method (GoF, pp. 107-116). Designmønstre

  32. Composite Intent Sammensæt objekter i en rekursiv træstruktur der repræsenterer et part-whole hierarki. Mønsteret muliggør at enkelte og sammensatte elementer kan behandles uniformt. Motivation Designmønstre

  33. Composite (2) Structure Designmønstre

  34. Composite (3) Participants Component (Graphic) - erklærer et interface for objekter i strukturen - implementerer standardopførsel for alle objekter - erklærer et interface til “child“-komponenter (evt.) - erklærer et interface til “parent”-komponenter. Leaf (Rectangle, Line, Text, etc.) - repræsenterer primitive objekter (blade) - (re-)definerer opførsel for primitive objekter. ... Designmønstre

  35. Composite (4) Participants, fortsat Composite (Picture) - (re-)definerer opførsel for sammensatte objekter - gemmer referencer til efterfølgerobjekter - implementerer efterfølger-relaterede operationer fra interfacet. Client - manipulerer Component-objekter gennem Component- interfacet. Designmønstre

  36. Composite (5) Implementation ... Skal operationer til håndtering af sammensatte objekter erklæres i Component eller i Composite? Svaret forudsætter en afvejning mellem sikkerhed og transparens; i dette designmønster er transparens fundet vigtigere end sikkerhed, men bemærk at det er i konflikt med substitutionsprincippet. Hvis operationerne flyttes ned i Composite, opstår der i Client behov for på runtime at kunne spørge på typen af et Component-objekt. I C++ kan man bruge dynamic_cast eller tilføje en operation getComposite i Component-interfacet: Designmønstre

  37. Composite, sikkerhed over transparens class Component { public: // ... Composite getComposite() { return null; } }; class Composite extends Component { public: add(Component); remove(Component); // ... Composite getComposite() { return this; } }; class Leaf extends Component { // ... } Designmønstre

  38. Template Method, GoF pp. 325-330 Intent At definere grundstrukturen i en algoritme, men udskyde den konkrete fastlæggelse af enkelte trin til subklasser. Subklasser kan redefinere elementer i en algoritme, men grundstrukturen ligger fast. Motivation Designmønstre

  39. Template Method (2) Class Application { public void OpenDocument(String name) { if ( !CanOpenDocument(name) ) { // cannot handle this document return; } Document doc = DoCreateDocument(); if ( doc ) { _docs.AddDocument(doc); AboutToOpenDocument(doc); doc.Open(); doc.DoRead(); } private Vector _docs; } Designmønstre

  40. Template Method (3) Operationen ’move’ i et figurhierarki er en Template Method: class Shape { public Shape(int x, int y) _x(x), _y(y) {} public void move(int dx, int dy) { hide(); _x+= dx; _y+= dy; show(); } public abstract void show(); public abstract void hide(); protected int _x; protected int _y; }; Designmønstre

  41. Template Method (4) Structure Designmønstre

  42. Adapter, GoF pp. 139-150 Intent Konverterer interfacet for en klasse til et som klinten forventer (wrapper, late abstraction). Motivation Det kan ske at en klasse er svær at genbruge fordi den har et “forkert” interface (eks.: Vector og List burde kunne behandles uniform, men har forskellige interfaces). Eller: Til et tegneprogram kan det være ligetil at implementere klasserne Shape, LineShape, PolygonShape, hvorimod TextShape er noget mere kompliceret; selv basal teksteditering involverer komplicerede skærm-opdateringer og buffer-håndtering. Designmønstre

  43. Adapter, Motivation fortsat Imidlertid findes der en ‘off-the-shelf’ klasse, TextView; problemet er blot at denne ikke er designet – og derfor ikke kan behandles – som en Shape. Hvis vi har kildeteksten til TextView kan vi ændre interfacet så det passer til Shape, men ofte har man ikke kildeteksten, og selv om man har, er det af hensyn til andre applikationer ikke ønskeligt at tilpasse interfacet. Men vi kan definere TextShape som en adapter der tilpasser TextViews interface til Shape-hierarkiet. Dette kan gøres på to måder: Class Adapter Object Adapter Designmønstre

  44. Adapter public class Shape { // BoundingBox-based public Shape(){…} public Box BoundingBox(); public Manipulator CreateManipulator(); }; class TextView { // OriginAndExtent-based public: TextView(); //returnerer centrum public point GetOrigin(Coord& x, Coord& y){…} //retrunerer bredde og højde public pair GetExtent(){…} public bool isEmpty(){…} }; Designmønstre

  45. Class Adapter (C++ style) class TextShape : public Shape, private TextView { public: TextShape(); virtual void BoundingBox(Point& bottomLeft, Point& topRight); virtual bool isEmpty(); virtual Manipulator* CreateManipulator(); }; void TextShape::BoundingBox(Point& bottomLeft, Point& topRight) { Coord bottom, left, width, height; GetOrigin(bottom, left); GetExtent(width, height); bottomLeft = Point(bottom, left); topRight = Point(bottom + height, left + width); } Designmønstre

  46. Adapter for containerklasser template<class T> class Vector { public: explicit Vector(size_t n); T& operator[](size_t); }; template<class T> class List { public: class Link { ... }; List(); void put(T*); T* get(); }; Hver klasse tilbyder ”de naturlige operationer” – de er små og kan inlines (effektivt) – og for hver klasse kan vi vælge en passende repræsentationsinvariant uden at tænke på de øvrige containere. Imidlertid kan forekomster af de to forskellige slags containerklassser ikke behandles uniformt (for eksem- pel med en iterator), og det er træls! Hvad gør vi? Designmønstre

  47. abstract wrap wrap Wrap, wrap, and abstract Late Abstraction Designmønstre

  48. Koden... template<class T> class Itor { public: virtual T* first()= 0; virtual T* next()= 0; }; template<class T> class VectorItor : public Itor { public: VectorItor(Vector<T>& vv) : v(vv), index(0) {} T* first() { ... } T* next() { ... } private: Vector<T>& v; size_t index; }; template<class T> class ListItor : public Itor { public: ListItor(List<T>& llst) : lst(llst), ... {} T* first() { ... } T* next() { ... } private: List<T>& lst; List<T>::Link p; }; Designmønstre

  49. Anvendelser int count (Itor<int>& i, int x) { int c = 0; for ( int* p=i.first(); p; p=i.next() ) if ( *p==x ) c++; return c; } Vector<int> v; VectorItor<int> vi(v); int periodCount = count(vi, 7); List<int> l; ListItor<int> li(v); int commaCount = count(li, 42); Operationerne first() og next() er simple, men de giver et overhead i form af et virtuelt funktionskald. Til et standardbibliotek er det ikke ideelt, men løsningen har dog været brugt i et utal af systemer, og i mange år var det faktisk Bjarne Stroustrups favoritløsning. Lige indtil Alexander Stepanov og Meng Lee fra HP kom med STL... Designmønstre

  50. Hvad vi lærte af “Late Abstraction” Bemærk: Et fælles interface som Itor kan laves længe efter at containerklasserne er designet og implementeret. Når vi designer og program-merer, udvikler vi typisk først noget meget konkret (for ek-sempel Vector og List). Først senere erkender vi ab-straktioner der kan generali-sere de mere konkrete kom-ponenter (f. eks. Itor). ”Late abstraction” kan vi benytte gentagne gange. ”Late abstraction” vha. abstrakte klasser tillader os at lave forskellige implementa-tioner af et begreb også når der ikke er en åbenlys lighed mellem implementationerne. Vector og List har oplagte fællestræk, men der er ikke noget i vejen for også at lave en Itor for eksempelvis en stream. Designmønstre

More Related