mboost-dp1
Spgsml til udvikling af større komplekse programmer??
- Forside
- ⟨
- Forum
- ⟨
- Programmering
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?
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?
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.
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.
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.
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...
Læs evt mere her:
http://en.wikipedia.org/wiki/Component-based_softw...
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.
Det kommer an på din definition af modul.Qw_freak (1) skrev:eller er det bygget op af moduler som snakker sammen?
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.
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.Qw_freak (3) skrev:hva, uddyb venligst..?
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.
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.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.
At du overhovedet tænker i "filer" er lidt skræmmende.Qw_freak (5) skrev:Det vil sige det er meget normalt at lave flere individuelle filer og så sætte dem sammen til sidst?
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.
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.
Generelt set må man vel bruge det antal linjer der er nødvendig per funktion.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.
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 :)
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.
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.Mnc (4) skrev:Hvis jeg kigger i bin mappen for eksempelvis Portal, så er der 57 dll filer.
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.
Jeg har 45 til 59.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.
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
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.
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:
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.
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.
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. ;-)
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.
Så er spørgsmålet om jeg skal refaktorerer koden før eller efter jeg skriver unit tests.
Jargon for at omskrive koden, på en eller anden måde, uden at ændre i funktionaliteten.Qw_freak (23) skrev:??
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
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.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?
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.
marker interfaces, go!
namespace + definition, ~ 3-5 linjers kode. I en seperat fil, jow jow.
Det er ikke så relevant i andre sprog. Ligesom marker interfaces ikke er relevant i C/C++ :p
namespace + definition, ~ 3-5 linjers kode. I en seperat fil, jow jow.
Nu begynder du at snakke C specifikt.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.
Det er ikke så relevant i andre sprog. Ligesom marker interfaces ikke er relevant i C/C++ :p
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.
Få dig en ordentlig editor!!
Windcape (11) skrev:Ligeledes er det nemmere at have et split-view på den måde.
Få dig en ordentlig editor!!
#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)
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)
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.
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.
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.myplacedk (31) skrev:evt. test-driven development
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.
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)
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)
På datamatiker uddannelsen forklares der lidt om det. Men ikke meget om faktisk strukturing af større projekter / eller strukturing af kode.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å 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.
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.
Hvis jeg husker rigtigt, af Mark Seemann.arne_v (36) skrev:Hvor pokker har du lært noget så katastrofalt.
Så du vil skrive en unit test, der sikre at følgende kode (C#) virker?arne_v (36) skrev:Kode med cyklomatisk kompleksitet 1 kan også indeholde fejl og skal dermed testes.
public string Test { get; set; }
Det mener du forhåbenlig ikke seriøst?
Rigtigt.arne_v (36) skrev:Formålet med unit test er at kunne teste om en vilkårlig implementation opfylder interface spec.
Implementationstest gøres bedst ved integration testing. Som jeg mener er langt mere relevant end unit testing.
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:Cyklomatisk kompleksitet er ikke interface men implementation.
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?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.
Jeg har endnu ikke oplevet det.
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
#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
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
Problemet her, er så at i C# og Java, bruger man jo tit classes til at repræsentere data strukturer.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.
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.
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:Man tester ikke for at få 100% coverage, men fordi at det er nødvendigt.
Autoproperties ;-) Netop at lade programmeringssproget hjælpe til at udrydde den slags fejl, er en dejlig ting.arne_v (38) skrev:* copy paste af setter/getter hvor man ikke får rettet navnet alle steder
I det mindste ikke et problem i C#.arne_v (38) skrev:* setter hvor man glemmer this
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.
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:Det sker faktisk at man putter funktionalitet i properties.
Problemet er f.eks. at det jeg arbejder med, bruger vi f.eks. en masse specifikke implementationer (Commands) som bruges i forbindelse med brugerfladen.arne_v (41) skrev:Man skriver stadig unit test af API'et ikke af implementationen.
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.
#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.
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.
#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.
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.
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 ;)
#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.
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.
#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.
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.
#49
Eksempel.
Man har:
og erstatter den med:
Jeg kan ikke se nogen grund til at unit tests så skulel fejle fordi fac mangler.
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.