Programmeer architectuur verbeteren

Pagina: 1
Acties:

Acties:
  • +1 Henk 'm!

  • 4Real
  • Registratie: Juni 2001
  • Laatst online: 14-09-2024
De laatste tijd val ik steeds over het punt dat mijn code te snel onleesbaar en onderhoudbaar wordt. De laatste tijd programmeer ik meer in C# dan in PHP en merk dat het een wereld van verschil in. In PHP pas ik Zend Framework en Doctrine toe, zodoende heb ik bepaalde lagen al voor grote delen klaar liggen en kan daarop door bouwen. Daarnaast is het bij PHP nog eenvoudig, omdat je een verzoek hebt voor data en deze toont of aangeleverde data verwerkt. Echter in C# merk ik dan instanties veel langer kan bestaan en hier een goede architectuur voor vinden is lastig.

Als voorbeeld ben ik nu bezig met een applicatie welke mijn muziekcollectie doorneemt en dat opslaat in een database. Dit is realiseerbaar, maar ik merk dat ik geen herbruikbare onderdelen krijg en als ik iets soortgelijk wil of er op door wil bouwen, dat er aardig wat refactor werk bij komt kijken. Vooral het opzetten van classes is iets wat moeite kost. Data inlezen vanaf de hardschijf zou via een speciale class kunnen, maar via 10regels code in de Form class kan ik ook de data krijgen welke ik nodig heb. Echter als ik dit blijf doen dan heb ik na een tijdje een Form class van honderden regels code en is het helemaal niet meer leesbaar. Aan de andere kant als ik deze logica in een class stop dan is het weer lastig om met de presentatielaag te communiceren. Het definiëren van classes, wat hun functie is en hoe je ze in een applicatie toepast kost mij erg veel moeite.

Zijn hier ook best practices in of bepaalde architecturen welke toepasbaar zijn, zodat je meer gedwongen wordt om bepaalde werkzaamheden in lagen van je applicatie te verwerken? Tevens het opzetten van classes, hoe kun je deze opzetten, zonder dat ze grote afhankelijkheden binnen te applicatie veroorzaken?

Acties:
  • 0 Henk 'm!

  • Haan
  • Registratie: Februari 2004
  • Laatst online: 18:46

Haan

dotnetter

Je zou eens kunnen beginnen met wat lezen over SOLID, je haalt zelf bijvoorbeeld al indirect de S van single responsability aan :) Verder gewoon veel oefenen en lekker blijven refractoren, niemand schrijft in 1x een perfecte applicatie.

Kater? Eerst water, de rest komt later


Acties:
  • 0 Henk 'm!

  • Lethalis
  • Registratie: April 2002
  • Niet online
Voor het bepalen van welke functionaliteit waar hoort, kun je de GRASP richtlijnen gebruiken:

Wikipedia: GRASP

Wat de architecturele lagen betreft, zit je wat lastig in Windows Forms. Zou je naar WPF overstappen, dan kun je MVVM gebruiken (Model View ViewModel). De WPF controls zijn dan de View, het Model de gegevens, en het ViewModel de class die de boel aan elkaar knoopt door een presentatie te vormen van het model waaraan de WPF controls kunnen binden.

MVVM is een veelgebruikte architectuur.

Windows Forms heeft er echter standaard geen ondersteuning voor en loopt sowieso op veel fronten achter. Het is daarmee sowieso lastig om handig met classes te werken. Dan moet je gaan kloten met Object datasources en classes die INotifyPropertyChanged implementeren. Bij Windows Forms is terugvallen op standaard datasets helaas veel eenvoudiger, omdat het daarvoor gemaakt is.

Bij een groot Windows Forms project waar ik aan werk, hebben we dus ook veel wrapper classes om datasets heen, om functionaliteit die bij elkaar hoort een plek te geven.

In jouw geval zou ik dus een class hebben die de gegevens inleest, en ook een DataSet bevat waaraan de user interface kan koppelen.

Maar veel liever zou ik voor WPF en MVVM kiezen ;)

[ Voor 31% gewijzigd door Lethalis op 06-06-2017 16:27 ]

Ask yourself if you are happy and then you cease to be.


Acties:
  • +1 Henk 'm!

  • Gaius
  • Registratie: September 2001
  • Niet online
4Real schreef op maandag 5 juni 2017 @ 20:03:
Zijn hier ook best practices in of bepaalde architecturen welke toepasbaar zijn, zodat je meer gedwongen wordt om bepaalde werkzaamheden in lagen van je applicatie te verwerken? Tevens het opzetten van classes, hoe kun je deze opzetten, zonder dat ze grote afhankelijkheden binnen te applicatie veroorzaken?
Naast de al genoemde suggesties. zijn Design Patterns wellicht ook interessant voor je.

Ik vond zelf Head First Design Patterns van O'Reilly een leerzaam boek hierover. Leest makkelijk en is niet zo gortdroog als IT-boeken kunnen zijn. :)

Daarnaast is "Clean Code" van Robert C Martin ook erg leerzaam.

Acties:
  • 0 Henk 'm!

  • vickypollard
  • Registratie: Juni 2009
  • Laatst online: 10:45
Lethalis schreef op dinsdag 6 juni 2017 @ 16:21:
Voor het bepalen van welke functionaliteit waar hoort, kun je de GRASP richtlijnen gebruiken:

Wikipedia: GRASP

Wat de architecturele lagen betreft, zit je wat lastig in Windows Forms. Zou je naar WPF overstappen, dan kun je MVVM gebruiken (Model View ViewModel). De WPF controls zijn dan de View, het Model de gegevens, en het ViewModel de class die de boel aan elkaar knoopt door een presentatie te vormen van het model waaraan de WPF controls kunnen binden.

MVVM is een veelgebruikte architectuur.

Windows Forms heeft er echter standaard geen ondersteuning voor en loopt sowieso op veel fronten achter. Het is daarmee sowieso lastig om handig met classes te werken. Dan moet je gaan kloten met Object datasources en classes die INotifyPropertyChanged implementeren. Bij Windows Forms is terugvallen op standaard datasets helaas veel eenvoudiger, omdat het daarvoor gemaakt is.

Bij een groot Windows Forms project waar ik aan werk, hebben we dus ook veel wrapper classes om datasets heen, om functionaliteit die bij elkaar hoort een plek te geven.

In jouw geval zou ik dus een class hebben die de gegevens inleest, en ook een DataSet bevat waaraan de user interface kan koppelen.

Maar veel liever zou ik voor WPF en MVVM kiezen ;)
@OP: dan is een MVVM framework wel handig om te gebruiken nadat je een keertje met MVVM geëxperimenteerd hebt. Scheelt een hoop gedoe :-) Kijk bijvoorbeeld eens naar Caliburn.Micro.

Acties:
  • 0 Henk 'm!

  • Jan_V
  • Registratie: Maart 2002
  • Laatst online: 15:52
Lethalis schreef op dinsdag 6 juni 2017 @ 16:21:
Voor het bepalen van welke functionaliteit waar hoort, kun je de GRASP richtlijnen gebruiken:

Wikipedia: GRASP

Wat de architecturele lagen betreft, zit je wat lastig in Windows Forms. Zou je naar WPF overstappen, dan kun je MVVM gebruiken (Model View ViewModel). De WPF controls zijn dan de View, het Model de gegevens, en het ViewModel de class die de boel aan elkaar knoopt door een presentatie te vormen van het model waaraan de WPF controls kunnen binden.

MVVM is een veelgebruikte architectuur.

Windows Forms heeft er echter standaard geen ondersteuning voor en loopt sowieso op veel fronten achter. Het is daarmee sowieso lastig om handig met classes te werken. Dan moet je gaan kloten met Object datasources en classes die INotifyPropertyChanged implementeren. Bij Windows Forms is terugvallen op standaard datasets helaas veel eenvoudiger, omdat het daarvoor gemaakt is.

Bij een groot Windows Forms project waar ik aan werk, hebben we dus ook veel wrapper classes om datasets heen, om functionaliteit die bij elkaar hoort een plek te geven.

In jouw geval zou ik dus een class hebben die de gegevens inleest, en ook een DataSet bevat waaraan de user interface kan koppelen.

Maar veel liever zou ik voor WPF en MVVM kiezen ;)
Mocht het zo zijn dat er toch WinForms gebruikt blijven worden, dan is het MVP pattern nuttig voor de extra abstractie. Vergelijkbaar met MVC en MVVM, maar beter toepasbaar op Win/WebForms.

Battle.net - Jandev#2601 / XBOX: VriesDeJ


Acties:
  • 0 Henk 'm!

  • xFeverr
  • Registratie: Juni 2011
  • Laatst online: 19:52
Bah... WinForms...

Ik zou inderdaad ook overstappen naar WPF. WinForms is oud en moet je niet meer gebruiken. Wellicht een keer leuk om C# een beetje te leren kennen.

Volg op bijvoorbeeld YouTube wat videos over WPF (Windows Presentation Foundation) en dan vooral het stukje databinding. De bedoeling is in jou geval dat je View dus alleen een weergave moet zijn van wat er in je bibliotheek zit. Je view gaat dus niet zelf aan het werk, want dan creëer je een zogenaamde 'smart UI' en dat is niet te doen zoals je zelf merkt.

Even in het kort: Je maakt een view die de data kan tonen. De data zelf gaat in een ViewModel klasse. Hierin zit bijvoorbeeld een lijst van Music in. Je zorgt voor een klasse die de Music-lijst ophaalt (een MusicLibraryManager oid?) en je hebt het al een stuk beter voor elkaar.

Acties:
  • 0 Henk 'm!

Verwijderd

4Real schreef op maandag 5 juni 2017 @ 20:03:
Data inlezen vanaf de hardschijf zou via een speciale class kunnen...
Even terug naar je oorspronkelijke verhaal - dat hoef je natuurlijk niet in een class te zetten. Het is geen enkel probleem om dat soort basisfunctionaliteiten in gewone functies te zetten zodat ze altijd overal beschikbaar zijn.

Aan de andere kant snap ik ook niet helemaal waarom een dedicated file-reader-class het moeilijk maakt met je presentatielaag te communiceren.

Over het maken van classes zou ik willen zeggen dat het belangrijk is er heel strikt alleen die dingen in te zetten die ook echt met het doel van de class te maken hebben. Een Form-class moet ergens een lijst met velden vandaan halen die getoond moeten worden, maar die moet 'ie niet zelf gaan samenstellen - die moet met 1 call uit een andere class gehaald worden of via een parameter bij je show-method meegegeven worden.

Wat ik zelf bij de wat complexere structuren doe is gewoon in een tekstbestand een lijst met items maken die spelen in het project. Dat kunnen database-gerelateerde items als 'gebruiker' zijn, maar ook puur functionele zoals 'form'. Vervolgens ga ik dan bedenken wat er bij die items hoort, zowel in het kader van tabellen en velden in de database als wat ze moeten doen. Dat ga ik dan vervolgens weer verfijnen omdat ik bijvoorbeeld geen validatie in de form-class wil doen, maar in een field-class.

Zo breid ik het verhaal steeds verder uit totdat alles staat zoals het moet staan, en pas dan begin ik met de daadwerkelijke classes te maken. En dan is het simpel de zaken die je in je tekstbestand op een rijtje hebt gezet omzetten naar classes en jezelf dwingen geen shortcuts te programmeren maar je class 'schoon' te houden.

Acties:
  • +1 Henk 'm!

  • MrFancyPantss
  • Registratie: Mei 2017
  • Laatst online: 15-11-2023
Ik denk dat het in jouw geval het beste is om het zo simpel mogelijk te houden, aangezien ik afleid uit je uitleg dat je niet al te veel kennis hebt over software engineering. Verdeel je software in een paar "lagen" (= projects), die elk hun eigen verantwoordelijkheid hebben. Makkelijkste is om te starten met de basis:

Domain: Bevat enkel je models (in jouw geval wsl Song, PlayList, ...)

DAL (Data Access Layer): Verzameling klasses die enkel data ophalen. (Bv SongRepository met methods als CreateSong(), ReadSongs(), ReadSongById(Guid id), UpdateSong(Song song), DeleteSong(Song song)) -> zoek repository pattern voor meer uitleg

BLL (Business layer): Alle logica die niet puur data access of puur view logica is moet hier. Wat deze laag doet is de DAL aanspreken en eventueel hier nog manipulaties op doen (lichtjes andere objecten returnen bijvoorbeeld. Als in je databank een Song een artiest en producer heeft, maar je view toont alleen de artiest, dan moet producer NIET in de code van je view terug te vinden zijn, dus hier kan je dan bv een mapping doen of in een ander geval een berekening etc...) Deze laag is in kleinere applicaties misschien overbodig, dan kan je gewoon je DAL aanspreken vanuit je view.

View (bv SongsApplicatie.WPF als naam): Hier gebruik je nog een ander pattern zoals bv MVVM of MVC, dit staat los van de andere applicatie architectuur. Hier call je de BLL om je data op te halen. Gebruik hier NIET je domain klasses, maar zorg voor aparte model klasses voor je view (map Domain entities naar models voor je view (ik zeg express niet ViewModels, want dit is nog net iets anders)).

Dit is mss kort door de bocht voor veel mensen, maar ik denk dat deze basic opsplitsing om te starten goed is om separation of concerns door te krijgen. Als je dit wat onder de knie hebt kan je beginnen zoeken naar termen als SOLID om verder te refactoren naar een volledig architecturaal correcte applicatie (bestaat trouwens niet, maar goed :) ).
Pagina: 1