RTFM - og hold så i øvrigt kæft!

Posted - Monday, July 14th, 2008 at 10:23 pm | Category - Kodning, Rants.

Jeg sniger mig rundt langs panelerne på eksperten.dk. Jeg er ikke helt vild med deres side, men hygger mig en gang imellem med at se hvor mange af spørgsmålene jeg kunne have svaret på - og ind imellem bliver jeg overrasket over en god løsning.

Og så skal jeg selvfølgelig blande mig… Der var en der havde et spørgsmål om et ListView, hvor han gerne ville have sortering på kolonnerne. Ahah! Mit forté - min hammer hedder DataBinding og der er ikke den udfordring, der ikke kan ligne et søm. Kom med en længere udredning om hvordan blot skulle databinde på en liste, der har de rare databinding-interfaces implementeret… der var så en anden bruger, der var kommet med en anden løsning - og af ren nysgerrighed fulgte jeg linket…

Til alles information - ListView kan ikke databindes… Det er ikke bygget til det. Så jeg måtte krybe til korset og indrømme min uvidenhed. Og så naturligvis komme med et link til CodeProject’s artikel om hvordan man kan ombrygge ListViewet til at understøtte DataBinding, så han ikke havde spildt sin tid fuldstændig.

Men det er en vigtig pointe, når man leder efter information på internettet - selv-udråbte guruer tager også fejl. For nu at give mig selv en anelse ros - jeg skrev i det mindste efterfølgende at jeg var en idiot - hvilket langt de færreste gør. Det er lidt som at anvende Google som stavekontrol - du finder blot folk, der er ligeså dårlige til at stave som dig selv…

Og nu vi er ved Eksperten.dk og selvudråbte guruer. Mange af løsningerne bærer præg af at det er rene amatører der sidder bag skærmen og svarer. Og det værste man kan gøre er at blande sig i diskussionen med fakta. Af en eller anden årsag er idioter uimodtagelige for kritik og korrektioner og det eneste man får ud af det er at blive svinet til.

Så er der os heldige, der har en blog, hvor vi bare kan slette kommentarer fra idioter, som skriver at forfatteren er en idiot…

Forretningsobjekter, databinding og WPF

Posted - Saturday, July 12th, 2008 at 12:22 am | Category - Kodning.

Efter at have brugt CSLA i omkring et år, er min absolut favorit-detalje hans brug af GetProperty<T>(SomeProperty) ;og SetProperty<T>(SomeProperty,value); sammen med en static SomeProperty som registreres. Han anvender det bl.a. til n’level undo og for at følge state i objekternes levetid (IsNew, IsDirty, IsDeleted osv.). Ideen er at alle properties registreres i en matrice, og alle ændringer noteres i matricen efterhånden som de sker, så det altid er muligt at returnere til en given state.

Det er ikke så meget funktionaliteten, jeg er vild med, som det er syntaxen. Istedet for at have flere linjer kode til at håndtere INotifyPropertyChanged, state osv. i set’eren for properties, sker og vedligeholdes alt dette ‘plumbing’ kode centralt i nogle ganske generelle metoder. Desuden er den typestærk (fordi der anvendes generics). Hvis man vil omgå hele det manageri, anvendes blot LoadProperty<T>(SomeProperty, value);. Overordentlig elegant, hvis du spørger mig.

Kombineret med at det ikke var nødvendigt at spilde tid med backing fields for properties, var reduktionen af kodelinjer enorm for ’standard’ properties. Derfor var det med en del vemod at jeg lavede en prototype uden CSLA. Det var indtil jeg opdagede DependencyObject og DependencyProperty. Jeg havde godt læst, at man kunne anvende DependencyProperty udenfor grafiske elementer (og uden for WPF skulle det vise sig), men var ikke overbevist om at det en god ide.

Lad mig sige det med det samme. Den er ikke ligeså elegant som CSLA’s løsning - men det er deroppe af - til gengæld er den noget mere letvægts (hvilket tæller meget i min bog) og enkel at implementere, hvis man gør sig selv den tjeneste at implementere den ‘korrekt’ (det vil i det her tilfælde sige at bruge den til noget, den ikke er lavet til.) Første tilbageskridt er at den ikke er generisk - og dermed ikke typestærk. Der skal kastes variable - og der kan derfor opstå problemer, hvis man ikke er vågen. De er dog forholdsvis nemme at rette (og finde), hvis man anvender regelmæssig test.

Den fremgangsmåde, som jeg vil anbefale er følgende:

  1. Nedarv fra DependencyObject i en abstrakt klasse, som danner grundlag for dine forretningsobjekter - hvis du anvender DDD, skal du have et niveau under igen - en udspecificering af rod-objekter og ikke-rod-objekter i dine aggregater.
  2. Override SetValue, så du har et sted at styre state.
  3. For hver property laver du en protected static readonly DependencyProperty, som du registrerer som beskrevet her.
  4. Derudover laver du dine normale properties med get’er og set’er som vanligt.

En lille note til 3′eren - hvis du laver dem public, kortslutter du den almindelige logik for at styre hvem der kan ændre hvad. Selvom du har en private set’er, kan man uden videre lave en someObject.SetValue(SomeObject.SomeProperty, someValue);, hvilket er mildt sagt uheldigt. Man kan vælge at tillade det for properties, som har public get’ere og set’ere, men jeg vil på det kraftigste fraråde det, med mindre der er en specifik grund til det. Det er simpelthen for risikabelt især med flere udviklere. Hvis du laver dem private vil nedarvede klasser ikke kunne se dem og de bliver svære at teste på (fx stubs).

Nå, men til det vigtigste - hvad får man ud af at anvende DependencyProperties på denne måde? Fuld databinding uden at røre en finger! Det virker bare. Elegant kode (efter min mening) som er let at vedligeholde. Det eneste der egentlig mangler er en typestærk variant evt. via generics, men mon ikke der er nogen derude, der laver det på et tidspunkt… hint, hint…

CSLA og design odours

Posted - Friday, July 11th, 2008 at 11:39 pm | Category - Kodning.

På arbejde har vi ansat en ny medarbejder, som vi forventer os meget af. Han skal blandt andet få gennemført Agile metoder, patterns mv. Hans første gerning har været at finde tre bøger, som vi læser alle sammen. Et af de begreber jeg har taget med mig er “design smells” eller ting, der lugter i et givent arkitektur og eller kode valg. De ting, der gør at advarselslamperne begynder at lyse (eller blinke vildt…).

Jeg har tidligere lovprist CSLA for at være et gennemtænkt framework for forretningslogik. Jeg synes for så vidt stadig at tankegangen bag er fin - men efter at være blevet klogere (og især efter at have sat mig ind i en række ting i version 3.5 af .Net frameworket) er jeg nået frem til, at jeg vil foreslå at skrotte CSLA. Ikke fordi det ikke virker, men fordi der er 3 større problemområder:

1. Hængende bagud-kompabilitet. CSLA har eksisteret siden version 1.1 af .Net frameworket. Derfor er der en del ekstra systemkald, for at gøre omstillingen fra projekter med den gamle version til den nye version så smertefri som muligt. Det vil sige, at der er en række funktioner som egentlig er forældede, men som stadig understøttes. Det er i sig selv ikke et problem, som ikke kan løses ved uddannelse - men det gør det svært at bruge andres erfaringer.

2. WPF. WPF er multi-trådet bag skærmen. Det giver en række problemer især med sikkerhedsmodellen, som er valgt i CSLA. (Det rækker for vidt at beskrive det i detaljer, men det handler om at man ikke kan være sikker på at en given tråd er korrekt auth’et.) Det vil sige, at hele det område af CSLA stort set er værdiløst i dens nuværende form.

3. Silverlight (og til dels WPF) kører som udgangspunkt i en Internet sandkasse, som ikke tillader reflection i særlig vidt omfang. Eftersom CSLA benytter meget refleksion, kan det per definition ikke anvendes til en ren web-klient der anvender Silverligt eller WPF.

De tre punkter er i sig selv væsentlige, fordi det decimerer værdien af et stort (og tungt) framework, men det sidste punkt som er på min agenda, er en ‘ny’ ting, jeg har læst mig til. Det er en stor del af Agile processer. Needless Complexity. Altså, overdreven teknisk løsning på et simpelt problem. CSLA er bygget til konkrete klasser - og ikke abstrakte klasser eller interfaces. Derudover anvendes mobile objekter, som serialiseres i vidt omfang for at understøtte en høj grad af mobilitet med hensyn til hvordan data skaffes (remoting, webservice, lokal klient osv.). Det gør vedligeholdelse til en stor tung opgave og mindsker fleksibiliteten.

Alt i alt reducerer det CSLA til at DataBinding er fuldt implementeret, valideringsregler, fuld understøttelse af ‘aggregater’ (objekter, der indeholder andre objekter - bruges især inden for Domain Driven Developement) samt en understøttelse af mange forskellige scenarier for data-fremkomst i den samme løsning. Som jeg i senere indlæg vil belyse, er databinding-issues nemt overvundne i WPF, valideringsregler ligeså - hvilket ender os tilbage ved at værdien af CSLA ikke står mål med investeringen af kompleksitet og tid.

Så, CSLA er på vej ud. Jeg blev klogere af at læse bogen (og dermed tankegangen) bag det, men nu har det udlevet sin rolle. Det kan sagtens være at det får en revival senere (selvom det er tvivlsomt med den bagage af bagud-kompabilitet, han slæber med sig), men for nuværende er projektet (i hvert fald for os) kollapset under dets egen vægt.

« Previous entries