"Flare" <dct_flare@hotmail.com> wrote
[8<8<8<]
>
http://anders.pings.dk/images/projekt/classdia.gif
>
Kan du forklare lidt om hvordan Button_Activate, Button_Calibrate etc.
adskiller sig fra hinanden ?
Er der nogen grund til at der er en hård 4 kardinalitet ?
[8<8<8<]
> Button_Controler::Check_Buttons()
> {
> Button *ButObj;
> Button_Activate ButActiObj;
> ButObj = ButActiObj;
> ButObj->Is.Pressed()
Hvorfor vil du have IsPressed til at være run-time polymorphisk ?
Du kender jo eksakt typen (Button_Activate) på dette sted.
Hvad sker der når IsPressed kaldes ?
[8<8<8<]
> Grunden til m it spørgsmål er at dette jo kræver en forbindelse fra
> Button_Controler til alle Button_XXX klasserne. Men de er jo ikke
> illustreret`??? Ligger de implicit i diagrammet eller er det en mere
> "elegant" måde at lave det polymorfikse kald.
Det er en sundt at du undrer dig over at Button_Controller skal kende alle
specialiseringerne af Button.
Som jeg læser diagrammet er Button_Controller og Button det abstrakte
interface som en applikation ser, og Button_Calibrate etc. er de konkrete
implementeringer af Button.
Designet har en cirkulær afhængighed, idet det konkrete afhænger af det
abstrakte (ved at arve) og det abstrakte afhænger af det konkrete (ved at
nævne det ved navn i implementeringen).
Der er et godt princip (The Dependency Inversion Principle), der bl.a. siger
at abstraktioner skal ikke afhænge af detaljer, men detaljer skal afhænge af
abstraktionen.
Se Robert C. Martins gode OO-design principper
http://www.objectmentor.com/resources/articles/dip.pdf
som er en del af
http://www.objectmentor.com/resources/articles/Principles_and_Patterns.PDF
Alle 10 principper findes mere detaljeret beskrevet på
http://www.objectmentor.com. Det er et glimrende sted, med mange gode
artikler om design, patterns og udviklingsprocess.
En almindelig variant af problemet i OO-systemer er kendt som "Fragile Base
Class", hvor base-klassen afhænger af specialiseringerne. Det er generelt
usundt, og et tegn på at koden er ved at forfalde.
Ud fra "The Dependency Inversin Principle" er problemet, sådan som du også
selv antyder, at Button_Controller afhænger af Button_Calibrate etc.
Du kan fjerne den afhængighed ved at lade Button constructoren registrere
hvert _instans_ i en container (f.eks. std::vector) og lade Button
destructoren afregistrere instansen fra containeren.
Button_Controller::Check_Buttons vil så kunne gøre sit arbejde ved at
iterere igennem containeren og kalde Is_Pressed polymorfisk på alle
instancerne.
Destructoren tl Button_Controller kan så nedlægge alle Button objekterne i
containeren.
Vær sikker på at du forstår forskellen og sammenhængen mellem klasser og
objekter.
Eventuelt skulle overveje om du virkelig har brug for 4 specialisering,
eller om du blot har brug for 4 instanser af samme klasse.
Hvis den eneste forskel mellem knapperne er hvad der konkret sker, når der
trykkes på dem kan du give hvert instans information om hvad de skal udføre
med i constructoren.
I det scenarie vil PushButton være en specialisering af Button.
Der er ofte tvivl om hvornår man skal lave specialiseringer og hvornår man
skal parameterisere variation. God smag og erfaring er væsentlige elementer
i at vælge i sådanne tvivlstilfælde.
Det hører ikke specielt sammen med OO-design.
Kig på C funktionen "realloc", som tager så mange parametre at den udgør et
komplet interface til en heap-manager - "malloc" og "free" er overflødige.
At de alligevel findes er et udtryk for god smag og erfaring (i forhold til
_kun_ at have "realloc")
Venlig hilsen
Mogens Hansen
"Flare" <dct_flare@hotmail.com> wrote in message
news:<3d8f0294$0$62709$edfadb0f@dspool01.news.tele.dk>...
[8<8<8<]
>
http://anders.pings.dk/images/projekt/classdia.gif
>
Kan du forklare lidt om hvordan Button_Activate, Button_Calibrate etc.
adskiller sig fra hinanden ?
Er der nogen grund til at der er en hård 4 kardinalitet ?
[8<8<8<]
> Button_Controler::Check_Buttons()
> {
> Button *ButObj;
> Button_Activate ButActiObj;
> ButObj = ButActiObj;
> ButObj->Is.Pressed()
Hvorfor vil du have IsPressed til at være run-time polymorphisk ?
Du kender jo eksakt typen (Button_Activate) på dette sted.
Hvad sker der når IsPressed kaldes ?
[8<8<8<]
> Grunden til m it spørgsmål er at dette jo kræver en forbindelse fra
> Button_Controler til alle Button_XXX klasserne. Men de er jo ikke
> illustreret`??? Ligger de implicit i diagrammet eller er det en mere
> "elegant" måde at lave det polymorfikse kald.
Det er en sundt træk at du undrer dig over at Button_Controller skal kende
alle specialiseringerne af Button.
Som jeg læser diagrammet er Button_Controller og Button det abstrakte
interface som en applikation ser, og Button_Calibrate etc. er de konkrete
implementeringer af Button.
Designet har en cirkulær afhængighed, idet det konkrete afhænger af det
abstrakte (ved at arve) og det abstrakte afhænger af det konkrete (ved at
nævne det ved navn i implementeringen).
Der er et godt princip (The Dependency Inversion Principle), der bl.a. siger
at abstraktioner skal ikke afhænge af detaljer, men detaljer skal afhænge af
abstraktionen.
Se Robert C. Martins gode OO-design principper
http://www.objectmentor.com/resources/articles/dip.pdf
som er en del af
http://www.objectmentor.com/resources/articles/Principles_and_Patterns.PDF
Alle 10 principper findes mere detaljeret beskrevet på
http://www.objectmentor.com. Det er et glimrende sted, med mange gode
artikler om design, patterns og udviklingsprocess.
En almindelig variant af problemet i OO-systemer er kendt som "Fragile Base
Class", hvor base-klassen afhænger af specialiseringerne. Det er generelt
usundt, og et tegn på at koden er ved at forfalde.
Ud fra "The Dependency Inversin Principle" er problemet, sådan som du også
selv antyder, at Button_Controller afhænger af Button_Calibrate etc.
Du kan fjerne den afhængighed ved at lade Button constructoren registrere
hvert _instans_ i en container (f.eks. std::vector<Button*>) og lade Button
destructoren afregistrere instansen fra containeren.
Button_Controller::Check_Buttons vil så kunne gøre sit arbejde ved at
iterere igennem containeren og kalde Is_Pressed polymorfisk på alle
instancerne.
Destructoren tl Button_Controller kan så nedlægge alle Button objekterne i
containeren.
Vær sikker på at du forstår forskellen og sammenhængen mellem klasser og
objekter.
Jeg tror desuden at du skulle overveje om du virkelig har brug for 4
specialisering, eller om du blot har brug for 4 instanser af samme klasse.
Hvis den eneste forskel mellem knapperne er hvad der konkret sker, når der
trykkes på dem kan du give hvert instans information om hvad de skal udføre
med i constructoren.
I det scenarie vil PushButton være en specialisering af Button.
Der er ofte tvivl om hvornår man skal lave specialiseringer og hvornår og
hvordan man skal parameterisere variation. God smag og erfaring er
væsentlige elementer i at vælge i sådanne tvivlstilfælde.
Det hører ikke specielt sammen med OO-design.
Kig på C funktionen "realloc", som tager så mange parametre at den udgør et
komplet interface til en heap-manager - "malloc" og "free" er overflødige.
At de alligevel findes er så afgjort et udtryk for god smag og erfaring (i
forhold til _kun_ at have "realloc")
Venlig hilsen
Mogens Hansen