[c++] Function pointer map t.b.v de code onderhoudbaarheid

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Gehakt
  • Registratie: Juli 2002
  • Laatst online: 19-09 15:50
Ik wil in dit topic graag een discussie beginnen over function pointer maps in cpp en deze voornamelijk richten op de onderhoudbaarheid en hoe gevaarlijk het is om function pointer maps te gebruiken.

De stelling hierbij is dan ook: Function pointer maps maken code beter onderhoudbaarder.

Function pointer maps zorgen ervoor dat de Unit Size en de complexity (McCabe) van functies omlaag gaat. Hierdoor worden ze makkelijker te begrijpen voor de programmeur en daarmee makkelijker onderhoudbaar.

Voorbeeldcode die ik weleens tegen kom waarbij een te ondernemen actie afhangt van een bepaalde string:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const std::string stringObject("DEFINE_A");
Test test;
if("DEFINE_A" == stringObject)
{
    test.TestA();
}
else if ("DEFINE_B" == stringObject)
{
    test.TestB();
}
else if ("DEFINE_C" == stringObject)
{
    test.TestC();
}
else
{
    // Error?
}

Door gebruik te maken van een function pointer map zou je dit ook als volgt kunnen scrijven:
C++:
1
2
3
const std::string stringObject("DEFINE_A");
Test test;
test.doStuff(stringObject);

Dit heeft twee voordelen. Allereerst is de volledige if else boom vermeden waardoor de McCabe complexity naar beneden gaat.
Daarnaast is er in het laatste voorbeeld maar 1 publieke functie nodig in Test in plaats van 3.
Verder is door het gebruik van een enkele define en een typedef de code in Test zelf ook nog leesbaar te houden. Ik ben daarom ook niet tegen het gebruik van function pointers maar ben benieuwd naar jullie mening hierover.

Indien gewenst post ik de implementatie van Test ook.

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

Gehakt schreef op dinsdag 08 maart 2011 @ 22:36:
en hoe gevaarlijk het is om function pointer maps te gebruiken.
Je stelt dat het zo is, maar vervolgens zie ik daar nergens argumenten voor. Als je een discussie wilt starten moet je ook je eigen argumenten kenbaar maken ;)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Gehakt
  • Registratie: Juli 2002
  • Laatst online: 19-09 15:50
Ik vindt ze niet gevaarlijk. Ik hoor echter andere collega's weleens roepen dat het "gevaarlijk" is omdat ze niet type-safe zouden zijn :? Maar echt overtuigende/concrete argumenten heb ik nooit gehoord. Oftewel ik zie geen nadelen aan deze methode om de unit size en complexity van code terug te brengen. :)
.oisyn schreef op dinsdag 08 maart 2011 @ 23:03:
[...]

Je stelt dat het zo is, maar vervolgens zie ik daar nergens argumenten voor. Als je een discussie wilt starten moet je ook je eigen argumenten kenbaar maken ;)
Dat laatste was meer bedoeld als een: is het wel gevaarlijk want ik zie daar zelf geen aanwijzingen voor? :)

[ Voor 39% gewijzigd door Gehakt op 08-03-2011 23:09 ]


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ah ok, dat was niet helemaal duidelijk. Ik zie niet helemaal wat er gevaarlijk aan is, of wat er niet type-safe is aan een 'void (Test::*ptr)()' of 'std::tr1::function<void()>'. Wellicht zou je eens na kunnen vragen wat hun beweegredenen zijn om daar zo tegen aan te kijken?

Waar ik wel een beetje huiverig voor ben, maar dat geldt voor elke vorm van abstractie en niet zozeer louter voor pointers naar functies an sich, is dat al het overzicht weg is op het moment dat je allerlei callbacks en interfaces e.d. in allerlei lijstjes gaat registreren. Daarmee ontkoppel je oorzaak (iemand die besluit dat iets ergens geregistreerd moet worden) en gevolg (het aanroepen van de geregistreerde callback), wat probleemanalyse knap lastig maakt. Bovendien kun je dan niet meer zoeken naar bijv. alle aanroepen van een bepaalde functie, omdat de aanroep zelf dan weggeabstraheerd is.

.edit: wat trouwens wel een probleem is, voornamelijk met VC++, is dat sizeof(T::*) nogal afhangt van wat T eigenlijk is. Nou maakt dat op zich niet uit aangezien T binnen een programma niet zal wijzigen, ware het niet dat als T een incomplete type is (een class declaratie zonder definitie), dat het zich dan anders gedraagt dan als T wél bekend is. Maar voor code dat met elkaar interact is het wel van belang dat ze dezelfde aannames maken. Daarom is het dus van belang dat voor pointer-to-members altijd de klassedefinitie bekend is op het moment dat je dergelijke typen gebruikt, ookal krijg je geen compile errors als dat niet zo is.

[ Voor 92% gewijzigd door .oisyn op 08-03-2011 23:30 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • MLM
  • Registratie: Juli 2004
  • Laatst online: 12-03-2023

MLM

aka Zolo

Als al je methodes dezelfde signature hebben (ie, members van zelfde class, zelfde returntype en argumenten), dan zie ik geen probleem. In alle andere gevallen gooi je type-safety overboord, dat is niet echt een fijne oplossing.

Kan me voorstellen dat in een geval met veel methodes een hash-map fijn kan zijn gezien je key-type een string is, maar in jouw voorbeeld met 3 methodes... Beetje een insect doodrijden met een bulldozer :P

En hoewel je het punt van aanroep versimpelt, verschuif je je "lange" code naar 1 of andere "register" functie die de map moet onderhouden, en dat word ook niet echt een feestje qua onderhoudbaarheid (maar nog steeds wel beter dan een if/else tree) :)

[ Voor 22% gewijzigd door MLM op 09-03-2011 10:32 ]

-niks-


Acties:
  • 0 Henk 'm!

  • Gehakt
  • Registratie: Juli 2002
  • Laatst online: 19-09 15:50
Het gaat inderdaad om members die dezelfde signature hebben. Op welke manier kan je de type-safety overboord gooien? Is het mogelijk om een generieke functiepointer te definiëren?

Overigens is die korte if else uiteraard een voorbeeld. Ik ben functies tegengekomen met rond de 20 if-else statements op deze manier. De map hoeft in principe niet onderhouden te worden toch? bij het constructen van het object zorg je dat de map gevuld wordt met de juiste member functies. Dit kan in een aparte functie fillMap() oid.

Ben het verder wel met .oisyn eens dat het aanroepen van de functies zelf wel veel ondoorzichtiger wordt wat ook fouten met zich mee kan brengen die moeilijk te vinden zijn.

[ Voor 14% gewijzigd door Gehakt op 09-03-2011 10:55 ]


Acties:
  • 0 Henk 'm!

  • MLM
  • Registratie: Juli 2004
  • Laatst online: 12-03-2023

MLM

aka Zolo

Gehakt schreef op woensdag 09 maart 2011 @ 10:51:
Het gaat inderdaad om members die dezelfde signature hebben. Op welke manier kan je de type-safety overboord gooien? Is het mogelijk om een generieke functiepointer te definiëren?

Overigens is die korte if else uiteraard een voorbeeld. Ik ben functies tegengekomen met rond de 20 if-else statements op deze manier. De map hoeft in principe niet onderhouden te worden toch? bij het constructen van het object zorg je dat de map gevuld wordt met de juiste member functies. Dit kan in een aparte functie fillMap() oid.

Ben het verder wel met .oisyn eens dat het aanroepen van de functies zelf wel veel ondoorzichtiger wordt wat ook fouten met zich mee kan brengen die moeilijk te vinden zijn.
Ik bedoeld dus dat je dan je fillMap() moet gaan onderhouden :) En omdat je niet voor elke instantie van je object een map wilt hebben, wil je dus dat die map static is. En dan moet dat weer een singleton oid zijn, en zit je met initialisation order etc. :)

Mbt generieke function pointers:
Volgens mij kan je pointer-to-member types niet portable casten (sommige compilers weigeren), maar daar kan je omheen werken. Ook het probleem wat .oisyn aankaart met sizeof(pointer-to-member) kan opgelost worden met wat kennis over hoe de compiler de pointer-to-member implementeerd (je kan adhv een pointer-to-member het uiteindelijke adres van de functie achterhalen door zelf de vtable/offsets door te lopen) voor meer informatie verwijs is door naar http://www.codeproject.com/KB/cpp/FastDelegate.aspx (een prima implementatie van generieke function pointers, met duidelijke uitleg over hoe en waarom het werkt)

-niks-


Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Ik vind dit soort algemene stellingen mbt code sowieso zinloos. Als het in jouw specifieke geval de code beter maakt, gebruik ze dan. Als in een ander geval het geheel lastig te onderhouden is, doe het dan niet.

Moet het switch statement makkelijk/dynamisch uitbreidbaar zijn? Dan lijkt een map me een prima idee. Dat is ook het principe achter veel factories die een registratie optie bieden.

Komt de switch een keer voor en is verder altijd hetzelfde? Dan zou ik gewoon voor een switch gaan.

Acties:
  • 0 Henk 'm!

  • Gehakt
  • Registratie: Juli 2002
  • Laatst online: 19-09 15:50
Zoijar schreef op woensdag 09 maart 2011 @ 11:44:
Ik vind dit soort algemene stellingen mbt code sowieso zinloos. Als het in jouw specifieke geval de code beter maakt, gebruik ze dan. Als in een ander geval het geheel lastig te onderhouden is, doe het dan niet.
Om de discussie iets breder te maken kan ik er wel het volgende aan toevoegen. De onderhoudbaarheid van het product wordt door de klant bepaald onder andere door de Unit Size en Complexity te meten.

Door het gebruik van een function pointer map zal de score dus verbeteren. Is de vraag is eigenlijk of deze stijging in de score wel overeenkomt met de werkelijkheid, namelijk is de onderhoudbaarheid echt verbeterd door het gebruik van een functiepointers.

Ik nijg er zelf naar om ook voor de switch te kiezen waarmee je ook voor een gemeten lagere onderhoudbaarheid kiest.

[ Voor 13% gewijzigd door Gehakt op 09-03-2011 13:35 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Volgens mij zegt Zoijar dat er geen universele waarheden bestaan en zeker geen simpele regels. Er zijn zoveel bedrijven die allerlei vormen van complexiteit hebben bedacht, maar welk probleem lossen ze op? Juist, geen enkel probleem.

Als je goede software wilt, huur dan mensen die grote systemen hebben gebouwd die foutloos zijn. Ga niet op zoek naar 'quick fixes', zoals dit er weer eentje is.

Acties:
  • 0 Henk 'm!

  • EddoH
  • Registratie: Maart 2009
  • Niet online

EddoH

Backpfeifengesicht

Verwijderd schreef op woensdag 09 maart 2011 @ 16:23:
...
Als je goede software wilt, huur dan mensen die grote systemen hebben gebouwd die foutloos zijn. Ga niet op zoek naar 'quick fixes', zoals dit er weer eentje is.
Dit heeft niets te maken met een 'quick fix' lijkt me. De TS geeft een manier aan om veelvoorkomende code 'netter' en beter onderhoudbaar te maken, of in ieder geval een discussie hierover te voeren.
De opmerking over 'goeie software door mensen die foutloze systemen hebben gebouwd' lijkt me, afgezien van het feit dat foutloze systemen niet bestaan, niet echt van toepassing op de TS zijn vraagstelling?

Verder ben ik het met de meeste hier eens dat het toch een kwestie van smaak en context is. Bij een factory method kan ik een dergelijke constructie waarschijnlijk wel waarderen. Maar voor kleine (constante) switch statements maakt het code onnodig midner debuggable.

Om nog even op de TS te reageren: Een bepaalde techniek toepassen alleen omdat er uit een bepaalde meting een lagere complexiteit waarde komt lijkt me niet de goede weg...

[ Voor 8% gewijzigd door EddoH op 09-03-2011 16:32 ]


Acties:
  • 0 Henk 'm!

Verwijderd

EddoH schreef op woensdag 09 maart 2011 @ 16:30:
Dit heeft niets te maken met een 'quick fix' lijkt me. De TS geeft een manier aan om veelvoorkomende code 'netter' en beter onderhoudbaar te maken, of in ieder geval een discussie hierover te voeren.
Het is een quick fix voor het daadwerkelijk begrijpen van de software. Er is helemaal niets dat zegt dat een 'goto' op een bepaalde plaats niet beter is, bijv. Nogmaals, er zijn geen simpele regels.
De opmerking over 'goeie software door mensen die foutloze systemen hebben gebouwd' lijkt me, afgezien van het feit dat foutloze systemen niet bestaan, niet echt van toepassing op de TS zijn vraagstelling?
Ik heb zat foutvrije systemen geschreven.

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

Desalniettemin was het een domme opmerking. Een discussie over wat handig is druk je niet de kop in met "goede programmeurs inhuren". We zijn programmeurs, dus we discussieren erover. Als dit het bedrijfsvoeringsforum was had je een punt.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Gehakt
  • Registratie: Juli 2002
  • Laatst online: 19-09 15:50
Verwijderd schreef op woensdag 09 maart 2011 @ 16:44:
[...]

Het is een quick fix voor het daadwerkelijk begrijpen van de software. Er is helemaal niets dat zegt dat een 'goto' op een bepaalde plaats niet beter is, bijv. Nogmaals, er zijn geen simpele regels.
Ik snap dat er geen simpele regels zijn. Daarom is het juist interessant om eens te kijken naar de voors/tegens van een bepaalde oplossing waarna een ieder voor zichzelf de conclusie trekt of een dergelijke constructie gerechtvaardigd is. :)

Acties:
  • 0 Henk 'm!

  • EddoH
  • Registratie: Maart 2009
  • Niet online

EddoH

Backpfeifengesicht

Verwijderd schreef op woensdag 09 maart 2011 @ 16:44:
[...]

Het is een quick fix voor het daadwerkelijk begrijpen van de software. Er is helemaal niets dat zegt dat een 'goto' op een bepaalde plaats niet beter is, bijv. Nogmaals, er zijn geen simpele regels.
Kan aan mij liggen, maar ik begrijp in zn geheel niet wat je hier bedoeld. Hoezo een quick fix voor het begrijpen van software? Het gaat hier m.i om een manier om bepaalde veelvoorkomende functionaliteit te implementeren. Zie het als een 'pattern' die je kan gebruiken. Dat heeft niets met regels te maken, maar de over de voorkeur om een bepaalde stijl toe te passen als die in veel gevallen voor beter onderhoudbare code zorgt.
Verwijderd schreef op woensdag 09 maart 2011 @ 16:44:
[...]
Ik heb zat foutvrije systemen geschreven.
Da's mooi.

Acties:
  • 0 Henk 'm!

Verwijderd

.oisyn schreef op woensdag 09 maart 2011 @ 16:48:
Desalniettemin was het een domme opmerking. Een discussie over wat handig is druk je niet de kop in met "goede programmeurs inhuren". We zijn programmeurs, dus we discussieren erover. Als dit het bedrijfsvoeringsforum was had je een punt.
Het doel van de vraag is uiteindelijk: hoe goede software te schrijven? Wat een of ander tooltje (complexiteitsmaat) daarover zegt is compleet irrelevant. Er zijn antwoorden die geen 'quick fix' zijn, maar uiteindelijk komt het gewoon neer op welke mensen je in je bedrijf hebt.

Acties:
  • 0 Henk 'm!

  • EddoH
  • Registratie: Maart 2009
  • Niet online

EddoH

Backpfeifengesicht

Verwijderd schreef op woensdag 09 maart 2011 @ 17:10:
[...]
Er zijn antwoorden die geen 'quick fix' zijn, maar uiteindelijk komt het gewoon neer op welke mensen je in je bedrijf hebt.
V:"Hoe maak ik heb best een biefstuk klaar?" A:"huur een goede kok in" 8)7

Acties:
  • 0 Henk 'm!

Verwijderd

EddoH schreef op woensdag 09 maart 2011 @ 17:27:
[...]


V:"Hoe maak ik heb best een biefstuk klaar?" A:"huur een goede kok in" 8)7
Ik snap wel hoe je dit bedoelt, maar als je een biefstuk op de best mogelijke manier wilt klaarmaken, dan zul je ook een robot moeten bouwen die continu biefstukken bakt, continu feedback krijgt of het een goede biefstuk was van een klant, en volgepakt zit met extreem hoge resolutie sensoren om zo de beste biefstuk te maken die nu te maken valt.

Voor het creëren van software kun je helemaal niet iets als een 'recept' opschrijven.

Acties:
  • 0 Henk 'm!

  • Gehakt
  • Registratie: Juli 2002
  • Laatst online: 19-09 15:50
Misschien dat deze discussie afgesplitst moet worden van de originele discussie aangezien deze een generiekere kant op gaat?
Verwijderd schreef op woensdag 09 maart 2011 @ 17:10:
[...]

Het doel van de vraag is uiteindelijk: hoe goede software te schrijven? Wat een of ander tooltje (complexiteitsmaat) daarover zegt is compleet irrelevant. Er zijn antwoorden die geen 'quick fix' zijn, maar uiteindelijk komt het gewoon neer op welke mensen je in je bedrijf hebt.
Wat een tooltje daarover zegt wordt een stuk relevanter als een klant dat gebruikt en daar bepaalde consequenties aan verbind. Dat kan de keuze om voor een bepaalde code constructie te kiezen (of niet) wel degelijk beinvloeden.

[ Voor 71% gewijzigd door Gehakt op 09-03-2011 17:45 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Gehakt schreef op woensdag 09 maart 2011 @ 17:39:
Misschien dat deze discussie afgesplitst moet worden van de originele discussie aangezien deze een generiekere kant op gaat?

[...]

Wat een tooltje daarover zegt wordt een stuk relevanter als een klant dat gebruikt en daar bepaalde consequenties aan verbind. Dat kan de keuze om voor een bepaalde code constructie te kiezen (of niet) wel degelijk beinvloeden.
Waarschijnlijk is het ook mogelijk om door middel van een speciale compiler om je code alsnog zo te schrijven als je dat wilt en dan dat die compiler het herschrijft naar iets met een lagere complexiteit volgens zo'n tooltje.

Dus een 'klant' kan van alles eisen, maar uiteindelijk wil dan die klant een quick fix hebben, terwijl die er dus niet is (zoek maar even de literatuur bij elkaar waarin staat dat hierin een consensus over is bereikt). Ik zou er niet aan moeten denken om afhankelijk van wat een tooltje zegt mijn code te moeten herschrijven.

Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 15:26
Verwijderd schreef op woensdag 09 maart 2011 @ 16:44:
Ik heb zat foutvrije systemen geschreven.
/bitchslap

Weet je zeker dat je collega's niet gezien hebben dat je dat postte?

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Laten we het hier wel een beetje gezellig houden, en elkaar niet gaan aanvallen.

@gang-ster: ook graag ontopic reageren. Het topic gaat niet over de vraag wat voor mensen je in moet huren, maar over de vraag of function pointer maps code beter onderhoudbaar maken, of dat het slecht voor de kwaliteit van code is.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

Gehakt schreef op dinsdag 08 maart 2011 @ 22:36:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const std::string stringObject("DEFINE_A");
Test test;
if("DEFINE_A" == stringObject)
{
    test.TestA();
}
else if ("DEFINE_B" == stringObject)
{
    test.TestB();
}
else if ("DEFINE_C" == stringObject)
{
    test.TestC();
}
else
{
    // Error?
}

Door gebruik te maken van een function pointer map zou je dit ook als volgt kunnen scrijven:
C++:
1
2
3
const std::string stringObject("DEFINE_A");
Test test;
test.doStuff(stringObject);
Wat denk je van:

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class CTestCommand
{
  friend class CTest;
public:
  static CTestCommand* GetCommand(std::string command)
  {
    // factory method implementatie, evt met switch (command)
  };
protected:
  void Execute(Test& test) = 0;
};

class TestDoA : CTestCommand
{
protected:
  void Execute(Test& test) { test.TestA(); }
};

class TestDoB : CTestCommand
{
protected:
  void Execute(Test& test) { test.TestB(); }
};

class CTest
{
public:
  void Run(CTestCommand& command) { command.Execute(*this); }
  void TestA() { }
  void TestB() { }
};

// body:
const std::string stringObject("Define_A");
CTest test:
CTestCommand* cmd = CTestCommand::Getcommand(stringObject);
test.Run(cmd);

... even los het feit van pointergebruik en GetCommand() implementatie.

Voordelen:
- strong typing op je command
- houdt string-ops gescheiden en buiten je core code
- duidelijk
- uitbreidbaar
- cruft zit in slechts 1 functie: GetCommand(). Je zou deze nog altijd met een map<std::string, CTestCommand*> kunnen implementern (mbv prototype pattern)

TestA en TestB blijven deel van de publieke interface. Het command is slechts een manier om een functie uit te voeren, code moet dit ook nog steeds kunnen. Bovendien hou je ook zo weer een loose coupling tussen CTestCommand en CTest.

ASSUME makes an ASS out of U and ME


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

H!GHGuY schreef op donderdag 10 maart 2011 @ 14:11:
Voordelen:
- strong typing op je command
- duidelijk
- uitbreidbaar
Geen verschil met de huidige implementatie.
- houdt string-ops gescheiden en buiten je core code
Je hoeft het natuurlijk niet te implementeren middels string operaties. Enums zou bijv. ook kunnen.

Nadelen:
- Je kan niet naar willekeurige class methods wijzen, je moet een class implementeren per 'command'.

Een callback interface met 1 method is een typisch java-isme, wegens gebrek aan "function pointers". In .Net heb je delegates, in C++ zou je std::tr1::function<> kunnen gebruiken.

Je bent de 'virtual' trouwens vergeten.

[ Voor 38% gewijzigd door .oisyn op 10-03-2011 14:19 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

.oisyn schreef op donderdag 10 maart 2011 @ 14:15:
[...]

Geen verschil met de huidige implementatie.
Wel tov de function-map implementatie.
Een CTestCommand is bvb toch nog net iets meer strong typed dan de content van een std::string.
[...]
Je hoeft het natuurlijk niet te implementeren middels string operaties. Enums zou bijv. ook kunnen.
Maar toch heb ik die string/enum/... cruft liever niet in m'n core code.

Bovendien kom ik liever niet in m'n core code te weten dat de string die aangevoerd wordt niet gekend is. Daarom zou ik daar nog steeds voor aparte functie gaan en dan extern de mapping van string naar functie regelen. Het afhandelen van foute user input hoort niet in de kern van je applicatie.
Nadelen:
- Je kan niet naar willekeurige class methods wijzen, je moet een class implementeren per 'command'.

Een callback interface met 1 method is een typisch java-isme, wegens gebrek aan "function pointers". In .Net heb je delegates, in C++ zou je std::tr1::function<> kunnen gebruiken.

Je bent de 'virtual' trouwens vergeten.
Tweemaal raak ;) Niet iedereen gebruikt reeds een compiler met full TR1 support, dus gelieve old-school code nog even te gedogen...
Punt blijft echter wel dat je inderdaad met function<> een stuk class overhead kunt wegwerken.

ASSUME makes an ASS out of U and ME


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

H!GHGuY schreef op donderdag 10 maart 2011 @ 14:50:
[...]

Wel tov de function-map implementatie.
Een CTestCommand is bvb toch nog net iets meer strong typed dan de content van een std::string.
En jij hebt een GetCommand(std::string). Wat is het verschil?
Maar toch heb ik die string/enum/... cruft liever niet in m'n core code.
Jij hebt CTestCommand crut in je code. Wederom, wat is het verschil? Of je nou een lijstje met enumvalues of een lijstje met CTestCommand pointers of desnoods void (CTest::*)() hebt, dat maakt natuurlijk niet uit.
Bovendien kom ik liever niet in m'n core code te weten dat de string die aangevoerd wordt niet gekend is. Daarom zou ik daar nog steeds voor aparte functie gaan en dan extern de mapping van string naar functie regelen. Het afhandelen van foute user input hoort niet in de kern van je applicatie.
True, ik zou zelf ook de lookup ergens anders plaats laten vinden.
Niet iedereen gebruikt reeds een compiler met full TR1 support
tr1::function is geen compiler iets maar gebaseerd op partial template specialization. De compilers die dát niet ondersteunen zijn wel heel erg old-school. Boost levert een TR1 implementatie, en je zou er zelf ook een kunnen maken.

[ Voor 17% gewijzigd door .oisyn op 10-03-2011 15:11 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

.oisyn schreef op donderdag 10 maart 2011 @ 15:05:
[...]

En jij hebt een GetCommand(std::string). Wat is het verschil?
Het hele omzetten van string -> command is slechts 1 functie die duidelijk en straight-forward is.
Netjes design steekt net dit soort stukken in een klein afgezonderd deel om het geheel overzichtelijk, duidelijk, eenvoudig en dus maintainable te houden.
[...]

Jij hebt CTestCommand crut in je code. Wederom, wat is het verschil? Of je nou een lijstje met enumvalues of een lijstje met CTestCommand pointers of desnoods void (CTest::*)() hebt, dat maakt natuurlijk niet uit.
Het gaat me niet om de enum, string, ... Het gaat me erom dat de cruft niet in de core code zit, maar netjes erbuiten, met 1 enkele one-line access functie. Strikt genomen is die zelfs nog overbodig als de Execute functie public staat.
[...]
True, ik zou zelf ook de lookup ergens anders plaats laten vinden.
[...]
tr1::function is geen compiler iets maar gebaseerd op partial template specialization. De compilers die dát niet ondersteunen zijn wel heel erg old-school. Boost levert een TR1 implementatie, en je zou er zelf ook een kunnen maken.
Ik beweer niet dat het een compiler is, toch? Ik heb het over een compiler met TR1 support in de std lib. Wij compilen bvb ook nog met een GCC 3.4.3, zònder. Toegegeven, we gebruiken boost, maar niet iedereen doet dat.

ASSUME makes an ASS out of U and ME


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

H!GHGuY schreef op donderdag 10 maart 2011 @ 16:58:
Het gaat me niet om de enum, string, ...
Ja ik snap je punt nu. Je voorgestelde ontkoppeling van de lookup is wat dat betreft ook te verenigen met het design van de TS, dus zonder een 1-method-interface te gebruiken.
Ik beweer niet dat het een compiler is, toch?
Je zei "een compiler met full TR1 support", dat klonk alsof je compiler support nodig hebt. Maar zoals ik al zei, de feature kan ook gewoon worden toegevoegd met een 3rd party lib, of desnoods iets wat je zelf in elkaar zet (zo ingewikkeld is het niet). Het feit dat TR1 niet is opgenomen in de standard library is dus geen argument om dergelijke features links te laten liggen.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • NC83
  • Registratie: Juni 2007
  • Laatst online: 21-08 21:44
Dan implementeer je toch zelf een delegate template class die dat voor je regelt.

ex-FE Programmer: CMR:DiRT2,DiRT 3, DiRT Showdown, GRID 2, Mad Max

Pagina: 1