Refaktorering er nu komplet – Prism implementeret

Skrevet - Saturday, January 24th, 2009 kl. 20:34 | Kategori - * Kodning

Undervejs i den uges arbejde, det tog at indføre Prism i vores projekt, var vi undervejs meget tæt på helt at forkaste frameworket. Det er nemlig ikke muligt for os helt at opdele funktionaliteten i moduler alligevel. Det er ikke frameworkets skyld, men derimod brugerkrav. En af de grundlæggende præmisser er, at alt funktionalitet, der giver bare den mindste mening i den givne kontekst skal kunne udføres via kontekstmenuer.

Kontekstmenuer i WPF er rigtig smarte, fordi de er nemme at lave og nemme at genbruge. Problemet opstår når den mængde funktionalitet spænder over flere moduler… I Prism er det udgangspunktet, at man påkobler funktionalitet fra andre moduler run-time. Det går også rigtig godt med knapper o.lign., men når det er grafiske elementer, der først bliver lavet run-time (dvs. når brugeren første gang har visuel adgang til dem… så er kompleksiteten lige pludselig en helt – og jeg mener helt – anden.

Vi har været langt omkring for at finde en løsning – det viser sig at for at få fat i en kontekstmenu, der ligger i en DataTemplate, som bliver valgt ud fra en TemplateSelector, som bestemmes ud fra en anden TemplateSelector… så er man ude på så dybt vand at koden bliver meget svær at vedligeholde og meget sårbar.

Samtidig ville vi gerne kunne genbruge commands på tværs af moduler netop for at supportere meget rige kontekstmenuer – og det endte med at vi måtte gå på kompromis med et par designprincipper – og til dels lave en lille smule om i den måde Prism er tiltænkt. Vi blev for det første nødt til at gøre vores IoC-container tilgængelig fra commands – vi valgte en statisk klasse. Ikke fordi den er pæn (på ingen måde), men det var den simpleste metode og en vi tidligere har brugt med succes. Derudover måtte vi hive interfaces fra alle Presenters (fra vores MVP-triader i modulerne) ned i samme lag som commands – igen for at have adgang til dem via IoC’en.

Det har resulteret i at de enkelte moduler ikke er helt så selvstændige som vi havde håbet, men til gengæld undgik vi en smertefuld refaktorering af hele vores arkitektur. Samtidig giver det os nogle muligheder for at ‘lokke’ med kunderne – det vil sige vise en deaktiveret funktionsmenu for de moduler de ikke har købt adgang til. De ting, der endte med at ligge i modulerne er de specialiserede domain services (alt udover GetById,Save og Find()), implementationen af Presenters og deres Views (inkl. interfaces).

Refaktoreringen blev besværliggjort en anelse af vores tilgang. Vi tog den store hammer, og valgte at oprette et nyt projekt og så importere tingene efterhånden som vi fik dem til at passe ind i puslespillet. Eftersom der var et par vildskud imellem endte vi med at flytte en række elementer mange gange og vi importerede først vores test-suite til allersidst, hvilket skulle vise sig at være en tåbelighed, da vi på det tidspunkt havde ændret namespaces… Her viste vores investering i R# sig at være guld værd… jeg tør ikke tænke på hvor længe vi ville have brugt, hvis vi skulle have gjort det via VS2008′s funktionalitet. Samtidig kunne vi ikke modstå fristelsen til at lave et par andre refaktoreringer undervejs…

Det vi burde have gjort var at beholde vores projekt, og så oprette de nye moduler og flytte klasserne – det ville også have hjulpet os til hurtigere at have opfanget problemområderne. Og så have lavet de andre mindre refaktoreringer efter alt var oppe at spille. Men alt i alt er vi meget tilfredse med refaktoreringen – vi har nu en projektstruktur, som er langt mere overskuelig.

Feed | Trackback |

Post a Comment