[alg]Optimale lengte van een methode/functie

Pagina: 1 2 Laatste
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 22:54

Janoz

Moderator Devschuur®

!litemod

Topicstarter
Modbreak:Afgesplitst van: [alg] Slechtste programmeervoorbeelden deel 4
PiepPiep schreef op maandag 17 januari 2011 @ 00:31:
[...]

Er was eerst 1 functie die een specifiek iets moet doen maar de andere programmeur vond dat in sommige gevallen die functie 1 dingetje uit de lijst van dingen die hij moest doen niet moest doen.
In plaats van die functie uitbreiden met een parameter om aan te geven of datgene wel of niet gedaan moet worden had hij een kopie gemaakt van de functie en 1 regel eruit weggehaald.
Het probleem hiervan is dat wanneer er een bug in blijkt te zitten de kopie van de functie ook aangepast moet worden. Als je even niet ziet of niet weet dat er een kopie van is dan blijft daar de bug dus bestaan.
Maar goed, het werkelijke probleem is dat jullie functies gewoon te groot zijn en teveel verantwoordelijkheden hebben ;).

[ Voor 7% gewijzigd door Woy op 17-01-2011 17:52 ]

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • PiepPiep
  • Registratie: Maart 2002
  • Laatst online: 18-01-2023
Janoz schreef op maandag 17 januari 2011 @ 10:21:
[...]

Maar goed, het werkelijke probleem is dat jullie functies gewoon te groot zijn en teveel verantwoordelijkheden hebben ;).
Even opgezocht, 53 regels.
Lengte is het probleem niet, het probleem is dat er een kopie van die 53 regels gemaakt was en van het kopie 1 regel verwijdert omdat dat ene kleine dingetje niet gedaan moest worden.
Vergelijk het met :
code:
1
2
3
4
5
6
7
8
9
10
int openFile(string fileWithPath)
{
   ... do stuff ...
}

int openFilePath(string fileName, string filePath)
{
   string fileWithPath = filePath + fileName;
   ... do stuff ...
}

Hierin is ... do stuff ... 50 regels die in beide functies hetzelfde zijn. 1 wijziging in 1 van de functies en ze doen niet meer hetzelfde.

486DX2-50 16MB ECC RAM 4x 500MB Drive array 1.44MB FDD MS-Dos 6.22


Acties:
  • 0 Henk 'm!

  • CodeCaster
  • Registratie: Juni 2003
  • Niet online

CodeCaster

Can I get uhm...

Daar maak je dan toch een overload van 8)7

code:
1
2
3
4
5
6
7
8
9
int openFile(string fileWithPath)
{
   ... do stuff ...
}

int openFilePath(string fileName, string filePath)
{
   return openFile(filePath + fileName);
}

Ik zou die argumenten sowieso andersom doen trouwens, eerst het pad en dan de bestandsnaam. Maar dat is een persoonlijke voorkeur en een richtlijn die wij intern ook gebruiken.

[ Voor 39% gewijzigd door CodeCaster op 17-01-2011 10:51 ]

https://oneerlijkewoz.nl
Het ergste moet nog komen / Het leven is een straf / Een uitgestrekte kwelling van de wieg tot aan het graf


Acties:
  • 0 Henk 'm!

  • PiepPiep
  • Registratie: Maart 2002
  • Laatst online: 18-01-2023
Precies, en niet 2 functies die volgens een diff 1 regel verschillen.

486DX2-50 16MB ECC RAM 4x 500MB Drive array 1.44MB FDD MS-Dos 6.22


Acties:
  • 0 Henk 'm!

  • Davio
  • Registratie: November 2007
  • Laatst online: 06-01 16:46
Sowieso moet er toch een lampje gaan branden als je als programmeur aan het copy-pasten bent...

Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 23:43
Gomez12 schreef op maandag 17 januari 2011 @ 08:53:
[...]


Maarja, dat is ook 1 van de redenen waarom ik voorstander ben van een programma circa 1x per 5 jaar te herschrijven
Herschrijven 8)7
Refactoren, OK, maar dat doe je constant.

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • CodeCaster
  • Registratie: Juni 2003
  • Niet online

CodeCaster

Can I get uhm...

Wat zei Joel daar ook alweer over?
Netscape 6.0 is finally going into its first public beta. There never was a version 5.0. The last major release, version 4.0, was released almost three years ago. Three years is an awfully long time in the Internet world. During this time, Netscape sat by, helplessly, as their market share plummeted.

It's a bit smarmy of me to criticize them for waiting so long between releases. They didn't do it on purpose, now, did they?

Well, yes. They did. They did it by making the single worst strategic mistake that any software company can make:

They decided to rewrite the code from scratch.
Oh die was gelukkig pas twee keer genoemd. :X :P

[ Voor 3% gewijzigd door CodeCaster op 17-01-2011 13:21 ]

https://oneerlijkewoz.nl
Het ergste moet nog komen / Het leven is een straf / Een uitgestrekte kwelling van de wieg tot aan het graf


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 22:54

Janoz

Moderator Devschuur®

!litemod

Topicstarter
PiepPiep schreef op maandag 17 januari 2011 @ 10:29:
[...]

Even opgezocht, 53 regels.
Lengte is het probleem niet,
Mwah... een functie van 53 regels vind ik behoorlijk aan de lange kant en ik vraag me dan ook af of die functie daadwerkelijk 1 verantwoordelijkheid heeft.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • PiepPiep
  • Registratie: Maart 2002
  • Laatst online: 18-01-2023
Janoz schreef op maandag 17 januari 2011 @ 11:17:
[...]

Mwah... een functie van 53 regels vind ik behoorlijk aan de lange kant en ik vraag me dan ook af of die functie daadwerkelijk 1 verantwoordelijkheid heeft.
Er staat voldoende commentaar en af en toe een extra enter om wat alinea vorming te krijgen in de functie en die regels worden ook meegeteld.

486DX2-50 16MB ECC RAM 4x 500MB Drive array 1.44MB FDD MS-Dos 6.22


Acties:
  • 0 Henk 'm!

  • jip_86
  • Registratie: Juli 2004
  • Laatst online: 02:03
whoami schreef op maandag 17 januari 2011 @ 11:06:
[...]


Herschrijven 8)7
Refactoren, OK, maar dat doe je constant.
Herschrijven op basis van huidige inzichten kan toch. Ik heb nu een afstudeeropdracht waarbij ik de achterliggende tabellen anders opzet. Daar moet je ook stukken voor herschrijven of anders schrijven.

Als je in verband met beschikbare tijd en resources kiest voor een iets minder mooie oplossing en je doet dat een aantal keer kan het wel eens goed zijn de schop er eens in te zetten.

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 22:54

Janoz

Moderator Devschuur®

!litemod

Topicstarter
PiepPiep schreef op maandag 17 januari 2011 @ 12:17:
[...]

Er staat voldoende commentaar en af en toe een extra enter om wat alinea vorming te krijgen in de functie en die regels worden ook meegeteld.
Ik vindt 15 regels al tegen de lange kant aanlopen.
Het feit dat je alinea vorming hebt geeft dus eigenlijk al aan dat er meerdere taken binnen die functie zelf geimplementeerd zijn.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 23:43
@Jip: Ik deel de mening van Woy en van Joel hieromtrent hoor ...

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:05

.oisyn

Moderator Devschuur®

Demotivational Speaker

Janoz schreef op maandag 17 januari 2011 @ 12:38:
[...]


Ik vindt 15 regels al tegen de lange kant aanlopen.
Het feit dat je alinea vorming hebt geeft dus eigenlijk al aan dat er meerdere taken binnen die functie zelf geimplementeerd zijn.
En al je locals lekker in classes stoppen. Jippie. :/

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!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 22:54

Janoz

Moderator Devschuur®

!litemod

Topicstarter
Ik doe het nu al een tijdje en ik moet zeggen dat het inderdaad eerst wat tegen mijn normale werkwijze in ging, maar uiteindelijk wordt alles wel weer een stuk leesbaarder.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:05

.oisyn

Moderator Devschuur®

Demotivational Speaker

Als je álle code zo schrijft ga ik me dan wel erg zorgen maken om de performance. Maar ik heb geen idee hoe een Java jiter daarmee om zou gaan.

En ook kun je dan niet meer makkelijk returnen uit een inner loop oid.

[ Voor 20% gewijzigd door .oisyn op 17-01-2011 14:04 ]

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!

  • CodeCaster
  • Registratie: Juni 2003
  • Niet online

CodeCaster

Can I get uhm...

Zeggen dat vijftien regels lang is voor een functie, zonder dat je weet wat 'ie doet? Zeker importfunctionaliteit (wat je al snel hebt als je met bestanden werkt) kun je soms beter imperatief/procedureel doen dan strikt OO waarbij je voor elk lullig, éénmalig voorkomend taakje een nieuwe procedure of zelfs klasse mag schrijven, dan blijft het nog overzichtelijk doordat alle acties die met de data worden uitgevoerd op één plek staan.

Hier tegenover staat natuurlijk dat vijf niveaus diep nesten en for-loops die niet op twee pagina's passen een drama zijn om te onderhouden wanneer het importformaat eens wijzigt.

En ontopic-gevalletje, volgens mij al eerder door mij genoemd, maar ik kwam hem net wéér een keer of twintig tegen:
Delphi:
1
2
   frmfoo.showmodal;
   if frmfoo.okpressed then

Waar was ShowModal ook alweer goed voor? :'(

https://oneerlijkewoz.nl
Het ergste moet nog komen / Het leven is een straf / Een uitgestrekte kwelling van de wieg tot aan het graf


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:05

.oisyn

Moderator Devschuur®

Demotivational Speaker

Wat is daar mis mee dan? Je laat eerst een modal dialog zien, en als die call returnt dan kun je kijken of er op Ok of op Cancel gedrukt was. Zo zou het in win32 iig werken, geen idee hoe de Delphi API daarmee omgaat.

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!

  • alwinuzz
  • Registratie: April 2008
  • Laatst online: 22:14

Acties:
  • 0 Henk 'm!

  • CodeCaster
  • Registratie: Juni 2003
  • Niet online

CodeCaster

Can I get uhm...

@.oisyn: er is handmatig een boolean "okpressed" op ieder form aangemaakt, terwijl als je de ModalResult-property van de OK- en Cancel-buttons zou instellen gewoon de returnwaarde van ShowModal zou kunnen afvangen:
Delphi:
1
if frmfoo.showmodal = mrOk then

:)

[ Voor 51% gewijzigd door CodeCaster op 17-01-2011 14:17 ]

https://oneerlijkewoz.nl
Het ergste moet nog komen / Het leven is een straf / Een uitgestrekte kwelling van de wieg tot aan het graf


Acties:
  • 0 Henk 'm!

  • Davio
  • Registratie: November 2007
  • Laatst online: 06-01 16:46
CodeCaster schreef op maandag 17 januari 2011 @ 14:03:
Zeggen dat vijftien regels lang is voor een functie, zonder dat je weet wat 'ie doet? Zeker importfunctionaliteit (wat je al snel hebt als je met bestanden werkt) kun je soms beter imperatief/procedureel doen dan strikt OO waarbij je voor elk lullig, éénmalig voorkomend taakje een nieuwe procedure of zelfs klasse mag schrijven, dan blijft het nog overzichtelijk doordat alle acties die met de data worden uitgevoerd op één plek staan.

Hier tegenover staat natuurlijk dat vijf niveaus diep nesten en for-loops die niet op twee pagina's passen een drama zijn om te onderhouden wanneer het importformaat eens wijzigt.

En ontopic-gevalletje, volgens mij al eerder door mij genoemd, maar ik kwam hem net wéér een keer of twintig tegen:
Delphi:
1
2
   frmfoo.showmodal;
   if frmfoo.okpressed then

Waar was ShowModal ook alweer goed voor? :'(
Zo doe ik het alleen maar in C# met .NET.

Vaak zo:
C#:
1
2
3
4
5
6
7
using(InvulForm invulForm = new InvulForm())
{
    if(invulForm.ShowDialog() != DialogResult.OK) return;
    
    // Sla properties van het form op
   // Bijv. user.Name = invulForm.NewName;
}

Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 23:43
Janoz schreef op maandag 17 januari 2011 @ 14:00:
Ik doe het nu al een tijdje en ik moet zeggen dat het inderdaad eerst wat tegen mijn normale werkwijze in ging, maar uiteindelijk wordt alles wel weer een stuk leesbaarder.
wat ?
Bedoel je dat je je local variables 'promoveert' tot class-members ?

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 23:43
.oisyn schreef op maandag 17 januari 2011 @ 14:05:
Wat is daar mis mee dan? Je laat eerst een modal dialog zien, en als die call returnt dan kun je kijken of er op Ok of op Cancel gedrukt was. Zo zou het in win32 iig werken, geen idee hoe de Delphi API daarmee omgaat.
Volgens mij returned ShowModal een enum, die aangeeft wat het 'Modalresult' was. In Delphi kan dit dus mrOk, mrCancel, mrYes, mrNo, zijn als ik het me nog goed herinner.

Idem in .NET: ShowDialog() returned ook een DialogResult enum waarde.

/spuit-elvendertig dus

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 22:54

Janoz

Moderator Devschuur®

!litemod

Topicstarter
niet meer makkelijk returnen uit een inner loop oid.
Hoezo niet?
CodeCaster schreef op maandag 17 januari 2011 @ 14:03:
Zeggen dat vijftien regels lang is voor een functie, zonder dat je weet wat 'ie doet? Zeker importfunctionaliteit (wat je al snel hebt als je met bestanden werkt) kun je soms beter imperatief/procedureel doen dan strikt OO waarbij je voor elk lullig, éénmalig voorkomend taakje een nieuwe procedure of zelfs klasse mag schrijven, dan blijft het nog overzichtelijk doordat alle acties die met de data worden uitgevoerd op één plek staan.
Mwah, juist het toevoegen van de extra methodes verhoogt de leesbaarheid. Wanneer je alles laat staan kun je op detail niveau heel goed zien wat er gebeurt, maar het hogere niveau is nauwelijks terug te vinden.

Wanneer pieppiep zelf al aangeeft dat de code te partitioneren is (alinea's toevoegen) geeft al aan dat de methode uit verschillende stappen bestaat. In 99.9% van de gevallen kun je die delen weer in aparte methoden onderbrengen. Hierdoor is het overzicht van de originele methode beter. Je hebt immers geen 53 regels meer nodig om te zien wat er gedaan wordt. Daarnaast bieden de nieuw geextraheerde methoden een ideale plek om op de standaard plek (voor de methode) commentaar te geven op wat daar gebeurt (en bij een fatsoenlijke IDE krijg je die terug wanneer je de informatie opvraagt bij die methode)

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 22:54

Janoz

Moderator Devschuur®

!litemod

Topicstarter
whoami schreef op maandag 17 januari 2011 @ 14:23:
[...]

wat ?
Bedoel je dat je je local variables 'promoveert' tot class-members ?
Dat ik eerder uit automatisme eigenlijk alles compleet threadsave maakte terwijl dat eigenlijk vaak helemaal niet nodig is omdat het object toch maar binnen 1 thread bruikbaar was. Niet dat alles nu een classmember wordt, maar ik merk dat het prettiger werkt wanneer niet alle methoden een berg parameters hebben omdat ik eigenlijk overal de state aan het meegeven ben die eigenlijk ook wel in het object zelf zou kunnen.

Als voorbeeld had ik een SAX parser waar ik op een gegeven moment in de abstracte parser implementatie zelf de tag stack bij ging houden ipv het bij de methoden mee te geven en enkele utilility methoden rechtstreeks op die stack te laten wereken ipv methoden maken die eigenlijk ook wel static konden worden omdat ze toch niks met het object zelf deden.
AbstractSaxParser.java

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • PiepPiep
  • Registratie: Maart 2002
  • Laatst online: 18-01-2023
Janoz schreef op maandag 17 januari 2011 @ 14:37:
[...]


Hoezo niet?


[...]

Mwah, juist het toevoegen van de extra methodes verhoogt de leesbaarheid. Wanneer je alles laat staan kun je op detail niveau heel goed zien wat er gebeurt, maar het hogere niveau is nauwelijks terug te vinden.

Wanneer pieppiep zelf al aangeeft dat de code te partitioneren is (alinea's toevoegen) geeft al aan dat de methode uit verschillende stappen bestaat. In 99.9% van de gevallen kun je die delen weer in aparte methoden onderbrengen. Hierdoor is het overzicht van de originele methode beter. Je hebt immers geen 53 regels meer nodig om te zien wat er gedaan wordt. Daarnaast bieden de nieuw geextraheerde methoden een ideale plek om op de standaard plek (voor de methode) commentaar te geven op wat daar gebeurt (en bij een fatsoenlijke IDE krijg je die terug wanneer je de informatie opvraagt bij die methode)
Sorry, ik ben het hier echt totaal niet mee eens.
Dat voorbeeld van extract till you drop vind ik ook vreselijk om te zien. Het eerste stukje code was gewoon goed leesbaar en het laatste is een hoop kleine dingetjes die gezamelijk 'iets' doen.
Een fatsoenlijke IDE laat zien wat een functie doet als je met je muis erover gaat maar dat wil ik helemaal niet doen als het niet nodig is. In dit extract till you drop moet ik dus telkens met de muis over de code gaan of zelf over het scherm zoeken waar de functie staat en die bekijken of de functienaam moet duidelijk zijn. Als je teveel functies gaat creeren vind ik zelf de namen over het algemeen steeds slechter worden, je kan er mijns inziens beter minder hebben met duidelijkere namen.
Verder is 1 functie van 50 regels die in 5 groepjes van 10 regels met in die 10 regels 5 regels code en 5 regels commentaar veel beter de volgorde te zien.

486DX2-50 16MB ECC RAM 4x 500MB Drive array 1.44MB FDD MS-Dos 6.22


Acties:
  • 0 Henk 'm!

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 17:35
Vergeet ook niet dat een functie weer 4 regels ruimte kost: 1 witregel, 1 regel met functiedeclaratie, 2 regels met accolades. Daarnaast nog wat commentaar natuurlijk. Er past dus minder effectieve code op je scherm, waardoor je het overzicht eerder kwijt raakt.

Vaak maak ik ergens pas een functie van op het moment dat het een herbruikbare unit is, dus als ik hem op een 2e plek nodig heb of dat de control flow anders te complex wordt. 85 regels zonder control flow kan veel overzichtelijker zijn dan diezelfde code over 10 functies verspreid.

[ Voor 9% gewijzigd door MBV op 17-01-2011 15:19 ]


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 22:54

Janoz

Moderator Devschuur®

!litemod

Topicstarter
Het is inderdaad de bedoeling dat je duidelijke functienamen moet hebben. Functienamen die duidelijk omschrijven wat er gebeurt. Wanneer je aangeeft dat je in de knel komt met naamgeving dan komt dat dus waarschijnlijk omdat je veel stukjes code hebt die bijna hetzelfde doen. Dat zou een indicator kunnen zijn van dat het ook iets beter zou kunnen.

Verder over commentaar. In principe zou je zo min mogelijk commentaar moeten gebruiken*. Het grote probleem met commentaar is dat het niet door de compiler wordt gecompileerd, niet door de unittests wordt getest en niet door automatische refactoring meegenomen wordt. Het is een handmatige actie om het commentaar in lijn met de code te houden en niks is schadelijker voor de onderhoudbaarheid wanneer het commentaar niet overeenkomt met de uiteindelijke werking.
Verder is 1 functie van 50 regels die in 5 groepjes van 10 regels met in die 10 regels 5 regels code en 5 regels commentaar veel beter de volgorde te zien.
Als je evenveel commentaar als code nodig hebt om je code leesbaar te houden is er IMHO toch echt iets mis aan code. Daarnaast zul je eerst de afzonderlijke blokjes van 10 regels moeten bekijken wat er precies in dat blok gebeurt voordat je een uitspraak kunt doen over wat de hele methode doet.


* let op, ik zeg zo min mogelijk.Een beetje zoals Einstein ooit zei: "Make things as simple as possible, but not simpler"
MBV schreef op maandag 17 januari 2011 @ 15:18:
Vergeet ook niet dat een functie weer 4 regels ruimte kost: 1 witregel, 1 regel met functiedeclaratie, 2 regels met accolades. Daarnaast nog wat commentaar natuurlijk. Er past dus minder effectieve code op je scherm, waardoor je het overzicht eerder kwijt raakt.
Het doel is niet om je class/module zo kort mogelijk te houden. Het doel is om een enkele functie zo klein mogelijk te houden. Zolang je naamgeving duidelijk is is vervolgens elke functie goed leesbaar zonder dat je de functies zelf weer erbij hoeft te pakken. Maar mocht je ze nodig hebben, met een beetje fatsoenlijke IDE spring je met CTRL-click er heen en met back weer terug naar je originele functie.
Vaak maak ik ergens pas een functie van op het moment dat het een herbruikbare unit is, dus als ik hem op een 2e plek nodig heb of dat de control flow anders te complex wordt. 85 regels zonder control flow kan veel overzichtelijker zijn dan diezelfde code over 10 functies verspreid.
Ik niet. Een verzameling statements die eigenlijk 1 actie uitvoert refactor ik vaak al naar een losse methode met als naam die actie. (Maar eigenlijk ontwikkel ik vaak wat meer topdown waarbij ik mijn hoofd algoritme uittik met nog niet bestaande methoden die ik later implementeer)

Ik ben erg benieuwd naar je lap code van 85 regels die niet overzichtelijker zou kunnen.

[ Voor 46% gewijzigd door Janoz op 17-01-2011 15:29 ]

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • PiepPiep
  • Registratie: Maart 2002
  • Laatst online: 18-01-2023
Zo min mogelijk commentaar vind ik een mooie uitspraak, als de code zelf al leesbaar is hoeft er idd geen commentaar bij.
Ook vind ik vaak het automatisch gegenereerde commentaar onduidelijk en dus overbodig.
Interface naam is IAction en functie heet Execute dan krijg je 'Executes the action.'

Maar een idee van een lange functie.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void StaOpEnGaNaarDeBus()
{
  ZetDeWekkerUit();
  StapUitBed();
  DoeKledingAan();
  GaNaarBeneden();
  ZetComputerAan();
  SchenkMelkIn();
  LogComputerIn();
  MaakBoterhamKlaar();
  OpenTweakersSite();
  while (MelkNietOp && BroodNietOp)
  {
    NeemHapOfSlok();
    LeesNieuwsOfForum();
  }
  ZetComputerUit();
  DoeJasAan();
  GaNaarBuitenEnLoopNaarBus();
}

Ik zie hier niet zo snel dingen die je als groepje in een extra functie kan plaatsen.

486DX2-50 16MB ECC RAM 4x 500MB Drive array 1.44MB FDD MS-Dos 6.22


Acties:
  • 0 Henk 'm!

  • barfieldmv
  • Registratie: Maart 2004
  • Laatst online: 11-04 21:15
PiepPiep schreef op maandag 17 januari 2011 @ 15:53:
Zo min mogelijk commentaar vind ik een mooie uitspraak, als de code zelf al leesbaar is hoeft er idd geen commentaar bij.
Ook vind ik vaak het automatisch gegenereerde commentaar onduidelijk en dus overbodig.
Interface naam is IAction en functie heet Execute dan krijg je 'Executes the action.'

Maar een idee van een lange functie.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void StaOpEnGaNaarDeBus()
{
  ZetDeWekkerUit();
  StapUitBed();
  DoeKledingAan();
  GaNaarBeneden();
  ZetComputerAan();
  SchenkMelkIn();
  LogComputerIn();
  MaakBoterhamKlaar();
  OpenTweakersSite();
  while (MelkNietOp && BroodNietOp)
  {
    NeemHapOfSlok();
    LeesNieuwsOfForum();
  }
  ZetComputerUit();
  DoeJasAan();
  GaNaarBuitenEnLoopNaarBus();
}

Ik zie hier niet zo snel dingen die je als groepje in een extra functie kan plaatsen.
Dit is dan wel weer een goed moment om te kijken of je een soort XML config file nodig heb met plugins en interfaces.

Voor mij mag een functie een regel of 40-50 zijn, das ongeveer een scherm vol. Dat moet uit ongeveer 3-4 alinea's bestaan en eentje voor fout afhandeling. Zodra daaronder/in de buurt een functie komt met een zelfde alinea dan moet dat in een functie, anders niet blijf je bezig en krijg je van de vreselijke 1-3 regel code functies die niet handig te debuggen zijn.

Acties:
  • 0 Henk 'm!

  • Davio
  • Registratie: November 2007
  • Laatst online: 06-01 16:46
Ja, je kan ook teveel extracten en elke keer als je 2 statements in een methode hebt een nieuwe methode aanmaken.

Je moet ook niet zozeer naar het aantal regels kijken als wel naar hoeveel taken een methode uitvoert.
Een methode zou in principe maar één taak uit moeten voeren waarbij die taak de ene keer iets meer omvat dan de andere. En dan kun je dingen die je vaak doet (database-connectie) wel extracten.

Even een losse tip: Ik gebruik voor Visual Studio de extensie VS10x Code Map.
Hiermee heb ik in een sidebar een mooi overzicht van mijn properties, methods en events etc. mooi gegroepeerd per zelf aangegeven region.

Acties:
  • 0 Henk 'm!

  • PiepPiep
  • Registratie: Maart 2002
  • Laatst online: 18-01-2023
Ik bedenk me dat dit waarschijnlijk net zo persoonlijk is als of er nou wel of niet goto gebruikt mag worden.

486DX2-50 16MB ECC RAM 4x 500MB Drive array 1.44MB FDD MS-Dos 6.22


Acties:
  • 0 Henk 'm!

  • Jan_V
  • Registratie: Maart 2002
  • Laatst online: 22:47
Volgens mij ben ik het compleet met jou eens voor wat betreft het maken van code, zeker ook Clean Code gelezen?

Ik snap echter niet waarom je dit hebt gemaakt:
Java:
1
2
3
4
5
6
7
8
9
10
11
 protected List<String> getStackTail(int offset) {
                return stack.subList(offset, stack.size());
        }
        
        protected String getNodeName() {
                return stack.getLast();
        }
        
        protected boolean isStackSize(int i) {
                return i == stack.size();
        }

Dit lijken gewoon wrappers van bestaande functionaliteit. Dat vind ik dan weer iets minder mooi. getStackTail zou nog kunnen, maar de andere 2 lijken mij op het eerste gezicht overbodig.

Battle.net - Jandev#2601 / XBOX: VriesDeJ


Acties:
  • 0 Henk 'm!

  • Davio
  • Registratie: November 2007
  • Laatst online: 06-01 16:46
Ik zou van de tweede dan sowieso een property maken, kan dat ook in Java?

C#:
1
protected String NodeName { get { return stack.getLast(); } }

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 22:54

Janoz

Moderator Devschuur®

!litemod

Topicstarter
Jan_V schreef op maandag 17 januari 2011 @ 16:09:
[...]

Volgens mij ben ik het compleet met jou eens voor wat betreft het maken van code, zeker ook Clean Code gelezen?

Ik snap echter niet waarom je dit hebt gemaakt:
Java:
1
2
3
4
5
6
7
8
9
10
11
 protected List<String> getStackTail(int offset) {
                return stack.subList(offset, stack.size());
        }
        
        protected String getNodeName() {
                return stack.getLast();
        }
        
        protected boolean isStackSize(int i) {
                return i == stack.size();
        }

Dit lijken gewoon wrappers van bestaande functionaliteit. Dat vind ik dan weer iets minder mooi. getStackTail zou nog kunnen, maar de andere 2 lijken mij op het eerste gezicht overbodig.
stack is private en dit zijn de enige 3 bewerkingen die ik nodig had, en ja, ik heb ook Clean Code gelezen. Ga binnenkort weer 10 boeken weggeven tijdens een workshop waarmee ik mijzelf member of the CLUB maak ;)
Davio schreef op maandag 17 januari 2011 @ 16:13:
Ik zou van de tweede dan sowieso een property maken, kan dat ook in Java?

C#:
1
protected String NodeName { get { return stack.getLast(); } }
Java kent geen properties, maar enkel getters en setters. Je C# voorbeeld is dus equivalent (en wanneer ik C# gedaan zou hebben zou ik het inderdaad ook op jou manier doen).

[ Voor 24% gewijzigd door Janoz op 17-01-2011 16:27 ]

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 22:54

Janoz

Moderator Devschuur®

!litemod

Topicstarter
PiepPiep schreef op maandag 17 januari 2011 @ 15:53:

code:
1
2
3
4
void StaOpEnGaNaarDeBus()
{
// ..
}
Het probleem met deze code is dat hij beweert 'sta op en ga naar bus' doet, terwijl er voornamelijk gegeten, gedronken en nieuwsgelezen wordt. Daarnaast zou ik 'zet wekker uit' eerder thuis vinden horen bij de trigger die je wakker maakt en dus eigenlijk een abstractie niveau hoger moeten zitten ;).

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • barfieldmv
  • Registratie: Maart 2004
  • Laatst online: 11-04 21:15
Janoz schreef op maandag 17 januari 2011 @ 16:19:
[...]

stack is private en dit zijn de enige 3 bewerkingen die ik nodig had, en ja, ik heb ook Clean Code gelezen. Ga binnenkort weer 10 boeken weggeven tijdens een workshop waarmee ik mijzelf member of the CLUB maak ;)
[...]

Java kent geen properties, maar enkel getters en setters. Je C# voorbeeld is dus equivalent (en wanneer ik C# gedaan zou hebben zou ik het inderdaad ook op jou manier doen).
Ik ben 'nu' clean code aan het lezen. Veel informatie en goede voorbeelden om over je code na te denken. Nu de rest hier nog meekrijgen.

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:05

.oisyn

Moderator Devschuur®

Demotivational Speaker

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void foo()
{
    // wat code

    for (int i = 0; i < num; i++)
    {
        if (conditie1(i))
            return;
        if (conditie2(i)
            break;

        // wat andere code
    }
}

Als je de inhoud van de for loop verhuist naar een eigen functie, dan heb je dus een returnvalue met 3 mogelijke waarden, waar je dan weer op moet controleren om te bepalen of je moet breaken of returnen oid. Het wordt er vaak ook niet leesbaarder op ofzo, dus dan kun je je afvragen waarom je sowieso nou per se zo nodig de boel wilt opdelen omdat iemand heeft bepaald dat X regels nou eenmaal te lang is.

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!

  • PiepPiep
  • Registratie: Maart 2002
  • Laatst online: 18-01-2023
Oh, maar dan krijg je weer de discussie of een functie maar 1 einde mag hebben of wel halverwege return mag doen :)

486DX2-50 16MB ECC RAM 4x 500MB Drive array 1.44MB FDD MS-Dos 6.22


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 22:54

Janoz

Moderator Devschuur®

!litemod

Topicstarter
@.oisyn
Ah op die manier, maar als je de initialisatie code extract, en wat andere code extract dan zit (conditie codes zijn al extracted) dan zit je nog steeds ruim onder de 15 :).

Maar ik moet zeggen dat ik een dergelijke constructie niet veel gebruik, maar dat zal ook wel komen omdat we compleet verschillende typen software ontwikkelen.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:05

.oisyn

Moderator Devschuur®

Demotivational Speaker

whoami schreef op maandag 17 januari 2011 @ 14:23:
[...]

wat ?
Bedoel je dat je je local variables 'promoveert' tot class-members ?
Wat ík bedoelde is dat je een class maakt voor het opslaan van de local state, zodat je niet 15 argumenten mee hoeft te geven aan een functie, en dat een functie dan ook (zeker in het geval van Java) die argumenten aan kan passen.

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!

  • Guldan
  • Registratie: Juli 2002
  • Laatst online: 01-06 21:02

Guldan

Thee-Nerd

Ik zelf kijk altijd naar de volgende zaken hoewel het natuurlijk een mening per persoon is:
1.Code moet duidelijk zijn;
2.Het moet onderhoudbaar zijn;
3.Wanneer een methode groot wordt: Splits deze op maar laat het de duidelijkheid niet in de weg zitten. dwz. Als je het op kan splitsen maar het voegt alleen complexiteit toe qua onderhoud omdat het minder duidelijk is. Doe het dan niet. (of zorg ervoor dat het wel duidelijk is natuurlijk :))

You know, I used to think it was awful that life was so unfair. Then I thought, wouldn't it be much worse if life were fair, and all the terrible things that happen to us come because we actually deserve them?


Acties:
  • 0 Henk 'm!

  • Avalaxy
  • Registratie: Juni 2006
  • Laatst online: 23:03
Aanrader? Ook als je Code Complete 2 hebt?

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 22:54

Janoz

Moderator Devschuur®

!litemod

Topicstarter
Dus eigenlijk een soort structs? Dat doe ik niet. Ik doe eerder wat whoami aangeeft.

@avalaxy
Ik heb code complete nog niet gelezen, maar als ik dit mag geloven is Clean Code zeker een aanvulling. Daarnaast kost het boek nog geen E19 op amazon, dus om de prijs hoef je het ook niet te laten.

[ Voor 68% gewijzigd door Janoz op 17-01-2011 16:53 ]

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 17:35
Janoz schreef op maandag 17 januari 2011 @ 15:21:

Het doel is niet om je class/module zo kort mogelijk te houden. Het doel is om een enkele functie zo klein mogelijk te houden.
Dat is heel simpel: als er meer dan 2 regels in staat, kan je het opsplitsen in 2 functies. Ik zou hem andersom willen stellen: mijn doel is een functie zo groot mogelijk te maken, zodat hij nog altijd 1 coherent ding doet, met een maximum van 50 regels (ongeveer 1 scherm). Het hangt heel erg af van het soort project hoe groot mijn functies worden, vaak maar een paar regels, maar er zitten altijd een paar functies tussen van 50 regels. Bijv een functie om de argumenten te verwerken, command-line help weer te geven, dat soort dingen. Ik zal misschien eens de LOC-statistieken van mijn afstudeerproject (parser met visitor-pattern, dus niet helemaal representatief) opzoeken, kijken hoe lang de langste functie was.
Ik niet. Een verzameling statements die eigenlijk 1 actie uitvoert refactor ik vaak al naar een losse methode met als naam die actie.
Dus als jij een functie hebt van 50 statements die 1 actie uitvoeren, dan refactor je die naar een functie van 50 statements die 1 actie uitvoeren. Leg uit, hoe doe je dat? 8)7
Ik ben erg benieuwd naar je lap code van 85 regels die niet overzichtelijker zou kunnen.
Ik heb even geen voorbeeld dat ik hier neer wil dumpen, maar laatst had ik een python-script dat 30 argumenten verwerkte. application.py had dus een switch/case van 100 regels waarin wat booleans werden aan/uit gezet (elke case had hooguit 2 regels, bij meer regels had ik er een functie van gemaakt). Betere suggesties?
Python:
1
2
3
4
def handleArgs(argsList)
    if (argName == 'first'):
        handleArgFirst(head(argsList))
    handleArgsNotFirst(tail(args))

Zoiets dus? :'(

[ Voor 5% gewijzigd door MBV op 17-01-2011 17:00 ]


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:05

.oisyn

Moderator Devschuur®

Demotivational Speaker

Janoz schreef op maandag 17 januari 2011 @ 16:42:
Dus eigenlijk een soort structs? Dat doe ik niet. Ik doe eerder wat whoami aangeeft.
Dus je gaat members toevoegen aan een class die alleen maar zinnig zijn tijdens een bepaalde method call?

Dus niet dat je bijv. een inner class maakt met de betreffende state en de methods die hebt geëxtract dan members van die inner class maakt dan he.

[ Voor 20% gewijzigd door .oisyn op 17-01-2011 17: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!

  • FragFrog
  • Registratie: September 2001
  • Laatst online: 02-06 01:19
MBV schreef op maandag 17 januari 2011 @ 16:56:
Ik heb even geen voorbeeld dat ik hier neer wil dumpen, maar laatst had ik een python-script dat 30 argumenten verwerkte.
Bedoel je dan enkele argumenten met 30 mogelijke waardes? Of daadwerkelijk 30 argumenten? In dat laatste geval is de lengte van je functie niet verwonderlijk, maar ook niet het grootste probleem ;)

Zelf hou ik ~ 15 regels per functie aan als ideaal maximum. Inclusief comments moet het makkelijk op een scherm kunnen, en een class probeer ik binnen 150 regels te houden. Ga ik daar overheen is het bijna altijd wel mogelijk om dingen te refactoren. Juist omdat je gedurende de levensduur van je applicatie nog wel dingen erbij wilt zetten, bugfixes wilt implementeren, etc. Een OS project waar ik aan werk heeft classes van 12.000 regels ertussen zitten, zelfs de meest simpele bugfix kost me daar uren aan uitzoekwerk omdat alles weer linkt naar alles en een fix op de ene plek kan vanalles stuk maken op een compleet andere plek.

Overigens hoeft het gebruik van korte functies niet te betekenen dat je ook veel class variabelen gebruikt, of ellenlange parameterlijsten. Als je echt veel verschillende informatie van een functie ook in meerdere andere functies wilt hebben kun je daar prima objecten / structs / andere taal-specifieke wrappers voor gebruiken. En die kun je juist weer makkelijk refactoren zodat je code er alleen maar beter leesbaar door wordt, in plaats van vijftien verschillende variabelen continue gebruiken in een functie van honderd regels.

[ Voor 20% gewijzigd door FragFrog op 17-01-2011 17:14 ]

[ Site ] [ twitch ] [ jijbuis ]


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 22:54

Janoz

Moderator Devschuur®

!litemod

Topicstarter
MBV schreef op maandag 17 januari 2011 @ 16:56:
Dus als jij een functie hebt van 50 statements die 1 actie uitvoeren, dan refactor je die naar een functie van 50 statements die 1 actie uitvoeren. Leg uit, hoe doe je dat? 8)7
In een methode van >50 statements zou ik dan inderdaad beginnen om die 50 statements te extracten naar een nieuwe method. Daarna verwacht ik dat ik die 50 regels nog wel verder op kan delen.
Ik heb even geen voorbeeld dat ik hier neer wil dumpen, maar laatst had ik een python-script dat 30 argumenten verwerkte. application.py had dus een switch/case van 100 regels waarin wat booleans werden aan/uit gezet (elke case had hooguit 2 regels, bij meer regels had ik er een functie van gemaakt). Betere suggesties?
Python:
1
2
3
4
def handleArgs(argsList)
    if (argName == 'first'):
        handleArgFirst(head(argsList))
    handleArgsNotFirst(tail(args))

Zoiets dus? :'(
In dat geval zou ik zeker Clean Code eens lezen aangezien een argumenten parser daar 1 van de case studies is.

In het kort, ja, het kan korter en netter.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 22:54

Janoz

Moderator Devschuur®

!litemod

Topicstarter
.oisyn schreef op maandag 17 januari 2011 @ 16:59:
Dus je gaat members toevoegen aan een class die alleen maar zinnig zijn tijdens een bepaalde method call?

Dus niet dat je bijv. een inner class maakt met de betreffende state en de methods die hebt geëxtract dan members van die inner class maakt dan he.
Niet bij een bepaalde method call, wel bij bepaalde method calls.

Kijk, ik ga niet de 'je moet zo min mogelijk parameter gebruiken'-regel oplossen door de 6 parameters die mijn methode nodig heeft te wrappen in een class en die meegeven. Kijk, maar 1 parameter \o/. Ik kijk eerder of ik ze alle 6 wel nodig heb en of het echt parameters zouden zijn. Uiteindelijk blijkt dan vaak dat enkele van die parameters eigenlijk gewoon state zijn die je overal in je class gebruikt. Maar ik vind het lastig om hier zo over te discussiëren zonder concrete voorbeelden omdat je dan nogal snel tegen terminologie verschillen aanloopt.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 18:27

alienfruit

the alien you never expected

Ach, ik heb hier een klasse rondslingeren van 1760 regels aan code. Een echte God class, die de flow van een systeem managed. Met vier interne state machines die afhankelijk zijn van externe processen (distributed media ontvangst over GPRS, CCA/CCR over SOAP, webservice-based event logging). Zonder unit tests, end-to-end testing. Een prima kandidaat om te refactoren als er tijd en geld voor was...

[ Voor 13% gewijzigd door alienfruit op 17-01-2011 23:33 ]


Acties:
  • 0 Henk 'm!

  • Caelorum
  • Registratie: April 2005
  • Laatst online: 22:45
alienfruit schreef op maandag 17 januari 2011 @ 23:24:
Ach, ik heb hier een klasse rondslingeren van 1760 regels aan code. Een echte God class, die de flow van een systeem managed. Met vier interne state machines die afhankelijk zijn van externe processen (distributed media ontvangst over GPRS, CCA/CCR over SOAP, webservice-based event logging). Zonder unit tests, end-to-end testing. Een prima kandidaat om te refactoren als er tijd en geld voor was...
Dat zoiets kan bestaan is al onbegrijpelijk!

Acties:
  • 0 Henk 'm!

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 17:35
@alienfruit: Ik heb hier een klasse van 15000 regels in de CPP, de headerfile is 2000 regels. Een soort mother-of-all-factories, maar dan met nog 'een paar' functies die handig zijn om overal bij de hand te hebben :P Unittesten is bijna onmogelijk, omdat bijna alle klasses afhankelijk zijn van die klasse, en daardoor de hele wereld wordt geinclude.

Niet zelf geschreven trouwens ;)

Acties:
  • 0 Henk 'm!

  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 18:27

alienfruit

the alien you never expected

Caelorum schreef op maandag 17 januari 2011 @ 23:42:
Dat zoiets kan bestaan is al onbegrijpelijk!
Ik ben al blij dat het stabiel werkt...

Acties:
  • 0 Henk 'm!

  • CodeCaster
  • Registratie: Juni 2003
  • Niet online

CodeCaster

Can I get uhm...

Caelorum schreef op maandag 17 januari 2011 @ 23:42:
[...]

Dat zoiets kan bestaan is al onbegrijpelijk!
Dat valt wel mee, hoor. :) Zoals in elk vakgebied is lang niet iedereen de purist die we allemaal (niet) als collega wensen. Er schijnen nu eenmaal mensen rond te lopen die nette code onbelangrijk vinden, zolang het maar werkt. Soms is de tijd gewoon op. Soms zijn die mensen manager en leggen ze die mening op aan hun developers, soms zijn het de programmeurs zelf die met die insteek rondlopen. En ze leveren wellicht nog sneller op dan mensen die netjes programmeren ook. Dat onderhoud een crime is bagatelliseren ze vervolgens.

[ Voor 13% gewijzigd door CodeCaster op 18-01-2011 11:14 ]

https://oneerlijkewoz.nl
Het ergste moet nog komen / Het leven is een straf / Een uitgestrekte kwelling van de wieg tot aan het graf


Acties:
  • 0 Henk 'm!

  • Davio
  • Registratie: November 2007
  • Laatst online: 06-01 16:46
Als er alleen maar puristen rondlopen komt een product nooit af.

Elke keer als het product bijna af is, zou er een nieuwe taal / methodiek uitkomen die helemaal hip is en wordt alles opnieuw geschreven.

How many programmers does it take to change a lightbulb?

Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Bovendien vind ik 1760 regels nog wel meevallen. Natuurlijk gaat er iets goed fout als dat meer de norm is, maar een enkele class die zo groot is zou ik echt geen ramp vinden.

“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!

  • Jan_V
  • Registratie: Maart 2002
  • Laatst online: 22:47
MBV schreef op dinsdag 18 januari 2011 @ 10:59:
@alienfruit: Ik heb hier een klasse van 15000 regels in de CPP, de headerfile is 2000 regels. Een soort mother-of-all-factories, maar dan met nog 'een paar' functies die handig zijn om overal bij de hand te hebben :P Unittesten is bijna onmogelijk, omdat bijna alle klasses afhankelijk zijn van die klasse, en daardoor de hele wereld wordt geinclude.

Niet zelf geschreven trouwens ;)
In dit boek het boek Working Effectively with Legacy Code (http://www.amazon.com/Wor...el-Feathers/dp/0131177052) wordt uitgelegd hoe je zoiets 'heel eenvoudig' kunt doen.
Tijdens het lezen vond ik de theorie op zich wel leuk, maar inderdaad, met zo'n enorme klasse zie ik dat in de praktijk niet snel gebeuren. Dat is het nadeel vaak, in theorie weet je vaak precies wel hoe het moet, maar ja, de praktijk is altijd anders.

Battle.net - Jandev#2601 / XBOX: VriesDeJ


Acties:
  • 0 Henk 'm!

  • kwaakvaak_v2
  • Registratie: Juni 2009
  • Laatst online: 02-06 12:29
Caelorum schreef op maandag 17 januari 2011 @ 23:42:
[...]

Dat zoiets kan bestaan is al onbegrijpelijk!
Waar gewerkt wordt op basis van betaalde uren, i.p.v onbeperkte tijd die ook nog eens niks kost, is dat helemaal niet zo heel raar hoor.

Soms heb je tijd om iets helemaal tot op het bot mooi te maken, maar soms moet het gewoon af in xx uur omdat er gewoon niet meer geld is. En ja dan kun je zeggen dat je het niet zo willen doen, maar dat vind de instantie die mijn hypotheek maandelijks afschrijft niet zo'n heel goed idee. Principe's zijn leuk, maar je verdient er zo weinig aan of mee ;)

Driving a cadillac in a fool's parade.


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 22:54

Janoz

Moderator Devschuur®

!litemod

Topicstarter
Maar die god class is er toch niet ineens. Die 'groeit' toch zo? Als er blijkbaar geld was om er pukkels tegenaan te maken dan was er dus eigenlijk ook geld geweest om het pukeltje er netjes in te hangen. Bij het eerste pukkeltje had het misschien marginaal langer geduurd, maar de daaropvolgende pukkels zullen allemaal korter duren.

Ik herken het wel. Ik zit nu op een project waar toch wel best wat mis is. Maar wanneer ik dat met een beetje scouting insteek benader maak ik het bij elke fix of uitbreiding telkens weer een stukje netter. Paar unittestjes erbij, stukje refactoren. Dat kost echt geen extra tijd. Die tests zul je toch wel moeten schrijven (zeker met brakke software kun je niet zonder tests om voor jezelf te bewijzen dat de boel blijft werken). Dat kost je misschien een half uurtje, maar die win je direct terug wanneer je je aanpassing doet omdat je je test kunt blijven gebruiken.

Er is maar 1 iemand die echt verantwoordelijk is voor het brak blijven van de software waar je aan moet werken, en dat ben je toch echt zelf. Verkondigen dat je er de tijd niet voor krijgt is een zwak excuus.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • Jan_V
  • Registratie: Maart 2002
  • Laatst online: 22:47
Nou ja, een zwak excuus...het is in ieder geval geen goed excuus.

Ik kan me voorstellen dat sommigen het niet 'durven' te doen, omdat ze niet volledig bekend zijn met de materie. Die wel ongeveer weten hoe iets verbeterd moet worden, maar niet precies. Wanneer je dan iets gaat refactoren ben je vaak al veel te snel en te diep bezig. Dan wil je het al snel te groot aanpakken.

Moet toegeven dat ik ook geen grote wijzigingen durf te maken bij m'n nieuwe werkgever. Wil de theorie eerst uitproberen op iets kleinere projecten (en wat credits opbouwen), voordat ik grote veranderingen ga toepassen.

Kan uiteraard nooit kwaad om een unittest project te bouwen. Hoeft niet eens een unit testen te bevatten, kan ook prima met scenario testen (in het begin), omdat je anders overal al snel DI moet gaan toepassen of allemaal gebinde objecten moet gaan mocken op een of andere manier.

Battle.net - Jandev#2601 / XBOX: VriesDeJ


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 22:54

Janoz

Moderator Devschuur®

!litemod

Topicstarter
Op zich hoef je weinig aan je werkwijze aan te passen. Als je een bak lelijke code voor je neus krijgt waar je een aanpassing in moet doen begin je toch altijd met uitzoeken wat er op dit moment gebeurt. In plaats van zomaar wat code uitvoeren kun je dit ook doen door er een unittest bij te maken. Dat kost je net zo veel tijd als los kijken wat er gebeurt, maar vervolgens heb je wel een test voor dat stukje code. Uiteraard hoort er bij je nieuwe aanpassing ook een stukje unittest en als je op een gegeven moment voldoende testdekking hebt op een stukje code zou je je er aan kunnen wagen om eens een stukje te refactoren.

Bij een bug is het nog makkelijker. Over het algemeen ben je best wat tijd kwijt bij het zoeken naar de bug. Hier is het juist nog veel waardevoller om dat middels unittests te doen. Uiteindelijk is het dan de bedoeling dat je een unittest weet te maken die faalt vanwege juist die bug. Daarna kun je de bug fixen en kun je met die unittest aantonen dat het nu wel werkt. En ook hier krijg je een steeds hogere testdekking waardoor je op een gegeven moment eens aan wat kleine refactordingetjes kunt denken.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

Anoniem: 180316

Wat vinden jullie de maximale lengte van een C/C++ main functie? Hier wordt vooral ingegaan op member functies e.d. Maar in C++ (en al helemaal in C) moet je toch echt de main functie ook dingen laten doen...

Acties:
  • 0 Henk 'm!

  • Cartman!
  • Registratie: April 2000
  • Niet online
Wij zijn een tijdje terug afgestapt van prefixes om korte functies. Het argument was altijd: dan weet je wat voor soort variabele het is. Maar met korte functies en een goede doc voor je class/functie weet je dat direct als je de functie bekijkt. Op die manier is code zonder prefixes veel leesbaarder en veel makkelijker te refactoren. Helaas hebben we er nog 1 die dit niet echt wil inzien.

Hiervoor was het inderdaad ook functies met enorme lappe code erin die wel 50 dingen deden en er werd veel gecopy/paste, drama om te debuggen/onderhouden. Heerlijk nu die korte functies icm. een goede IDE.

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:05

.oisyn

Moderator Devschuur®

Demotivational Speaker

Anoniem: 180316 schreef op dinsdag 18 januari 2011 @ 22:44:
Wat vinden jullie de maximale lengte van een C/C++ main functie? Hier wordt vooral ingegaan op member functies e.d. Maar in C++ (en al helemaal in C) moet je toch echt de main functie ook dingen laten doen...
Wat is er zo speciaal aan main() :?

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!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 28-05 16:11
Verkondigen dat je er de tijd niet voor krijgt is een zwak excuus
Lekker praktische insteek ook. Als de klant de aanpassing over een week moet hebben ga jij em dan uitleggen dat dat niet kan omdat je ergens anders code zit aan te passen? Zal wel overheidswerk zijn dan ofzo want mijn klanten zitten daar echt niet op te wachten.

Moet je ook nog gaan uitleggen dat die code eigenlijk bagger is, gaat die kant nog harder steigeren omdat het dus de eerste keer ook al brak was.

De lengte van een functie is echt de moeite van de discussie niet waard eigenlijk : een functie is zo lang als tie moet zijn en niet langer maar ook niet korter.

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!

  • CodeCaster
  • Registratie: Juni 2003
  • Niet online

CodeCaster

Can I get uhm...

Anoniem: 180316 schreef op dinsdag 18 januari 2011 @ 22:44:
Wat vinden jullie de maximale lengte van een C/C++ main functie? Hier wordt vooral ingegaan op member functies e.d. Maar in C++ (en al helemaal in C) moet je toch echt de main functie ook dingen laten doen...
Als jij om wat voor reden dan ook vijftig forms wil spawnen in je main()-procedure dan doe je dat toch lekker. :)

Of die code niet gegroepeerd kan worden in logisch genaamde procedures is een tweede vraag.

[ Voor 9% gewijzigd door CodeCaster op 18-01-2011 23:54 ]

https://oneerlijkewoz.nl
Het ergste moet nog komen / Het leven is een straf / Een uitgestrekte kwelling van de wieg tot aan het graf


Acties:
  • 0 Henk 'm!

Anoniem: 180316

.oisyn schreef op dinsdag 18 januari 2011 @ 23:39:
[...]

Wat is er zo speciaal aan main() :?
Nou, zeker in C, gebeurd daar vaak nog wel het een en ander. Ook op embedded platformen, daar is het ook inefficienter om overal een functie aanroep te doen.

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:05

.oisyn

Moderator Devschuur®

Demotivational Speaker

Dat bewijst niet wat er speciaal is aan main(). Het is gewoon een functie zoals alle andere (die toevallig als entry point voor je app dient). Als het inefficient is om functieaanroepen te doen, dan geldt dat ook voor andere functies, en niet alleen voor main(). Ergo, exact dezelfde argumenten gaan op voor main() als voor elke andere functie.

[ Voor 13% gewijzigd door .oisyn op 19-01-2011 02:26 ]

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!

  • RayNbow
  • Registratie: Maart 2003
  • Laatst online: 22:13

RayNbow

Kirika <3

farlane schreef op dinsdag 18 januari 2011 @ 23:45:
[...]

Lekker praktische insteek ook. Als de klant de aanpassing over een week moet hebben ga jij em dan uitleggen dat dat niet kan omdat je ergens anders code zit aan te passen? Zal wel overheidswerk zijn dan ofzo want mijn klanten zitten daar echt niet op te wachten.
Als je maar een week de tijd hebt en je zit ergens aan andere code te werken, dan moet je dingen beter plannen. ;)

Daarnaast kost het refactoren van een enkele functie nauwelijks tijd (en helemaal weinig als je refactoring-tools gebruikt). Het idee is namelijk dat je kleine aanpassingen maakt en die telkens test, zoals beschreven in het originele Refactoring boek. Dit is trouwens ook de manier hoe je het in de wiskunde doet. Je schrijft niet een draak van een expressie in 1x om, maar vervangt geleidelijk stap voor stap subexpressies.
Moet je ook nog gaan uitleggen dat die code eigenlijk bagger is, gaat die kant nog harder steigeren omdat het dus de eerste keer ook al brak was.
Bij wie ligt de verantwoordelijkheid voor die brakke code? ;)
  • Als je zelf de code hebt geschreven, dan lijkt het me duidelijk dat je jezelf ermee geholpen hebt.
  • Indien de code reeds bestond en door een andere partij geschreven is, dan had je bij aanvang van de opdracht moeten aankaarten dat de kwaliteit van de code zodanig is, dat onderhoud meer werk kost.
De lengte van een functie is echt de moeite van de discussie niet waard eigenlijk : een functie is zo lang als tie moet zijn en niet langer maar ook niet korter.
Het is geen wet dat als een functie langer dan N regels beslaat, dat de functie per definitie te lang is. Het zijn vuistregels dat er zeer waarschijnlijk iets mis en dat je de boel kunt refactoren. Het is vergelijkbaar met code coverage. Als je geen 100% code coverage haalt, wil dat niet zeggen dat je testsuite niet goed is, maar het is wel raadzaam om te controleren welke zaken niet gedekt worden.

Daarnaast bestaan er trouwens refactoring-technieken die een functie langer kunnen maken, zoals bijv. Introduce ExplainingVariable:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
if ( (platform.toUpperCase().indexOf("MAC") > -1) &&
      (browser.toUpperCase().indexOf("IE") > -1) &&
       wasInitialized() && resize > 0 )
{
    // do something
}


// Introduce Explaining Variable -->


final boolean isMacOs     = platform.toUpperCase().indexOf("MAC") > -1;
final boolean isIEBrowser = browser.toUpperCase().indexOf("IE")  > -1;
final boolean wasResized  = resize > 0;

if (isMacOs && isIEBrowser && wasInitialized() && wasResized)
{
    // do something
}

Een groei van 2 regels. ;)

Ipsa Scientia Potestas Est
NNID: ShinNoNoir


Acties:
  • 0 Henk 'm!

  • Camulos
  • Registratie: Januari 2009
  • Laatst online: 01-06 14:27

Camulos

Stampert

farlane schreef op dinsdag 18 januari 2011 @ 23:45:
De lengte van een functie is echt de moeite van de discussie niet waard eigenlijk : een functie is zo lang als tie moet zijn en niet langer maar ook niet korter.
Idd :) Elke programmeur zal zo zijn voorkeur en stijl hebben bij het proggen van lappen code ^^

Persoonlijk heb ik best wel een hekel eraan als alles totaal over-engineered wordt, oftewel dat alles tot in de puntjes ge-extract en ge-refactored wordt. Dit soort code is namelijk prima voor de originele progger, alleen kost het vet veel tijd als collega/extern progger om de code te begrijpen! En al helemaal er ook nog eens een niet-logische of niet consistente naamgeving aan de methoden gegeven worden.

In het voorbeeld dat eerder werd aangehaald: Ik heb liever het eerste dan wel 2e stukje code dan de spaghetti op het einde.

Daarnaast is de lengte afhankelijk van de taal waarin je progt en het doel van je functie.
Voorbeelden:
- PHP library klasse kan methoden hebben van gemiddeld 20 tot 40 regels per functie...
- terwijl een JAVA GUI code lappen (lees 80 tot 100 regels) voor enkele functies heeft.
- Extende klassen in C# die super kort zijn per functie omdat ze alles door zetten naar hun parent ^^

[ Voor 8% gewijzigd door Camulos op 19-01-2011 08:48 ]

Not just an innocent bystander


Acties:
  • 0 Henk 'm!

  • Cartman!
  • Registratie: April 2000
  • Niet online
Camulos schreef op woensdag 19 januari 2011 @ 08:43:
[...]
Dit soort code is namelijk prima voor de originele progger, alleen kost het vet veel tijd als collega/extern progger om de code te begrijpen!
Integendeel denk ik. Als ik een functie van 200 regels voor m'n neus krijg dan zal ik echt heel erg goed moeten gaan lezen wat er nu precies allemaal gebeurt. Bij een functie van 5 regels zie je dat direct.
En al helemaal er ook nog eens een niet-logische of niet consistente naamgeving aan de methoden gegeven worden.
Dat is een kwestie van code-standaard en goed code reviewen en iemand die daar niet op let erop aanspreken.

Acties:
  • 0 Henk 'm!

  • Camulos
  • Registratie: Januari 2009
  • Laatst online: 01-06 14:27

Camulos

Stampert

Cartman! schreef op woensdag 19 januari 2011 @ 08:48:
Integendeel denk ik. Als ik een functie van 200 regels voor m'n neus krijg dan zal ik echt heel erg goed moeten gaan lezen wat er nu precies allemaal gebeurt. Bij een functie van 5 regels zie je dat direct.
Je vergeet even dat jij die functie van 5 regels eerst moet vinden :) Een functie van 200 regels refactoren naar 5-regel-functies.. (40 functies ongeveer?). Een wir-war van functies doorspitten om die ene functie te vinden...

Nu vind ik 200 regels ook best lang :) ^^ zelf streef ik naar maximaal 50 regels per functie

Not just an innocent bystander


Acties:
  • 0 Henk 'm!

  • BertS
  • Registratie: September 2004
  • Laatst online: 14-04 17:14
Davio schreef op maandag 17 januari 2011 @ 16:01:
Even een losse tip: Ik gebruik voor Visual Studio de extensie VS10x Code Map.
Hiermee heb ik in een sidebar een mooi overzicht van mijn properties, methods en events etc. mooi gegroepeerd per zelf aangegeven region.
Thanx! is een mooie toevoeging.

Acties:
  • 0 Henk 'm!

  • Cartman!
  • Registratie: April 2000
  • Niet online
Camulos schreef op woensdag 19 januari 2011 @ 09:12:
[...]
Je vergeet even dat jij die functie van 5 regels eerst moet vinden :) Een functie van 200 regels refactoren naar 5-regel-functies.. (40 functies ongeveer?). Een wir-war van functies doorspitten om die ene functie te vinden...
Dat lijkt me geen enkel probleem, gewoon doorklikken in je IDE. En als iedereen netjes werkt weet je meestal wel ongeveer waar iets zit, of je klikt gewoon wat rond in je IDE dus.

Acties:
  • 0 Henk 'm!

  • RayNbow
  • Registratie: Maart 2003
  • Laatst online: 22:13

RayNbow

Kirika <3

Camulos schreef op woensdag 19 januari 2011 @ 09:12:
[...]


Je vergeet even dat jij die functie van 5 regels eerst moet vinden :) Een functie van 200 regels refactoren naar 5-regel-functies.. (40 functies ongeveer?). Een wir-war van functies doorspitten om die ene functie te vinden...
Het is natuurlijk wel de bedoeling dat je de gerefactorde functie grotendeels kunt begrijpen zonder de details erop na te hoeven slaan. Hierbij is van groot belang dat de kleinere functies een duidelijke naam hebben.
Mocht je geinteresseerd zijn in de details van een bepaalde functie, dan helpt een IDE je om er naar toe te springen. Het is echter niet de bedoeling om bij elke functieaanroep die je tegenkomt tijdens het lezen meteen de diepte in te gaan.**

(** Dit is vooral een slechte manier om bijv. een recursieve functie f te begrijpen. Tijdens het lezen van f kom je gegarandeerd een aanroep van f tegen. Om f te begrijpen moet je dus eerst f begrijpen? :p)

Ipsa Scientia Potestas Est
NNID: ShinNoNoir


Acties:
  • 0 Henk 'm!

Anoniem: 313723

Er schijnen nu eenmaal mensen rond te lopen die nette code onbelangrijk vinden, zolang het maar werkt.
Die mensen heten klanten, managers en ontwikkelaars. Je kan het je in het bedrijfsleven gewoon niet permitteren altijd purist te zijn. Dat levert vertraging op. Soms moet iets ad hoc gebeuren en dan zul je uiteindelijk pragmatisme over purisme gaan prefereren.
De spaghettivorming is iets van kwadratisch aan het aantal onderhoudsbeurten :+

Overigens vind ik dat verhaal over 1 functie-call in een method ook echt onzin. Je code wordt er alleen minder leesbaar en onderhoudbaar door. Daarnaast maak je debuggen ook alleen maar lastiger, omdat je je call-stack onnodig groot maakt (wat daarnaast ook nog eens een negatieve invloed heeft op performance). Je moet gewoon logische stukken groeperen. Niet extracten om het extracten.

[ Voor 29% gewijzigd door Anoniem: 313723 op 19-01-2011 09:55 ]


Acties:
  • 0 Henk 'm!

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 17:35
RayNbow schreef op woensdag 19 januari 2011 @ 09:36:

(** Dit is vooral een slechte manier om bijv. een recursieve functie f te begrijpen. Tijdens het lezen van f kom je gegarandeerd een aanroep van f tegen. Om f te begrijpen moet je dus eerst f begrijpen? :p)
Vooral leuk bij 2-laags-recursie (of hoe dat ook heet): f roept g aan, en g roept in bepaalde gevallen f weer aan. "Volgens mij heb ik daarnet net zo'n functie gezien, welke malloot gaat dit nou copy/pasten?" Oh ja, recursie... :z

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 22:54

Janoz

Moderator Devschuur®

!litemod

Topicstarter
farlane schreef op dinsdag 18 januari 2011 @ 23:45:
[...]

Lekker praktische insteek ook. Als de klant de aanpassing over een week moet hebben ga jij em dan uitleggen dat dat niet kan omdat je ergens anders code zit aan te passen? Zal wel overheidswerk zijn dan ofzo want mijn klanten zitten daar echt niet op te wachten.
Nee, ik zit niet ergens anders code aan te passen. Lees nog eens mijn beschrijving door. Ik doe mijn aanpassing en laat de code netter achter dan dat ik hem gevonden heb. Als dat bij elke aanpassing gebeurt evolueert de code vanzelf naar nettere code.

En overheid? Dat valt wel mee. Niet alles anders dan cowboy omgevingen is overheid.
Moet je ook nog gaan uitleggen dat die code eigenlijk bagger is, gaat die kant nog harder steigeren omdat het dus de eerste keer ook al brak was.
Hier is al eerder op gereageerd. Het is echt niet de klant die brakke code geschreven heeft. Als je nu meer tijd voor je aanpassing nodig hebt dan is dat de consequentie van de kantjes die je team er eerder vanaf gelopen heeft. Verder zijn jullie blijkbaar niet goed in het onderkennen en communiceren van de technical debt en daarnaast kost nette code niet meer tijd dan brakke aanpassingen.
De lengte van een functie is echt de moeite van de discussie niet waard eigenlijk : een functie is zo lang als tie moet zijn en niet langer maar ook niet korter.
Het is geen keiharde regel. Het is een leidraad. Bij enorme lange lappen code is de kans veel groter dat je met ononderhoudbare code te maken hebt. Het is een belangrijke metric die wij gebruiken om onderhoudbaarheid te kunnen afleiden.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • Camulos
  • Registratie: Januari 2009
  • Laatst online: 01-06 14:27

Camulos

Stampert

Anoniem: 313723 schreef op woensdag 19 januari 2011 @ 09:49:
Overigens vind ik dat verhaal over 1 functie-call in een method ook echt onzin. Je code wordt er alleen minder leesbaar en onderhoudbaar door. Daarnaast maak je debuggen ook alleen maar lastiger, omdat je je call-stack onnodig groot maakt (wat daarnaast ook nog eens een negatieve invloed heeft op performance). Je moet gewoon logische stukken groeperen. Niet extracten om het extracten.
+1 !! kan het niet beter verwoorden :)

Not just an innocent bystander


Acties:
  • 0 Henk 'm!

  • Flapmo
  • Registratie: April 2000
  • Laatst online: 02-06 08:25

Flapmo

and back is gigi!

Camulos schreef op woensdag 19 januari 2011 @ 10:14:
[...]


+1 !! kan het niet beter verwoorden :)
en nog een +1 :).

"The purpose of computing is insight, not numbers." -- Richard Hamming


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 22:54

Janoz

Moderator Devschuur®

!litemod

Topicstarter
Anoniem: 313723 schreef op woensdag 19 januari 2011 @ 09:49:
Die mensen heten klanten, managers en ontwikkelaars. Je kan het je in het bedrijfsleven gewoon niet permitteren altijd purist te zijn. Dat levert vertraging op. Soms moet iets ad hoc gebeuren en dan zul je uiteindelijk pragmatisme over purisme gaan prefereren.
Het heeft niks met purisme te maken, maar alles met professionaliteit. Ook bij een adhoc aanpassing kost het geen extra tijd om daar een unittestje bij te bouwen.
De spaghettivorming is iets van kwadratisch aan het aantal onderhoudsbeurten :+
Dat hoeft dus helemaal niet. Dat gebeurt alleen wanneer je je code laat rotten.
Overigens vind ik dat verhaal over 1 functie-call in een method ook echt onzin. Je code wordt er alleen minder leesbaar en onderhoudbaar door. Daarnaast maak je debuggen ook alleen maar lastiger, omdat je je call-stack onnodig groot maakt (wat daarnaast ook nog eens een negatieve invloed heeft op performance). Je moet gewoon logische stukken groeperen. Niet extracten om het extracten.
Je kunt het natuurlijk in het belachelijke trekken. Een functie hoeft echt niet uit 1 regel te bestaan. Echter wanneer bij voorbaat je onderhoudbaarheid in gaat leveren vanwege vermoedelijk performance verlies dan ben je imho niet goed bezig.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

Anoniem: 313723

Janoz schreef op woensdag 19 januari 2011 @ 10:38:
[...]

Het heeft niks met purisme te maken, maar alles met professionaliteit. Ook bij een adhoc aanpassing kost het geen extra tijd om daar een unittestje bij te bouwen.
Tja, dat vind jij, dat vind ik, maar wat je ziet is toch dat er dingen on-the-fly veranderd gaan worden, om het snel even iets op te leveren. Een regeltje code in een method, zonder opnieuw te testen.
Dat is niet leuk, maar dagelijkse praktijk. Er zijn nog legio bedrijven waar unit-testen uberhaupt niet vanzelfsprekend is. Ik heb bij een multinational gewerkt waar unit-testen nu pas geimplementeerd wordt. En nu klaagt men al over het feit dat dat tijd kost.
Je kunt het natuurlijk in het belachelijke trekken. Een functie hoeft echt niet uit 1 regel te bestaan. Echter wanneer bij voorbaat je onderhoudbaarheid in gaat leveren vanwege vermoedelijk performance verlies dan ben je imho niet goed bezig.
Daar zijn we het dus eens, het sloeg voornamelijk op deze blogpost: http://blog.objectmentor....ing-extract-till-you-drop die door iemand gelinkt werd.

Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Anoniem: 180316 schreef op woensdag 19 januari 2011 @ 00:53:
[...]


Nou, zeker in C, gebeurd daar vaak nog wel het een en ander. Ook op embedded platformen, daar is het ook inefficienter om overal een functie aanroep te doen.
Dat valt toch wel mee. Ik werk ook best veel op embedded platformen, maar mijn main function is nooit erg lang. Je roept een paar initialisatie routines aan, en dan start je je main loop/scheduler. Meestal zal de compiler toch ook nog wel het een en ander inlinen, dus dan is de overhead van een functie aanroepen ook geen argument meer.

“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!

  • SeatRider
  • Registratie: November 2003
  • Laatst online: 29-05 11:26

SeatRider

Hips don't lie

CodeCaster schreef op maandag 17 januari 2011 @ 11:14:
Wat zei Joel daar ook alweer over?

[...]

Oh die was gelukkig pas twee keer genoemd. :X :P
Die blogpost haal ik ook altijd aan ja, briljant gewoon.

Nederlands is makkelijker als je denkt


Acties:
  • 0 Henk 'm!

  • Davio
  • Registratie: November 2007
  • Laatst online: 06-01 16:46
Woy schreef op woensdag 19 januari 2011 @ 10:48:
[...]

Dat valt toch wel mee. Ik werk ook best veel op embedded platformen, maar mijn main function is nooit erg lang. Je roept een paar initialisatie routines aan, en dan start je je main loop/scheduler. Meestal zal de compiler toch ook nog wel het een en ander inlinen, dus dan is de overhead van een functie aanroepen ook geen argument meer.
Ik ga toch liever voor leesbaarheid van mijn code dan voor micro-optimalisatie middels het minimaliseren van functie-aanroepen.

Acties:
  • 0 Henk 'm!

  • RayNbow
  • Registratie: Maart 2003
  • Laatst online: 22:13

RayNbow

Kirika <3

MBV schreef op woensdag 19 januari 2011 @ 09:56:
[...]

Vooral leuk bij 2-laags-recursie (of hoe dat ook heet): f roept g aan, en g roept in bepaalde gevallen f weer aan. "Volgens mij heb ik daarnet net zo'n functie gezien, welke malloot gaat dit nou copy/pasten?" Oh ja, recursie... :z
Haskell:
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
-- De priemgetallen:

primes = 2 : oddprimes
oddprimes = filter isPrime [3,5..]




-- Wanneer is iets priem?
-- Nou, als het maar 1 priemfactor heeft:

isPrime n = case (primeFactors n) of
              [p] -> True
              _   -> False




-- Maar hoe bereken je de priemfactoren van een getal n?
-- Nou, we delen gewoon herhaaldelijk door elk priemgetal:

primeFactors n = factor n primes
  where factor m (p:ps)
          | p*p > m         =  [m]
          | m `mod` p == 0  =  p : factor (m `div` p) (p:ps)
          | otherwise       =  factor m ps

Mutual recursion. *O*

Ipsa Scientia Potestas Est
NNID: ShinNoNoir


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:05

.oisyn

Moderator Devschuur®

Demotivational Speaker

Davio schreef op woensdag 19 januari 2011 @ 10:55:
[...]

Ik ga toch liever voor leesbaarheid van mijn code dan voor micro-optimalisatie middels het minimaliseren van functie-aanroepen.
Het zijn alleen niet altijd micro-optimalisaties. Zo hebben wij onlangs wat vaak aangeroepen virtual methods ontdaan van het virtual zijn. Op embedded platforms waar een cycle relatief lang duurt is de impact nog veel groter.
Cartman! schreef op woensdag 19 januari 2011 @ 09:32:
[...]

Dat lijkt me geen enkel probleem, gewoon doorklikken in je IDE. En als iedereen netjes werkt weet je meestal wel ongeveer waar iets zit, of je klikt gewoon wat rond in je IDE dus.
De mens is slecht in recursie. Als jij 3 of 4 functies diep moet raak je al snel het overzicht kwijt.

[ Voor 30% gewijzigd door .oisyn op 19-01-2011 11:29 ]

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!

Anoniem: 24417

whoops, scrollfaal*

[ Voor 87% gewijzigd door Anoniem: 24417 op 19-01-2011 12:06 ]


Acties:
  • 0 Henk 'm!

  • Cartman!
  • Registratie: April 2000
  • Niet online
.oisyn schreef op woensdag 19 januari 2011 @ 11:28:
[...]
De mens is slecht in recursie. Als jij 3 of 4 functies diep moet raak je al snel het overzicht kwijt.
Dan ga je er voor t gemak even vanuit dat alle code die je schrijft recursief is. We maken vast heel verschillende producten, ik gebruik t maar zelden iig.

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:05

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ik heb het niet over recursieve functies, ik heb het over in je hoofd steeds weer opnieuw een functie in en maar proberen te onthouden wat je 'stack' was.

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!

  • RayNbow
  • Registratie: Maart 2003
  • Laatst online: 22:13

RayNbow

Kirika <3

.oisyn schreef op woensdag 19 januari 2011 @ 16:41:
ik heb het over in je hoofd steeds weer opnieuw een functie in en maar proberen te onthouden wat je 'stack' was.
En daarom is het niet de bedoeling om bij elke functieaanroep de diepte in te gaan. :)

Als je iets ziet als...
Python:
1
2
xs = range(10)
random.shuffle(xs)

...spring je niet naar de definitie van random.shuffle, maar behandel je het als een black box.

Ipsa Scientia Potestas Est
NNID: ShinNoNoir


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:05

.oisyn

Moderator Devschuur®

Demotivational Speaker

Tot je wilt weten hoe die geïmplementeerd is. Volgens mij ging de discussie over http://blog.objectmentor....ing-extract-till-you-drop.

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!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 01:23
Ik geloof dat de term cyclomatic complexity nog niet gevallen is? Het is een maat van de complexiteit van een procedure aan de hand van het aantal punten waarop branching plaats vindt. Voorbeelden zoals hier gegegeven werden van functies die simpelweg een heleboel andere procedures aanroepen maar verder nauwelijks branching bevatten kunnen wel uit veel statements bestaan, maar zijn volgens deze maat nog steeds niet complex. Dit sluit waarschijnlijk beter aan bij het intuïtieve idee van complexiteit dan simpelweg statements tellen.

(Sowieso geldt dat het aantal statements dat je nodig hebt om een bepaalde taak uit te voeren nogal verschilt per taal. In C heb je relatief veel code nodig voor het alloceren en vrijgeven van resources ten op zichte van bijvoorbeeld C++, waar dat soort dingen meestal automatisch via constructors en destructors gebeuren, maar dat maakt de code nauwelijks moeilijker om te begrijpen.)

Ik heb het ook eens met (o.a.) .oisyn dat het weinig zin heeft om meer procedures te introduceren tenzij daarbij ook abstractie plaatsvindt. Als je de hele context expliciet moet meegeven, dan heb je alleen maar meer code nodig om hetzelfde gedaan te krijgen, en de resulterende code is dan niet eenvoudiger om in z'n geheel te begrijpen. Afsplitsen van functionaliteit is mijns inziens pas zinnig als je daardoor ófwel codeduplicatie voorkomt (soms moet je dan helaas nog steeds veel contextinformatie meegeven), óf onafhankelijke functionaliteit die eerst verweven was ontwart. Kortom: als het afsplitsen van functionaliteit tot makkelijker te begrijpen code leidt.

Acties:
  • 0 Henk 'm!

  • RayNbow
  • Registratie: Maart 2003
  • Laatst online: 22:13

RayNbow

Kirika <3

.oisyn schreef op woensdag 19 januari 2011 @ 17:41:
Tot je wilt weten hoe die geïmplementeerd is.
Tuurlijk, als je echt wilt weten hoe iets geimplementeerd is, dan kun je altijd naar de definitie springen. Dit doe je echter niet als je al bezig bent om de functie te begrijpen waarin deze functieaanroep (in mijn voorbeeld random.shuffle) plaatsvindt.
Volgens mij ging de discussie over http://blog.objectmentor....ing-extract-till-you-drop.
Daarvan vind ik helaas alle iteraties van de code lelijk. :p

Ipsa Scientia Potestas Est
NNID: ShinNoNoir


Acties:
  • 0 Henk 'm!

  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 18:27

alienfruit

the alien you never expected

Het probleem met die klasse van eerder is. Dat het te veel afhankelijk is van externe partijen. Gezien de klant niet een onafhankelijk test omgeving wilde leveren. Nu moeten we dus altijd een vier onderaannemers van de klant bellen. Om delen van het systeem te testen. Volgens vaste richtlijnen die minstens een week in beslag nemen. Dus breek me de bek niet open. Eigenlijk zou ik de klasse wat willen refactoren zodat de state machines gesepareerd worden. Om het overzichtelijker te maken en state guard etc.

Verder was dit mijn eerste project bij mijn baas en was de documentatie in een taal waar ik niet vloeiend in ben. Acht het project waarop het gebaseerd is (v1) was nog erger... Wat ik mijn nu al een tijd afvraag hoe werk je met unit tests als je zoveel afhankelijkheden hebt?

Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 28-05 16:11
Janoz schreef op woensdag 19 januari 2011 @ 10:06:
Nee, ik zit niet ergens anders code aan te passen. Lees nog eens mijn beschrijving door. Ik doe mijn aanpassing en laat de code netter achter dan dat ik hem gevonden heb. Als dat bij elke aanpassing gebeurt evolueert de code vanzelf naar nettere code.
Ik snap de werkwijze ( en ook de impuls om dat soort dingen te doen ), maar elke aanpassing die je maakt kost tijd, hoe dan ook. En in brakke code kost het meer tijd want kleine aanpassingen hebben meestal meer gevolgen dan je kunt zien in een korte tijd. Jouw oplossing daarvoor is tests schrijven, wat ook tijd kost.

Imho moet je je gewoon blijven afvragen of dat wat je aan het doen bent wel iets gaat opleveren, anders dan alleen 'nettere code'.
Hier is al eerder op gereageerd. Het is echt niet de klant die brakke code geschreven heeft. Als je nu meer tijd voor je aanpassing nodig hebt dan is dat de consequentie van de kantjes die je team er eerder vanaf gelopen heeft.
Ik heb het over code die uit hetzelfde 'nest' komt, dus waarvoor jij/ik verantwoordelijk bent. Dat kan code van jezelf zijn, of code geschreven door iemand/iemanden ander en waarvoor je eigenlijk niet de verantwoordelijkheid wilt, omdat je weet dat het geen goede code is. Ook al heb je er geen hand in gehad, je moet alsnog met de billen bloot op dat moment. Wat de oorzaak ook geweest is, de klant zal niet blij zijn om te horen dat het brakke code is.
Verder zijn jullie blijkbaar niet goed in het onderkennen en communiceren van de technical debt en daarnaast kost nette code niet meer tijd dan brakke aanpassingen.
Met het tweede ben ik het helemaal eensch, maar soms heb je daar gewoon geen invloed op.
Het eerste punt vind ik erm, vaag. Wat bedoel je daar mee, dat ik/wij niet weten dat goede software maken belangrijk is?
Het is geen keiharde regel. Het is een leidraad.
Als leidraad zou het kunnen functioneren misschien.

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!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:05

.oisyn

Moderator Devschuur®

Demotivational Speaker

RayNbow schreef op woensdag 19 januari 2011 @ 18:20:
[...]

Tuurlijk, als je echt wilt weten hoe iets geimplementeerd is, dan kun je altijd naar de definitie springen.
Ja, en als die functie is opgesplitst in 5 niveaus diep, dan spring je en spring je en wordt de code zo onoverzichtelijk als de pest.

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!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 22:54

Janoz

Moderator Devschuur®

!litemod

Topicstarter
farlane schreef op woensdag 19 januari 2011 @ 20:29:
[...]

Ik snap de werkwijze ( en ook de impuls om dat soort dingen te doen ), maar elke aanpassing die je maakt kost tijd, hoe dan ook. En in brakke code kost het meer tijd want kleine aanpassingen hebben meestal meer gevolgen dan je kunt zien in een korte tijd. Jouw oplossing daarvoor is tests schrijven, wat ook tijd kost.
Uiteraard kost een aanpassing tijd. Ik neem verder aan dat we het eens zijn dat een aanpassing in nette code minder tijd kost dan een aanpassing in rotte code. Wat ik echter daarnaast nog beweer is dat een aanpassing maken en de code netter achter te laten dan je hem gevonden hebt niet meer tijd hoeft te kosten dan de aanpassing adhoc doorvoeren en werkend te krijgen.
Imho moet je je gewoon blijven afvragen of dat wat je aan het doen bent wel iets gaat opleveren, anders dan alleen 'nettere code'.
Als het enkel daarom ging dan zou nu gelijk alle rotte code gerefactord worden op het moment dat er daadwerkelijk een wijziging nodig was ;)
Ik heb het over code die uit hetzelfde 'nest' komt, dus waarvoor jij/ik verantwoordelijk bent. Dat kan code van jezelf zijn, of code geschreven door iemand/iemanden ander en waarvoor je eigenlijk niet de verantwoordelijkheid wilt, omdat je weet dat het geen goede code is. Ook al heb je er geen hand in gehad, je moet alsnog met de billen bloot op dat moment. Wat de oorzaak ook geweest is, de klant zal niet blij zijn om te horen dat het brakke code is.
Als de waarheid vervelend is vindt niemand dat fijn om te horen. Het is echt niet pas een probleem op het moment dat je het probeert op te lossen. Het is nu al een probleem. Zeker wanneer je de schijn op wilt houden dat de code niet brak is lijkt het mij het handigste om er beetje bij beetje voor te zorgen dat de code niet meer brak is.
Met het tweede ben ik het helemaal eensch, maar soms heb je daar gewoon geen invloed op.
Het eerste punt vind ik erm, vaag. Wat bedoel je daar mee, dat ik/wij niet weten dat goede software maken belangrijk is?
Nee, eerder dat jullie niet weten wat de gevolgen van jullie technical debt is, of dit niet over weten te brengen op het project managment/sales afdeling. Dat kan aan jullie liggen, maar ligt over het algemeen vaker aan de managment/sales afdeling.
Als leidraad zou het kunnen functioneren misschien.
Lees gewoon het eerder aangehaalde boek eens en probeer het zo nu en dan eens toe te passen.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 28-05 16:11
Janoz schreef op woensdag 19 januari 2011 @ 22:50:
Als de waarheid vervelend is vindt niemand dat fijn om te horen. Het is echt niet pas een probleem op het moment dat je het probeert op te lossen.
Dat klopt wel, maar het probleem is dat ook rotte code meestal wel redelijk werkt, alleen de uitzonderingen op de regel laten de boel in het honderd lopen. Die uitzonderingen echter koment niet vaak voor, zodat de klant van mening is dat het product redelijk werkt, behalve die paar 'speciale situaties' die een onevenredige hoeveelheid werk vergen om op te lossen.
Nee, eerder dat jullie niet weten wat de gevolgen van jullie technical debt is, of dit niet over weten te brengen op het project managment/sales afdeling. Dat kan aan jullie liggen, maar ligt over het algemeen vaker aan de managment/sales afdeling.
Ah ok, tja ik ben me daar maar al te bewust van en ik zie het als mijn taak om het management er ook van te blijven overtuigen. Echter, prioriteiten liggen vaak ergens anders op het moment dat puntje bij paaltje komt, en het momentum van de 'andere partij' is op dat moment vaak moeilijk te stoppen.
Lees gewoon het eerder aangehaalde boek eens en probeer het zo nu en dan eens toe te passen.
Als ik tijd heb ga ik dat zeker doen .. :P

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!

  • Jan_V
  • Registratie: Maart 2002
  • Laatst online: 22:47
alienfruit schreef op woensdag 19 januari 2011 @ 20:03:
Wat ik mijn nu al een tijd afvraag hoe werk je met unit tests als je zoveel afhankelijkheden hebt?
Dat zou je met Dependency Injection moeten oplossen om zo verschillende mock objecten te kunnen maken. Echter ben ik er daar ook nog niet helemaal uit hoe ik zoiets moet gaan ontwikkelen.
Je krijgt dan een constructor met mogelijk 10 verschillende interfaces als parameter. Volgens mij is dat inderdaad de bedoeling, zo kun je iedere gebruikte klasse binnen de klasse die je wilt testen aanroepen met een benodigde interface. Het is dan wel noodzakelijk dat iedere aangeroepen klasse ook zo werkt natuurlijk.

Zeker in het boek Working Effectively with Legacy Code wordt hier op ingegaan, maar omdat ik dat boek zo droog vind, kom ik er niet echt door en blijft het ook niet echt hangen.

Battle.net - Jandev#2601 / XBOX: VriesDeJ


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Jan_V schreef op donderdag 20 januari 2011 @ 07:53:
[...]
Dat zou je met Dependency Injection moeten oplossen om zo verschillende mock objecten te kunnen maken. Echter ben ik er daar ook nog niet helemaal uit hoe ik zoiets moet gaan ontwikkelen.
Maar op bestaande code is dat een stuk lastiger.
Je krijgt dan een constructor met mogelijk 10 verschillende interfaces als parameter. Volgens mij is dat inderdaad de bedoeling, zo kun je iedere gebruikte klasse binnen de klasse die je wilt testen aanroepen met een benodigde interface. Het is dan wel noodzakelijk dat iedere aangeroepen klasse ook zo werkt natuurlijk.
DI hoeft niet perse via de constructor te gaan natuurlijk
Zeker in het boek Working Effectively with Legacy Code wordt hier op ingegaan, maar omdat ik dat boek zo droog vind, kom ik er niet echt door en blijft het ook niet echt hangen.
Ik ga dat boek ook eens bestellen, het lijkt me wel interessant want ik loop ook vaak tegen het probleem van Legacy Code aan, waar je aan de ene kant van alles aan wil veranderen, maar aan de andere kant niet durft omdat je bang bent dat er van alles omvalt, omdat het afhankelijk is van de quircks van het systeem.

“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.”

Pagina: 1 2 Laatste