mboost-dp1

Spgsml til udvikling af større komplekse programmer??


Gå til bund
Gravatar #1 - Qw_freak
19. okt. 2011 12:32
Hey, mit spørgsmål er relativt simpelt.

Når man laver store og komplekse programmer laver man dem så som et stykke kode, eller bygger man dem op af mindre individuelle programmer?

Fx Photoshop, Mathcad, matlab, Computespil og andre store programmer med masser af indbyggede funktionaliteter og enkeltstående brugsmuligheder , er de store programmer lavet udi et stykke kode, eller er det bygget op af moduler som snakker sammen?
Gravatar #2 - Windcape
19. okt. 2011 12:41
Det afhænger af om programmørene ikke selv kan tænke sig til det korrekte svar på netop dit spørgsmål.
Gravatar #3 - Qw_freak
19. okt. 2011 12:45
Windcape (2) skrev:
Det afhænger af om programmørene ikke selv kan tænke sig til det korrekte svar på netop dit spørgsmål.


hva, uddyb venligst..?
Gravatar #4 - Mnc
19. okt. 2011 12:56
Hvis jeg kigger i bin mappen for eksempelvis Portal, så er der 57 dll filer.
Hver dll-fil er så vidt jeg husker et namespace, der så kan indeholde x antal classer.
Hvor mange kodefiler der er per namespace kan variere meget. En dll kan indeholde 2 klasser lige så vel som den kan indeholde 200 klasser. Og klasserne kan så have hver deres kodefil eller endda flere filer per klasse.

Jeg har ikke meget erfaring med programmering, så det er bare hvad jeg ved man kan i C#/Visual Studio.

Qw_freak (3) skrev:
hva, uddyb venligst..?

Hvis programmørerne er nogle fjolser, så skrives det i én kæmpe fil.
Hvis de har blodomløb i kraniet, så skrives det i flere (aka mange) filer.
Gravatar #5 - Qw_freak
19. okt. 2011 13:03
Mnc (4) skrev:
Hvis programmørerne er nogle fjolser, så skrives det i én kæmpe fil.
Hvis de har blodomløb i kraniet, så skrives det i flere (aka mange) filer.


Det vil sige det er meget normalt at lave flere individuelle filer og så sætte dem sammen til sidst?
Gravatar #6 - Arnfast
19. okt. 2011 13:05
Man kan med fordel bruge det der hedder komponent baseret udvikling hvis man har et større system. Hvor man separere funktionalitet i komponenter, komponenter som i mange tilfælde bliver til f.eks. dll'er indenfor windows udvikling. Det giver en god afkobling af funktionalitet, samt gør at det muligt at genbruge komponenter i andre programmer.

Læs evt mere her:

http://en.wikipedia.org/wiki/Component-based_softw...
Gravatar #7 - myplacedk
19. okt. 2011 13:07
Qw_freak (1) skrev:
Når man laver store og komplekse programmer laver man dem så som et stykke kode, eller bygger man dem op af mindre individuelle programmer?

Tommelfingerreglen er, at en metode/funktion skal kunne være på ét skærmbillede, så når man sidder og koder skal man kunne læse metode uden at scrolle.

Og der skal helst ikke være særligt mange metoder i samme fil.

Om det så er mange små programmer, eller ét stort program med mange moduler, hvad et "program" eller "modul" er osv. kommer helt an på hvad man laver. Men der er kun én mode at lave et stort system: Divide and conquer.
Gravatar #8 - kasperd
19. okt. 2011 13:11
Qw_freak (1) skrev:
eller er det bygget op af moduler som snakker sammen?
Det kommer an på din definition af modul.

Man kan sagtens lave et stort program med et gennemtænkt design hvor alt koden afvikles i en enkelt tråd. Og i mange tilfælde er det faktisk også den nemmeste måde at opnå et fornuftigt design.

Men selve kildekoden har selvfølgelig en struktur. Man deler sin kode op i forskellige filer, hvor koden i hver fil kun beskæftiger sig med relateret funktionalitet.

Indeholder programmet netværkskode kan man f.eks. have en separat fil for hver protokol man implementerer. Har man en GUI lægges GUI koden i filer der er separeret fra den bagvedliggende funktionalitet.

Du gør klogt i at have en klar lagdeling i arkitekturen. Hver fil hører til på et lag og må kun kalde funktioner på lavere lag. Kald på tværs mellem filer på samme lag er problematisk, og kald af kode på højere lag er direkte ødelæggende for arkitekturen.

Kald fra lavere lag til højere lag kan selvfølgelig ske gennem callbacks, hvis din API bruger den slags. F.eks. har qsort funktionen i C et argument med en funktionspointer. Funktionen der kalder qsort ligger på et højere niveau. Den funktion der gives med til qsort ligger enten i samme fil som kaldet eller i en anden fil på et lavere niveau. Men funktionen der gives med til qsort vil dog altid ligge på et højere niveau end qsort. At qsort kalder en funktion på et højere niveau er ikke et problem fordi det sker gennem en funktionspointer.

Hvor stor hver fil må være kan diskutteres. Den kode jeg arbejder på nu har i gennemsnit 218 linier per fil og den største er på 978 linier. Jeg har også set projekter med mere kode per fil end det uden at det blev et problem. At man har en meningsfuld opdeling er vigtigere end det præcise antal linier per fil.

I sidste ende kan det sagtens være at alle ens source filer resulterer i en program fil. Det er ikke noget problem, linkeren er bedre til at bevare overblikket end udvikleren.
Gravatar #9 - Windcape
19. okt. 2011 13:16
Qw_freak (3) skrev:
hva, uddyb venligst..?
At hvis du så meget som overvejer et splitsekund ikke at dele din kode op i overskuelige dele, så er du ikke særlig kløgtig.

Man bruger typisk langt langt mere tid på at LÆSE kode, end man bruger på at skrive den. Derfor er det vigtigt at det er nemt at overskue koden.


Gravatar #10 - kasperd
19. okt. 2011 13:22
myplacedk (7) skrev:
Tommelfingerreglen er, at en metode/funktion skal kunne være på ét skærmbillede, så når man sidder og koder skal man kunne læse metode uden at scrolle.
Men ikke alle har det samme antal linier på skærmen. Før i tiden har 24 eller 25 linier været det normale. Og en sjælden gang imellem er man nødt til at fejlfinde under omstændigheder hvor man ikke har flere linier end det at gøre brug af. For det meste har man dog flere, og jeg har læst meget kode på en skærm der var 1920 pixels høj og 1080 pixels bred. Kan ikke huske hvor høj fonten har været, men den har nok været mellem 10 og 12 pixels, hvilket når man så ser bort fra overhead giver omkring 150 linier på skærmen. Så er det de 24 eller de 150 linier man må bruge per funktion? Det rigtige svar ligger nok et sted derimellem.
Gravatar #11 - Windcape
19. okt. 2011 13:22
Qw_freak (5) skrev:
Det vil sige det er meget normalt at lave flere individuelle filer og så sætte dem sammen til sidst?
At du overhovedet tænker i "filer" er lidt skræmmende.

Jeg sidder på et lille projekt pt. med 305 filer i 95 mapper. Der typisk under 200 linjers kode i hver fil, fordi det er hurtigere at tabbe mellem flere filer, end det er at scrolle op og ned. Ligeledes er det nemmere at have et split-view på den måde.

Strukturen er 6 assemblies (+ 3 mere til unit testing), hvilket er .NET jargon for et dynamic linked library (aka. DLL). (I java kendt som en JAR fil).

Det er delt op i følgende

Hovedmodul (selve programmet, .exe fil)
Common (Diverse delt, DLL)
Data (Data layer, og data repositories)
Samt 3 GUI moduler, der hver representere en del af brugerfladen . En af dem er en overordnet Ribbon shell, de 2 andre er to tabs.

Hvert modul har så flere filer, der repræsentere enkelte views, dialogere, osv. Men det er ikke så relevant som den overordnede struktur.
Gravatar #12 - Windcape
19. okt. 2011 13:23
Derudover kan du jo evt. tage et kig på kildekoden til https://github.com/jonasswiatek/strokes , hvor vi har sørget for en rigtig god struktur af koden.
Gravatar #13 - Windcape
19. okt. 2011 13:25
kasperd (10) skrev:
Så er det de 24 eller de 150 linier man må bruge per funktion? Det rigtige svar ligger nok et sted derimellem.
Generelt set må man vel bruge det antal linjer der er nødvendig per funktion.

Hvis man altså fokusere på det funktionelle -- ie. at en funktion kun udfører én handling, ud fra et givet input, og ikke modificere noget state på vejen.

I så fald er det sjældent man ender med meget større funktioner end 30-40 linjer -- medmindre det da lige er kryptering :)
Gravatar #14 - myplacedk
19. okt. 2011 13:34
kasperd (10) skrev:
Men ikke alle har det samme antal linier på skærmen.

Enhver udvikler har vel en eller anden form for ide om hvor mange linjer der typisk er plads til på skærmen på sin arbejdsplads.
Kan man ikke overskue det uden at få tal på, kan vi da godt sige "op til 25-35 linjer". Det er en tommelfingerregel.
Gravatar #15 - Windcape
19. okt. 2011 13:34
Mnc (4) skrev:
Hvis jeg kigger i bin mappen for eksempelvis Portal, så er der 57 dll filer.
Nu har jeg ikke installeret Portal på arbejde, men jeg vil skyde på at mindst en 10-15 stykker af de assemblies er 3. parts biblioteker.

Men det bekræfter jo også bare argumentet for at kode der kan sepereres, skal være i et seperate bibliotek, så det kan bruges til 2 forskellige ting.

F.eks. så er datalaget i det værktøjer jeg arbejder på pt. genbrugeligt , så både vores webservice, og client-værktøjet kan bruge det.
Gravatar #16 - Windcape
19. okt. 2011 13:36
myplacedk (14) skrev:
Kan man ikke overskue det uden at få tal på, kan vi da godt sige "op til 25-35 linjer". Det er en tommelfingerregel.
Jeg har 45 til 59.

Det afhænger af hvilke vinduer der er åbent.

Men man kan jo altid hive sin kode op i fuldskærm, på begge monitors, hvis man virkelig vil have oversigt over koden.

Visual Studio niceness
Gravatar #17 - myplacedk
19. okt. 2011 13:38
Windcape (16) skrev:
eg har 45 til 59.

Ja, det er en gammel tommelfingerregel. Det kan diskuteres om større skærme betyder større funktioner.
Gravatar #18 - Windcape
19. okt. 2011 13:40
myplacedk (17) skrev:
Ja, det er en gammel tommelfingerregel. Det kan diskuteres om større skærme betyder større funktioner.
Helst ikke :(

Det gør jo ikke noget man kan læse hele TO funktioner på ét skærmbillede.
Gravatar #19 - myplacedk
19. okt. 2011 13:48
Windcape (13) skrev:
Generelt set må man vel bruge det antal linjer der er nødvendig per funktion.

Pointen med tommelfingerreglen er netop at komme med noget bedre end det der.
En grøn udvikler kan godt lave en funktion med 2000 linjer, og mene at der ikke er alverden der kan skæres væk. Men han kan godt fornemme at det er væsentligt mere end en skærmfuld, og dermed formentlig bør deles op.
Gravatar #20 - myplacedk
19. okt. 2011 13:48
Mit råd er: Gør forskel på "hvad" og "hvordan". Der hvor koden beslutter HVAD der skal gøres, skal man ikke definere HVORDAN det gøres. Det er ikke kun for at holde metoderne korte, det er også en hjælp til at strukturere sin kode fornuftigt.

Fx:

public boolean addToBasket(Sting sku, int amount) {
if (!stock.isAvailable(sku, amount) {
...

Det ville være todset hvis det var her man kodede, hvordan man tjekker lageret. Koden her handler om at lægge varer i kurven.
Gravatar #21 - myplacedk
19. okt. 2011 13:58
Windcape (18) skrev:
Helst ikke :(

Det gør jo ikke noget man kan læse hele TO funktioner på ét skærmbillede.

Enig. Den ekstra plads skal ikke bruges på ekstra lange funktioner. Det bliver man ikke mere effektiv af. Til gengæld er der plads til at vise flere metoder, flere værktøjer, dokumentation, test-resultater osv.

Jeg må indrømme at jeg ikke har det store indtryk af hvor lange mine længste metoder er. Jeg er erfaren nok til at bruge "code-smell" metoden. ;-)
Gravatar #22 - kasperd
19. okt. 2011 14:41
Det er vist på tide jeg refaktorerer lidt af den kode jeg arbejder på. Jeg opdagede at en af mine funktioner er nået op på 312 linier. Ifølge gcov er der 177 kodelinier hvoraf 119 er dækket af unittest.

Så er spørgsmålet om jeg skal refaktorerer koden før eller efter jeg skriver unit tests.
Gravatar #23 - Qw_freak
19. okt. 2011 14:49
kasperd (22) skrev:
refaktorerer

??

Så hvis jeg forstår jer ret har i jeres programmer delt op i en masse små filer med mellem 25 og 200 linier kode ihver???
Gravatar #24 - Windcape
19. okt. 2011 14:51
Qw_freak (23) skrev:
??
Jargon for at omskrive koden, på en eller anden måde, uden at ændre i funktionaliteten.

Det kunne f.eks. være at splitte én metode op i 2-3 metoder.

Martin Fowler & friends har skreven en hel bog om emnet
Gravatar #25 - kasperd
19. okt. 2011 15:08
Qw_freak (23) skrev:
Så hvis jeg forstår jer ret har i jeres programmer delt op i en masse små filer med mellem 25 og 200 linier kode ihver?
Nej. Så små synes jeg ikke filerne skal være. Hver funktion bør holdes på et sted mellem 4 og 50 linier. Hver fil indeholder et antal beslægtede funktioner. Det er ikke noget problem at have flere hundrede linier i en fil, det skal bare ikke være en enkelt funktion der er så lang.

For de fleste datastrukturer der indgår i din kode er det en god idé at begrænse antallet af filer der skal kende indholdet. F.eks. kan man tit have en situation hvor kun en enkelt fil indeholder beskrivelsen af en struktur, så kun funktioner i den fil kan modificere strukturen. Funktioner i andre filer kan stadigvæk godt manipulere pointere/referencer til strukturen, men ikke dens indhold.
Gravatar #26 - Windcape
19. okt. 2011 15:22
marker interfaces, go!

namespace + definition, ~ 3-5 linjers kode. I en seperat fil, jow jow.

kasperd (25) skrev:
F.eks. kan man tit have en situation hvor kun en enkelt fil indeholder beskrivelsen af en struktur, så kun funktioner i den fil kan modificere strukturen. Funktioner i andre filer kan stadigvæk godt manipulere pointere/referencer til strukturen, men ikke dens indhold.
Nu begynder du at snakke C specifikt.

Det er ikke så relevant i andre sprog. Ligesom marker interfaces ikke er relevant i C/C++ :p
Gravatar #27 - onetreehell
19. okt. 2011 15:31
Man skal også passe på med bare at dele alting op i mange filer. Jeg har set et par gange hvor folk har delt ting op på en tilsyneladende tilfældig måde, og så bliver det bare noget rod.

Windcape (11) skrev:
Ligeledes er det nemmere at have et split-view på den måde.

Få dig en ordentlig editor!!
Gravatar #28 - Windcape
19. okt. 2011 15:35
onetreehell (27) skrev:
Få dig en ordentlig editor!!
Jeg kan godt lave split view med samme fil, det er bare nedern at overskue.

Gravatar #29 - onetreehell
19. okt. 2011 15:40
#28
onetreehell (27) skrev:
Få dig en ordentlig editor!!


:)
Gravatar #30 - Windcape
19. okt. 2011 15:47
#29

Problemet med at det er samme fil, er jo at du har samme fil åben i flere tabs. Det er jo sådan lidt fjollet. Jeg bruger netop filnavnen i mine tabs til at give et hurtigere overblik :p

Så det kan lade sig gøre, jeg synes bare ikke det er gavnligt. (Og så er Visual Studio den bedste editor der findes, men det er en anden diskussion)
Gravatar #31 - myplacedk
19. okt. 2011 17:02
Heh, den her tråd ligner efterhånden en masse bitte må bidder fra første semester på datamatiker-uddannelsen. :-D

Nu vil jeg ikke tage modet fra nogen, men her er lidt perspektiv:

Da jeg gik på datamatiker, havde vi faget "programmering" i første semester. Det var få timer om ugen i et halvt år. Da det var overstået, kunne klassen programmere.

Men programmering er ikke nok. Hele uddannelsen varer godt 2 år, og det er vel over halvdelen som handler om objektorienteret, arkitektur, databaser osv. Og uddannelsen er en kort introduktion til at lave software. Og det enda kun den mest tekniske del af det. Så er der også usability (UX), design, forretningsanalyse, test, ledelse... og hver af dem kan bestå af flere stillinger. (fx. har vi generelle testere, systemtestere, testledere...) - disse områder bliver kun kort berørt under datamatiker-uddannelsen.

Min pointe er: Man lærer ikke så meget af at en enkelt tråd i et forum. Det vigtigste man kan håbe at finde ud af er HVAD man skal lære.

Hvis du gerne vil lave software på hobbyplan, og gerne vil tage det næste skridt efter at have lært at programmere, så vil jeg nok anbefale at læse om: Patterns, unittests (evt. test-driven development) og refactoring. Og det er nok en god ide at finde læsestof med eksempler på samme sprog som du selv koder i.
Gravatar #32 - kasperd
19. okt. 2011 17:20
myplacedk (31) skrev:
evt. test-driven development
Efter at have taget en datalogi uddannelse på universitetet og brugt nogle år i erhvervslivet vil jeg fremhæve test-drevet udvikling som den vigtigste ting jeg ikke lærte under min uddannelse. Jeg tror nok vi blev præsenteret for begrebet, men det var ikke noget vi prøvede at bruge.

Et introduktionskursus i programmering mener jeg bør struktureres så alle opgaver der involverer at skrive et program også kræver at der skrives unit tests til at dække alle forgreninger i programmet. Om man så skriver unit test før eller efter den kode der testes vil jeg ikke hænge mig i, så længe man bliver præsenteret for begge muligheder.
Gravatar #33 - Mnc
19. okt. 2011 17:54
02-07 holdet på Datafagteknikeruddannelsen i Ringsted blev da både introduceret for UT og vi brugte en uges tid på at rode med det.

Dog på ingen måde nok, da jeg har glemt næsten det hele af det. :P
Gravatar #34 - Windcape
19. okt. 2011 18:00
Hvis folk så bare fattede at der ikke er nogen grund til at skrive unit tests for kode med en CC på 1, så ville det jo være endnu bedre.

Uddannelserne opfordre generelt folk til at skrive meningsløse tests.

Og så giver unit-tests først rigtig god mening, når man har lært dem sammen med mocks, og DI/IoC. Hvilket jeg vurdere til at være et niveau højere end hvad der kan forventes på bachelor-niveau.

(Men så igen... jeg gik på en uddannelse for at få papiret, ikke for at lære noget)
Gravatar #35 - Windcape
19. okt. 2011 18:09
myplacedk (31) skrev:
Heh, den her tråd ligner efterhånden en masse bitte må bidder fra første semester på datamatiker-uddannelsen. :-D
På datamatiker uddannelsen forklares der lidt om det. Men ikke meget om faktisk strukturing af større projekter / eller strukturing af kode.

På ingeniør- og datalogi studiet, forklares der stort set intet, da det forventes at være op til de studerende selv at finde ud af.

Problemet er nok også, at det er meget teknologi-specifikt. I Java tvinges du til at træffe nogle valg, som ikke nødvendigvis er ideele, og i .NET har du større frihed, men forsøger stadigvæk at integere med dit udviklingsmiljø.

Og så er der folk som kasper, der bruger emacs og en masse seperate filer i en mappe, og synes det er en fornuftig projektstruktur :p

Overordnet set, må det vel være op til erfarne udviklere (nb. erfaring kan fåes andre steder end en arbejdsplads!), at forklare de nye hvordan tingene foregår.

Så lærer folk det efterhånden.

Den bedste måde at lære det på, er at arbejde med større projekter. Hobby, Arbejde eller Open Source.
Gravatar #36 - arne_v
19. okt. 2011 18:14
Windcape (34) skrev:
Hvis folk så bare fattede at der ikke er nogen grund til at skrive unit tests for kode med en CC på 1, så ville det jo være endnu bedre.


Nej.

Hvor pokker har du lært noget så katastrofalt.

For det første:

Man bør skrive unit tests for al kode som kan indeholde fejl.

Kode med cyklomatisk kompleksitet 1 kan også indeholde fejl og skal dermed testes.

Og det er ikke tør teori, men noget der ses i praksis.

For det andet:

Formålet med unit test er at kunne teste om en vilkårlig implementation opfylder interface spec.

Cyklomatisk kompleksitet er ikke interface men implementation.

Det duer ikke at man undlader at skrive unit test for noget fordi implementationen er simpel, og så udskifter man senere implementationen med en mere kompleks og forventer at kunne teste om den nye implementation virker med den gamle unit test.
Gravatar #37 - Windcape
19. okt. 2011 18:28
arne_v (36) skrev:
Hvor pokker har du lært noget så katastrofalt.
Hvis jeg husker rigtigt, af Mark Seemann.

arne_v (36) skrev:
Kode med cyklomatisk kompleksitet 1 kan også indeholde fejl og skal dermed testes.
Så du vil skrive en unit test, der sikre at følgende kode (C#) virker?


public string Test { get; set; }


Det mener du forhåbenlig ikke seriøst?

arne_v (36) skrev:
Formålet med unit test er at kunne teste om en vilkårlig implementation opfylder interface spec.
Rigtigt.

Implementationstest gøres bedst ved integration testing. Som jeg mener er langt mere relevant end unit testing.

arne_v (36) skrev:
Cyklomatisk kompleksitet er ikke interface men implementation.
Men når man nu engang tester implementationen, så er der fandme ingen grund til at teste ting med CC på 1, bare for at nå 100% coverage. (Se property eksemplet).

arne_v (36) skrev:
Det duer ikke at man undlader at skrive unit test for noget fordi implementationen er simpel, og så udskifter man senere implementationen med en mere kompleks og forventer at kunne teste om den nye implementation virker med den gamle unit test.
Kan du komme på et eksempel på noget kode med en CC på 1, hvor du mener det er relevant at skrive en unit test?

Jeg har endnu ikke oplevet det.
Gravatar #38 - arne_v
19. okt. 2011 18:41
Windcape (37) skrev:
Hvis jeg husker rigtigt, af Mark Seemann.


Shame on him then.

Windcape (37) skrev:
Så du vil skrive en unit test, der sikre at følgende kode (C#) virker?


public string Test { get; set; }


Det mener du forhåbenlig ikke seriøst?


Jo da.

Ikke så meget fordi der kan være fejl. Jeg har tillid til C# compileren.

Men hvis den kode senere bliver erstattet af en property med kode, så ønsker jeg at unit test faktisk tester den.

Og jeg kender ikke noget sprog hvor man kan angive i et interface at en implementation kun kan have cyklomatisk kompleksitet 1.

Windcape (37) skrev:
Men når man nu engang tester implementationen, så er der fandme ingen grund til at teste ting med CC på 1, bare for at nå 100% coverage. (Se property eksemplet).


Man tester ikke for at få 100% coverage, men fordi at det er nødvendigt.

Windcape (37) skrev:
Kan du komme på et eksempel på noget kode med en CC på 1, hvor du mener det er relevant at skrive en unit test?

Jeg har endnu ikke oplevet det.


Man bør teste al kode som kan være forkert.

Jeg finder det lidt svært at tro at du ikke kan forestille dig kode med cyklomatisk kompleksitet 1 med fejl.

Nogle af de klassiske er:
* copy paste af setter/getter hvor man ikke får rettet navnet alle steder
* setter hvor man glemmer this

Gravatar #39 - arne_v
19. okt. 2011 18:48
#1

Det meget korte svar er meget simpelt: ved større programmer skal der deles op.

Det lidt længere svar er noget mere komplekst.

Der skal faktisk laves 3 opdelinger af programmet:
A) en logisk opdeling
B) en fysisk opdeling af source code
C) en fysisk opdeling af deployable code

re A)

Hvis OO opdeler du i flere niveauer:
* pakke/namespace (som kan nestes)
* klasse
* metode
hvis proecuralt opdeler du tilsvarende i:
* modul/unit
* proceure/function/subroutine

At finde en passende opdeling i disse er klassisk software design. En logisk opdeling baseret på lav ekstern kobling og høj intern sammenhæng.

re C)

For Windows native + .NET:
* exe
* dll
for *nix native:
* (executable)
* so
for VMS native:
* (executable) exe
* (shareable) exe
for Java:
* jar
* war
* rar
* ear
for diverse script:
* source code (eventuelt stripped)

Kriteriet for hvad der er godt her vil typisk være hvad det giver mening at kunne opdatere uafhængigt af resten.

re B)

Opdeling i:
* projekter
* foldere/mapper
* filer

Lidt afhængig af teknologi vil B tit være meget bestemt af A og C.

Hvis man har valgmuligheder skal man vælge således at det er nemt at:
- finde koden til en given klasse & metode
- finde koden til en given deployable unit
Gravatar #40 - Windcape
19. okt. 2011 18:49
arne_v (38) skrev:
Men hvis den kode senere bliver erstattet af en property med kode, så ønsker jeg at unit test faktisk tester den.
Problemet her, er så at i C# og Java, bruger man jo tit classes til at repræsentere data strukturer.

Dvs. der vil ALDRIG være kode i ens properties. Da de faktisk ligeså godt kunne være public fields. (Hvorfor vi ikke gør det, tror jeg er mest for at gøre intellisense glad).

Og så er det altså meningsløst at skrive 100 unit tests, for at opnå 100% coverage, af en datastruktur uden faktisk funktionalitet i.

arne_v (38) skrev:
Man tester ikke for at få 100% coverage, men fordi at det er nødvendigt.
Jeg kender en del i USA, der skriver unit test for 100% coverage, pga. kontraktkrav. Hvilket indbefatter at teste kode, der er meningsløst at teste.

arne_v (38) skrev:
* copy paste af setter/getter hvor man ikke får rettet navnet alle steder
Autoproperties ;-) Netop at lade programmeringssproget hjælpe til at udrydde den slags fejl, er en dejlig ting.

arne_v (38) skrev:
* setter hvor man glemmer this
I det mindste ikke et problem i C#.

Gravatar #41 - arne_v
19. okt. 2011 19:01
Windcape (40) skrev:
Problemet her, er så at i C# og Java, bruger man jo tit classes til at repræsentere data strukturer.

Dvs. der vil ALDRIG være kode i ens properties.


Det sker faktisk at man putter funktionalitet i properties.

Windcape (40) skrev:
Og så er det altså meningsløst at skrive 100 unit tests, for at opnå 100% coverage, af en datastruktur uden faktisk funktionalitet i.


Man skriver stadig unit test af API'et ikke af implementationen.
Gravatar #42 - Windcape
19. okt. 2011 19:08
arne_v (41) skrev:
Det sker faktisk at man putter funktionalitet i properties.
Jeps. Selvom det er imod Microsofts guidelines (de anbefaler man bruger en normal metode, for at gøre opmærksom på at det ikke er en instant operation)

arne_v (41) skrev:
Man skriver stadig unit test af API'et ikke af implementationen.
Problemet er f.eks. at det jeg arbejder med, bruger vi f.eks. en masse specifikke implementationer (Commands) som bruges i forbindelse med brugerfladen.

De kan unit-testes. Men det giver mere mening at bruge dem til integration testing.

Men det er jo typisk at man skriver unit tests for ALT koden nu om dage. Også internal/private kode.

Hvilket jeg ser som en fejl.
Gravatar #43 - arne_v
19. okt. 2011 19:53
#42

Jeg mener ihvertfald ikke at man skal skrive unit test kode baseret på viden om hvorvidt en implementation er simpel eller kompleks.
Gravatar #44 - arne_v
19. okt. 2011 19:55
#42

Og at unit teste private/internal kode er noget tvivlsomt.

Det kan nemt gøre at unit tests fejler selv ved en korrekt ændring af implementationen.
Gravatar #45 - Mort
19. okt. 2011 20:11
#44

At unit teste private/internal kode er da lige så vigtig som at teste public/protected kode.

Unit testen har til formål at checke at ens kode gør som man forventer den gør, også efter at nogen har ændret på den. Det er lige så relevant for kode som er intern som for kode der er ekstern tilgængelig.

Unit testen må ikke binde sig tæt op af en bestemt implementation. Gør den det bliver den mere eller mindre meningsløs da den så blot tester at koden er som koden er.

Dens funktion skal i stedet være at teste at koden udfører den opgave som koden var tænkt at udføre, uden hensyn til hvordan det er implementeret.

Hvis unit testen kan verificere at den testede kode bliver udført som forventet, må det også forventes at kode som benytter den testede kode, fortsat virker selv efter at implementationen er ændret.
Gravatar #46 - arne_v
19. okt. 2011 20:16
#45

Det er vel helt validt at fjerne en internal/private metode eller ændre dens funbktion i forbindelse med at man skifter implementation, så længe at alle de public metoder ikke fjernes eller ændrer funktionalitet.

Hvis man unit tester internal/private behøver fejl i unit test ikke at betyde fejl i ændringen af implementationen.
Gravatar #47 - Darwind
19. okt. 2011 20:29
kasperd (32) skrev:
Efter at have taget en datalogi uddannelse på universitetet og brugt nogle år i erhvervslivet vil jeg fremhæve test-drevet udvikling som den vigtigste ting jeg ikke lærte under min uddannelse. Jeg tror nok vi blev præsenteret for begrebet, men det var ikke noget vi prøvede at bruge.
[...]


Vi lærte også nærmest kun ordet på min bachelor - lidt ærgeligt faktisk.

Har du nogle gode eksempler på læsestof til at komme igang med TDD? Jeg er igang med at sætte mig ind i TDD, men kunne godt bruge et par gode "grundbøger" omkring emnet ;)
Gravatar #48 - Mort
19. okt. 2011 20:33
#46

Ja det er da fuldkommen tilladt at fjerne eller ændre en metode så den skifter funktion, men gør man det så har man også ændret intentionen med metoden og så bør unit testen ændres tilsvarende da det nu er noget andet den tester.

Den eneste grund jeg kan se til ikke at unit teste en private/internal metode er hvis man ikke benytter den nogen steder, da det er det eneste tidspunkt hvor det at ændre implementationen kan gøres uden der er nogen chance for at påvirke andre steder i koden - Men hvis en metode ikke benyttes andre steder i koden, så er der heller ingen grund til at metoden eksisterer.
Gravatar #49 - arne_v
19. okt. 2011 20:42
#48

Private metoder bruges internt i klassen.

Internal metoder bruges internt i samme assembly.

Der er masser af gode grunde til at have sådanne metoder. Det kan gøre koden langte bedre struktureret.

Men der er ingen pointe i at unit teste dem, da de ikke er en del af det API der exposes til andre.

Og man kan ændre dem når man ændrer i implementationen uden at ændre i interfacet.
Gravatar #50 - arne_v
19. okt. 2011 21:03
#49

Eksempel.

Man har:


private static long fac(int n) {
long res = 1;
for(int i = 1; i <= n; i++) {
res *= i;
}
return res;
}
public static int comb(int n, int p) {
return (int)(fac(n)/(fac(n-p)*fac(p)));
}


og erstatter den med:


public static int comb(int n, int p) {
long res = 1;
for(int i = n; i > n-p; i--) {
res *= i;
}
for(int i = 1; i <= p; i++) {
res /= i;
}
return (int) res;
}


Jeg kan ikke se nogen grund til at unit tests så skulel fejle fordi fac mangler.
Gå til top

Opret dig som bruger i dag

Det er gratis, og du binder dig ikke til noget.

Når du er oprettet som bruger, får du adgang til en lang række af sidens andre muligheder, såsom at udforme siden efter eget ønske og deltage i diskussionerne.

Opret Bruger Login