Ohjelmistotuotannon menetelmät Syksy 2003

48
Ohjelmistotuotannon menetelmät Syksy 2003 Design Patterns (Sami Jantunen, LTY/TITE)

description

Ohjelmistotuotannon menetelmät Syksy 2003. Design Patterns (Sami Jantunen, LTY/TITE). Ohjelma. Design Patterneista Yleisesti Historiatietoa Määrittely Ominaisuuksia Design Patternien kuvaustavat Patterntyypit Patternkieli, systeemi, kataloogi - PowerPoint PPT Presentation

Transcript of Ohjelmistotuotannon menetelmät Syksy 2003

Page 1: Ohjelmistotuotannon menetelmät Syksy 2003

Ohjelmistotuotannon menetelmätSyksy 2003

Design Patterns(Sami Jantunen, LTY/TITE)

Page 2: Ohjelmistotuotannon menetelmät Syksy 2003

Ohjelma1. Design Patterneista Yleisesti

Historiatietoa Määrittely Ominaisuuksia Design Patternien kuvaustavat Patterntyypit Patternkieli, systeemi, kataloogi Design patternien käyttö oliopohjaisen järjestelmän

kehityksessä AntiPattern

2. Esimerkkejä Design Patterneista Creational Patterns Structural Patterns Behavioral Patterns

Page 3: Ohjelmistotuotannon menetelmät Syksy 2003

Luettavaa

Design PatternsElements of Reusable Object-Oriented

Software

byErich Gamma,

Richard Helm, Ralph Johnson, and John Vlissides

(The Gang of Four).

Page 4: Ohjelmistotuotannon menetelmät Syksy 2003

Historiatietoa Arkkitehti Christopher Alexanderin kirjoitukset 1970-luvun

lopulla. “ajattomien” hyväksi todettuja ratkaisuja etsintä talojen

suunnittelussa termi Pattern Pattern ajattelun omaksuminen ohjelmistotuotannon alalla

1980-luvun lopussa Kent Beck and Ward Cunningham, Textronix, OOPSLA'87

(käytti Alexander's "pattern" ideaa Smalltalkin GUI suunnittelussa)

Erich Gamma, Ph. D. väitöskirja, 1988-1991 James Coplien, Advanced C++ Idioms kirja, 1989-1991 Gamma, Helm, Johnson, Vlissides ("Gang of Four“ - GoF)("Gang of Four“ - GoF)

Design Patterns: Elements of Reusable Object-Oriented Software, 1991-1994

Page 5: Ohjelmistotuotannon menetelmät Syksy 2003

Design Patterns määrittely … a fully realized form, original, or model accepted or proposed

for imitation…[dictionary]

... describes a problem which occurs over and over again in our environment, and then describes the core of the solution to that problem, in such a way that you can use this solution a million times over, without ever doing it the same way twice [Alexander]

… the abstraction from a concrete form which keeps recurring in specific non-arbitrary contexts [Riehle]

…both a thing and the instructions for making the thing [Coplien]

...a literary format for capturing the wisdom and experience of expert designers, and communicating it to novices

Page 6: Ohjelmistotuotannon menetelmät Syksy 2003

Patternien ominaisuuksiaPatternit… tarjoaa yhteisen sanaston kuvaamaan

ratkaisumalleja tiettyihin ongelmiin tehostaa kommunikaatiota monimutkaisten

järjestelmien suunnittelussa auttaa arkkitehtuurin dokumentoinnissa

Patternit eivät... tarjoa eksaktia ratkaisua ratkaise kaikkia suunnitteluongelmia rajoitu pelkästään oliokeskeiseen suunnittelutyöhön

Page 7: Ohjelmistotuotannon menetelmät Syksy 2003

Esimerkki: The Courtyard Pattern – Christopher Alexander

“Consider the forces at work in a courtyard. Most fundamental of all, people seek

some kind of private outdoor space, where they can sit under the sky, see the

stars, enjoy the sun, perhaps plant flowers. This is obvious. But there are more

subtle forces too. For instance, when a courtyard is too tightly enclosed, has no

view out, people feel uncomfortable, and tend to stay away … they need to see

out into some larger and more distant space. Or again, people are creatures of

habit. If they pass in and out of the courtyard, every day, in the course of their

normal lives, the courtyard becomes familiar, a natural place to go … and it is

used. But a courtyard with only one way in, a place you only go when you “want”

to go there, is an unfamiliar place, tends to stay unused … people go more often

to places which are familiar. Or again, there is a certain abruptness about

suddenly stepping out, from the inside, directly to the outside … it is subtle, but

enough to inhibit you. If there is a transitional space, a porch or a veranda, under

cover, but open to the air, this is psychologically half way between indoors and

outdoors, and makes it much easier, more simple, to take each of the smaller

steps that brings you out into the courtyard”

Page 8: Ohjelmistotuotannon menetelmät Syksy 2003

The Courtyard Pattern jatkoa…(johtopäätös)

“When a courtyard has a view out to a larger space has crossing

paths from different rooms has a veranda or a porch these forces

can resolve themselves. The view out makes it comfortable, the

crossing paths help generate a sense of habit there, the porch

makes it easier to go out more often … and gradually the courtyard

becomes a pleasant customary place to be.”

Page 9: Ohjelmistotuotannon menetelmät Syksy 2003

Patternin sisältö

Pattern

Solution

Problem

Context

a design situation giving rise to a design problem

a form or rule that can be applied to resolve these forces

a set of forces occuring in that context

“Courtyard” esimerkki… Identifioi patternin Kuvasi asiat mitä tulisi tavoitella Kuvasi miten tavoite voitaisiin saavuttaa Kertoi voimista, mitkä saattaisi vahingoittaa toivottua

tavoitetta

Page 10: Ohjelmistotuotannon menetelmät Syksy 2003

Patternin rakenne Alexanderin tyyli (canonical form)

Namemeaningful name

Problemthe statement of the problem

Contexta situation giving rise to a problem

Forcesa description of relevant forces and constraints

Solution proven solution to the problem

Examples sample applications of the pattern

Resulting context (force resolution)the state of the system after pattern has been applied

Rationale explanation of steps or rules in the pattern

Related patterns static and dynamic relationship

Known useoccurrence of the pattern and its application within existing system

Page 11: Ohjelmistotuotannon menetelmät Syksy 2003

Patternin rakenne GoF tyyli

Pattern name and classification Intent

what does pattern do / when the solution works

Also known as other known names of pattern (if any)

Motivation the design problem / how class and object structures solve the problem

Applicability situations where pattern can be applied

Structure a graphical representation of classes in the pattern

Participants the classes/objects participating

and their responsibilitiesCollaborations

of the participants to carry out responsibilitiesConsequences

trade-offs, concerns Implementation

hints, techniquesSample code

code fragment showing possible implementationKnown uses

patterns found in real systemsRelated patterns

closely related patterns

Page 12: Ohjelmistotuotannon menetelmät Syksy 2003

Pattern-tyyppejä

Creational Patterns tekee järjestelmistä riippumattomampia

olioiden luontitavasta.Structural Patterns

Luokkien ja olioiden kokoaminen suuremmiksi rakenteiksi.

Behavioral Patterns Algoritmien ja olioiden välisten vastuiden

määrittely.

Page 13: Ohjelmistotuotannon menetelmät Syksy 2003

Pattern catalogs and systems

[Buschmann, POSA][Buschmann, POSA] pattern catalog

…a collection of related patterns, where patterns are subdivided into small number of broad categories…

pattern system…a cohesive set of related patterns, which work

together to support the construction and evolution of hole architectures...

Page 14: Ohjelmistotuotannon menetelmät Syksy 2003

Design pattern luettelo (Gang of Four)

Purpose

Creational Structural Behavioral

Class Factory Method Adapter Interperter

Scope

Object

Abstract Factory

Builder Prototype Singleton

Adapter Bridge Composite Decorator Facade Flyweight Proxy

Chain of Responsibility Command Iterator Mediator Momento Observer State Strategy Vistor

Patterneita kuvattu esim: http://pages.cpsc.ucalgary.ca/~kremer/patterns/

Page 15: Ohjelmistotuotannon menetelmät Syksy 2003

Patternien käyttö luokkakaaviossa-Vaikeudet ja riskit

Patternit eivät ole patenttiratkaisu: Älä käytä patterneja suin päin. Patternien

soveltaminen voi johtaa huonoihin ratkaisuihin.

Ymmärrä aina syvällisesti seikat mitkä pitää ratkaista ja mikä pattern ratkaisee kyseiset ongelmat

Pidä huolta, että perustelet jokaisen suunnittelupäätöksen huolellisesti

Page 16: Ohjelmistotuotannon menetelmät Syksy 2003

AntiPattern AntiPattern kertoo kuinka ongelma ratkaistaan

huonosti Hyvä AntiPattern kertoo:

miksi huono ratkaisu näyttää houkuttelevalta miksi ratkaisu osoittautuu lopulta huonoksi mitä Patternia kannattaisi käyttää ongelman

ratkaisuun

“an anti-pattern is something that looks like a good idea, but which backfires badly when applied.” (Jim Coplien)

Page 17: Ohjelmistotuotannon menetelmät Syksy 2003

Antipatternesimerkki: ZeroMeansNull

Name: ZeroMeansNull Type: Design Category: AntiPattern Problem: Implementing an optional field. Forces: Laziness or optimism. Ignorance of nulls, e.g. "they're too inconvenient to

deal with". Using a storage implementation that doesn't support them. Supposed solution: Nobody will ever set this to all zeros, so let that represent

"omitted." Resulting context: When it really needs to be zero, it can't be. When you need to

convert from ints to some form of real, you can't reliably detect zero (RealNumbersAreNotEqual). You can forget to compare with zero in some cases, and let it through as a nonsense value. You're more likely to get an exception (e.g. NullPointerException in Java) if you use a proper null.

Example: Designer thinks "Nobody will ever be at latitude zero, longitude zero." User reports:"I hope you can help me! I'm trying to draw grid lines on the globe and for some reason one is always missing...."

Lisää antipatterneja: http://c2.com/cgi/wiki?AntiPatternsCatalog

Page 18: Ohjelmistotuotannon menetelmät Syksy 2003

Missä mennään?

1. Design Patterneista Yleisesti Historiatietoa Määrittely Ominaisuuksia Design Patternien kuvaustavat Patterntyypit Patternkieli, systeemi, kataloogi Design patternien käyttö oliopohjaisen järjestelmän

kehityksessä AntiPattern

2. Esimerkkejä Design Patterneista Creational Patterns Structural Patterns Behavioral Patterns

Page 19: Ohjelmistotuotannon menetelmät Syksy 2003

Esimerkki:TietokonepeliHaluaisimme luoda labyrintin tietokonepeliin…

Alustava ratkaisu:

Page 20: Ohjelmistotuotannon menetelmät Syksy 2003

Luokkien määrittely

MapSite-luokka on yhteinen abstrakti isäluokka kaikkiin labyrinttiin kuuluviin luokkiin.

Class MapSite {

public:

virtual void Enter() = 0;

};

Enter-metodin tarkoitus riippuu siitä mihin ollaan labyrintissä astumassa sisään

Page 21: Ohjelmistotuotannon menetelmät Syksy 2003

Jatkoa luokkien määrittelyyn...

Enum Direction {North, South, East, West};

Class Room : public MapSite {

public:

Room(int roomNo);

MapSite* Side(Direction) const;

void Set_side(Direction, MapSite*);

virtual void Enter() { //… }

private:

MapSite* _sides[4];

int _roomNo;

};

Page 22: Ohjelmistotuotannon menetelmät Syksy 2003

Jatkoa luokkien määrittelyyn...

Jokaisessa huoneessa on 0-4 seinää ja 0-4 ovea.

Class Wall : public MapSite {

public:

Wall();

virtual void Enter() { /… }

};

Page 23: Ohjelmistotuotannon menetelmät Syksy 2003

Jatkoa luokkien määrittelyyn...Jokainen ovi on kahden huoneen välissä:

class Door : public MapSite {

public:

Door(Room* = NULL, Room* = NULL);

virtual void Enter() { //… }

Room* Other_side_from(Room*);

private:

Room* _room1;

Room* _room2;

bool _isOpen;

};

Page 24: Ohjelmistotuotannon menetelmät Syksy 2003

Jatkoa luokkien määrittelyyn...

Maze (labyrintti) -luokka koostuu kokoelmasta huoneita:class Maze {

public:

Maze();

void Add_room(Room*);

Room* RoomNo(int) const;

private:

List rooms; //List of Room*

};

Page 25: Ohjelmistotuotannon menetelmät Syksy 2003

Labyrintin kokoaminen

Implementoidaan Maze_game –luokka joka luo labyrintin. Labyrintti voidaan luoda sarjalla operaatioita, missä olioita lisätään labyrinttiin yksi kerrallaan ja kytketään niitä sitten yhteen.

Esimerkki: Luodaan 2 hengen labyrintti

Maze* Maze_game::Create_maze () {

Maze* maze = new Maze;

Room* r1 = new Room(1);

Room* r2 = new Room(2);

Door* door = new Door(r1, r2);

maze->Add_room(r1);

maze->Add_room(r2);

r1->Set_side(North, new Wall);

r1->Set_side(East, door);

r1->Set_side(South, new Wall);

r1->Set_side(West, new Wall);

r2->Set_side(North, new Wall);

r2->Set_side(East, new Wall);

r2->Set_side(South, new Wall);

r2->Set_side(West, door);

return maze;

}

Page 26: Ohjelmistotuotannon menetelmät Syksy 2003

OngelmaJOUSTAMATTOMUUS

Labyrintti on kovakoodattu Labyrintin muuttaminen merkitsisi käytännössä uusiksi

ohjelmoimista

Page 27: Ohjelmistotuotannon menetelmät Syksy 2003

Labyrintin jatkokehitys…

Mitä jos haluttaisiin käyttää hyväksi vanhaa labyrinttiä ja jatkokehittää sitä seuraavilla luokilla:

Door_needing_spell – Ovi, joka sulkeutuu tai avautuu loitsun avulla.

Enchanted_room – Huone, jossa on epätavallisia esineitä.

Page 28: Ohjelmistotuotannon menetelmät Syksy 2003

Labyrintin uudelleenkäytön parantelu…Olemassa oleva koodi tulisi muuttaa sellaiseksi, että uuden tyyppisten olioiden luominen

tapahtuisi mahdollisimman pienin koodimuutoksin? Annetaan Create_maze:en parametrina olio, jonka tehtävänä on luoda huoneet, seinät ja ovet

Määritellään ensin Maze_factory –luokka, joka luo labyrintin osaset ajonaikana.

Class Maze_factory {public:

Maze_factory(); // the following are also called “virtual constructor”.

virtual Maze* Make_maze() const { return new Maze; }virtual Wall* Make_wall() const{ return new Wall; }virtual Room* Make_room(int n) const { return new Room(n); }virtual Door* Make_door(Room* r1, Room* r2) const { return new Door(r1, r2); }

};

Page 29: Ohjelmistotuotannon menetelmät Syksy 2003

Parannetaan Create_maze -metodia

Maze* Maze_game::Create_maze(Maze_factory& factory) { Maze* maze = factory.Make_maze(); Room* r1 = factory.Make_room(1); Room* r2 = factory.Make_room(2); Door* door = factory.Make_door(r1, r2);

maze->Add_room(r1); maze->Add_room(r2);r1->Set_side(North, factory.Make_wall());r1->Set_side(East, door);r1->Set_side(South, factory.Make_wall());r1->Set_side(West, factory.Make_wall());

r2->Set_side(North, factory.Make_wall());r2->Set_side(East, factory.Make_wall());r2->Set_side(South, factory.Make_wall() );r2->Set_side(West, door);

return maze;}

Page 30: Ohjelmistotuotannon menetelmät Syksy 2003

Ja palataan sitten parannellun labyrintin pariin….

Luodaan Enchanted_maze_factory –luokka perimällä se Maze_factory:sta.

Tämä luokka yliajaa jäsenfunktiot ja palauttaa erilaiset Room- Wall, … -oliot

Class Enchanted_maze_factory : public Maze_factory {public:

Enchanted_maze_factory ();

virtual Room* Make_room(int n) const {return new Enchanted_room(n, Cast_spell()); }

virtual Door* Make_door(Room* r1, Room* r2) const { return new Door_needing_spell(r1, r2);}

protected:Spell* Cast_spell() const;

};

Page 31: Ohjelmistotuotannon menetelmät Syksy 2003

Labyrintin rakentaminenMaze_game game;

Enchanted_maze_factory factory;

game.create_maze(factory);

Tällä tavalla voimme luoda minkälaisen labyrintin tahansa!

Page 32: Ohjelmistotuotannon menetelmät Syksy 2003

Lopputulos: Abstract Factory

Maze_factoryMaze_factory

Make_maze()Make_room()

Make_wall()

Make_door()

RoomRoom

Clientuses

usesDoorDoor

uses

Bombed_factoryBombed_factory

Make_wall() Make_room()

Enchanted_factoryEnchanted_factory

Make_room()Make_door()

Door_need_spell

Bombed_wall

Enchanted_roomRoom_with_bomb

create

createcreate

WallWall

uses

Page 33: Ohjelmistotuotannon menetelmät Syksy 2003

Abstract Factory Pattern

AbstractFactoryAbstractFactory

createProductA()createProductB()

ConcreteFactory1ConcreteFactory1

createProductA()createProductB()

ConcreteFactory2ConcreteFactory2

createProductA()createProductB()

AbstractProductAAbstractProductA

AbstractProductBAbstractProductB

ProductB1ProductB2

ProductA1ProductA2

ClientClientuses

uses

uses

create

create

Page 34: Ohjelmistotuotannon menetelmät Syksy 2003

Singleton Pattern

Konteksti: On hyvin tavallista että tietystä luokasta pitäisi olla

olemassa vain yksi instanssi (singleton) Ongelma:

Kuinka varmistat, että luokkaa ei missään tilanteessa luoda enemää kuin yksi olio?

Vahingoittavia voimia: public konstruktorin käyttö ei takaa, että olioita

tulee vain yksi. singleton instanssi pitää olla kaikkien halukkaiden

luokkien käytettävissä

Page 35: Ohjelmistotuotannon menetelmät Syksy 2003

Singleton Patternclassclass Singleton { Singleton {publicpublic:: staticstatic Singleton *get_instance(); Singleton *get_instance();protectedprotected:: Singleton(); Singleton();

Singleton( Singleton( constconst Singleton& s); Singleton& s);privateprivate:: staticstatic Singleton *instance; Singleton *instance;};};Singleton::instance = 0;Singleton::instance = 0;

Singleton *Singleton::get_instance() {Singleton *Singleton::get_instance() { ifif ( instance == 0 ) { ( instance == 0 ) { instance = instance = newnew Singleton; Singleton; } } returnreturn instance; instance;}}

Company

theCompany

Company «private»getInstance

if (theCompany==null) theCompany= new Company();

return theCompany;

«Singleton»

theInstance

getInstance

Page 36: Ohjelmistotuotannon menetelmät Syksy 2003

Esimerkki: Singleton patternin käyttö labyrintissäClass Maze_factory {public:

static Maze_factory* get_instance();//existing interface goes here…

protected:Maze_factory();Maze_factory(const Maze_factory& f);

private:static Maze_factory* instance;

};Maze_factory::instance = 0;Maze_factory* Maze_factory::get_instance(){

if (_instance == 0)_instance = new Maze_factory;

return _instance;}

Page 37: Ohjelmistotuotannon menetelmät Syksy 2003

Missä mennään?

1. Design Patterneista Yleisesti Historiatietoa Määrittely Ominaisuuksia Design Patternien kuvaustavat Patterntyypit Patternkieli, systeemi, kataloogi Design patternien käyttö oliopohjaisen järjestelmän

kehityksessä AntiPattern

2. Esimerkkejä Design Patterneista Creational Patterns Structural Patterns Behavioral Patterns

Page 38: Ohjelmistotuotannon menetelmät Syksy 2003

Adapter Pattern Konteksti

Olet rakentamassa perintähierarkiaa ja haluat käyttää siinä hyväksi jo olemassa olevaa luokkaa

Uudelleenkäytetty luokka on usein jo osa omaa perintähierarkiaa

Ongelma Kuinka voi käyttää polymorphismin etuja hyväksi kun

uudelleenkäyttää olemassa olevan luokan metodeja, jotka:

sisältävät halutun toiminnallisuuden mutta funktion nimikirjoitus (signature) ei ole sama

kuin muut hierarkiassa olevat metodit? Vahingoittavat voimat

Et halua tai saa käyttää moniperintää.

Page 39: Ohjelmistotuotannon menetelmät Syksy 2003

Adapter

«Adaptee»

adaptedMethod

«Superclass»

polymorphicMethod

«Adapter»

polymorphicMethod()

return adaptee.adaptedMethod();

{

}

Page 40: Ohjelmistotuotannon menetelmät Syksy 2003

Façade Pattern Konteksti

Sovellus sisältää usein useita monimutkaisia moduuleja Ohjelmoijan, joka käyttää moduuleja täytyy manipuloida useita

eri luokkia Ongelma

Kuinka voi yksinkertaistaa monimutkaisten moduulien käytettävyyttä?

Vahingoittavat voimat Ohjelmoijan on vaikea ymmärtää ja käyttää kokonaisia

alisysteemejä Jos useat eri sovelluksen luokista kutsuvat moduulin metodeita,

niin moduulin kohdistuvat muutokset pakottaa katselmoimaan uusiksi kaikki ne luokat jotka pakettia käyttävät.

Page 41: Ohjelmistotuotannon menetelmät Syksy 2003

Façade

Page 42: Ohjelmistotuotannon menetelmät Syksy 2003

Proxy Konteksti

On usein aikaavievää ja monimutkaista luoda raskaasta luokasta (heavyweight class) olioita

Tällaisen olion luomiseen liittyy monimutkainen luontimekanismi ja se aiheuttaa aikaviiveen

Ongelma Kuinka voisi vähentää tarvetta luoda instansseja

raskaista luokista? Vahingoittavat voimat

Kaikki oliot on oltava käytettävissä tarpeen mukaan Joillekin olioille on tärkeää olla olemassa koko

ohjelman ajon ajan

Page 43: Ohjelmistotuotannon menetelmät Syksy 2003

Proxy

Käyttötarkoituksia: Remote Proxy voi piilottaa tiedon siitä, että todellinen

olio onkin toisessa muistiavaruudessa object is in another address space.

Virtuaali Proxyt voi luoda resursseja syövät oliot tarpeen vaatiessa.

Protection proxy voi kontrolloida käyttöoikeuksia olioon.

Page 44: Ohjelmistotuotannon menetelmät Syksy 2003

Missä mennään?

1. Design Patterneista Yleisesti Historiatietoa Määrittely Ominaisuuksia Design Patternien kuvaustavat Patterntyypit Patternkieli, systeemi, kataloogi Design patternien käyttö oliopohjaisen järjestelmän

kehityksessä AntiPattern

2. Esimerkkejä Design Patterneista Creational Patterns Structural Patterns Behavioral Patterns

Page 45: Ohjelmistotuotannon menetelmät Syksy 2003

Chain of Responsibility

Tarkoitus: Välttää pyynnön lähettäjän ja vastaanottajan kytkemistä (coupling) tarjoamalla

useita vaihtoehtoisia olioita, jotka voivat hoitaa pyynnön. Pyynnön vastaanottajaoliot (handler) ketjutetaan ja pyyntöä kuljetetaan handlerilta toiselle kunnes jokin handlereista hoitaa sen.

Esimerkki: Käyttöliittymän context-sensitive help ominaisuus. Käyttäjä voi saada apua mistä

tahasa käyttöliittymän osiosta klikkaamalla kyseistä käyttöliittymän osaa. Jos tästä osasta ei ole ohjeita saatavilla, yleisempi ohje valitusta kontekstista esitetään.

Page 46: Ohjelmistotuotannon menetelmät Syksy 2003

Observer

Tarkoitus: Määrittelee one-to-many riippuvuuden olioiden välille siten, että kun yksi

olio muuttaa tilaansa kaikki siitä riippuvat oliot päivittyvät. Muuttoksen aiheuttava olio ei välttämättä tiedä muita muutettavia olioita

Page 47: Ohjelmistotuotannon menetelmät Syksy 2003

Observer -Esimerkkejä

WeatherViewer

Observers are notified when a new prediction is readyForecaster

Observable * ****** «interface»Observer

Page 48: Ohjelmistotuotannon menetelmät Syksy 2003

Iterator

Tarjoaa keinon päästä käsiksi aggregaatin hallinoimiin elementteihin ilman, että aggregaatin sisäinen toteutus paljastuu

Tarjoaa yhtenäinen rajapinta eri aggregaatti rakenteiden selailuun

esimerkki: Standard Template Library (STL) container iteraattorit.