Results 1 to 15 of 15

Thread: Grote applicatie - design tips voor datamodules

  1. #1

    Grote applicatie - design tips voor datamodules

    Hallo!

    Voor een ERP applicatie die toch wel redelijk groot is vroeg ik me af wat ik het beste doe voor de data layer. Ik had gedacht van 1 form = 1 datamodule. Maar hier zie ik al een 1e probleem. Er zitten natuurlijk heel wat kleine formpjes in, die combo boxes moeten voorzien van data. Voorbeelden hiervan zijn: woonplaatsen, landen, betalingsvoorwaarden, vennootschapsvormen, betaalwijzen, BTW regimes, ........ Voor al die kleine forms gaan we al snel met een hoop datamodules zitten met 1 query op. Maar voor de ene form die ene query op de form zetten en geen datamodule gebruiken en voor grotere forms dan wel een datamodule, dat lijkt me dan ook niet netjes en niet consistent. Dus als ik hetzelfde systeem voor gans de applicatie gebruik, dan zal ik al gauw aan 100 forms en 100 datamodules zitten. Ik gebruik Delphi 10.3.2. Mijn eerste vraag is, kan delphi zoveel forms en datamodules aan? Ik heb lange tijd met Delphi XE 5 gewerkt. Was wel stabiel, maar crashte toch ook wel eens op grote builds. Wat Delphi 10 betreft meen ik me nog te herinneren dat de eerste releases (de Seattle dacht ik) nogal wat problemen had met grote projecten.

    Ik vroeg me af hoe mensen het doen die geen gebruik maken van een application server? Gebruiken jullie ook de 1 form - 1 datamodule methode of misschien hebben jullie wat tips?

    Voor Multi-tier architectuur voel ik niet zo veel. Heb ooit nog bij een bedrijf gewerkt die een applicatie ontwikkeld had die multi-tier was. Datasnap was dat toen als ik me niet vergis. Wel we kregen heel wat telefoons om problemen te melden met de verbinding tussen de application server en de client. En ook was dat enkel maar performant voor kleine datasets. Van zodra je met grote datasets werkte waarbij je die data eerst moest fetchen en dan moest opslaan in een ClientDataset, dan zat je al snel met performantie problemen.

    Vele dank alvast!
    Groeten...
    Last edited by stevedeclerck; 04-Nov-19 at 09:13. Reason: typo

  2. #2
    Fornicatorus Formicidae VideoRipper's Avatar
    Join Date
    Mar 2005
    Location
    Vicus Saltus Orientalem
    Posts
    5,469
    Ikzelf heb nooit echt het grote voordeel gezien van "Eén form, één datamodule" (in een vorig leven een werkgever gehad die een aantal van dit soort policies had, zonder er een duidelijke reden voor te hebben). Meer logica zie ik in "Eén soort functionaliteit, één datamodule" (meer het idee achter OO), al kan het zijn dat de "Functionaliteit" zo breed wordt, dat het beter is om het dan weer op te delen in specialisaties. Bedoel je echter of data op de presentatielaag mag bevinden, dan is mijn mening dat dit niet mag. Maar goed: er zijn mensen die afgestudeerd zijn op het gebied van frameworks en UI/business logic scheiding, dus zij zullen er wellicht een goed onderbouwde filosofie over hebben. Ik doe slechts onderhoud en moet het dan doen met code die door voorgangers aan elkaar geplakt is.
    TMemoryLeak.Create(Nil);

  3. #3
    Hallo,

    Ja, daar zit wel in iets in. En die 'geplakte' code, inderdaad...
    Als je voor opsplitsen van functionaliteit gaat, dan zou het denk ik mooi zijn als je zegt van : ok, hier hebben we 1 file, daar zit alles in om de hoofding van een order te maken. Vervolgens heb je dan nog een file, en die file doet alles wat het aanmaken van orderlijnen betreft, enz..... Zo kom je denk ik tot mooi opgesplitste entiteiten met elk een eigen doel. Maar dan zit je al snel aan hopen datamodules. Maar de vraag is : moet je dan nog datamodules gebruiken of breng je dan alles onder in gewone .pas files. Dan heb je de overhead niet van de .dfm files die met datamodules komen. Het vervelende aan flat files is dan wel dat je al de queries in code moet gaan aanmaken en de events koppelen. Ik vind dat op zich niet echt een probleem, maar een collega klaagt daar wel over. Hij vindt het beter om queries visueel te kunnen plaatsen en zo de events te koppelen, dus via datamodule. Maar ik denk dat het toch wel zo is, dat als je alles onderbrengt in een .pas file, je toch de overhead niet hebt van de visuele container die de datamodule met zich mee brengt.

    Confused .......

  4. #4
    Zoals ik er tegenaan kijk staat het al dan niet gebruik van een applicatieserver/middleware los van het ontwerp van je client. Of je client nu direct tegen een database aan praat of tegen middleware of 3 REST API's zou in principe niet uit moeten maken.

    Ik gebruik voor mijn Delphi clients, zeker voor de wat grotere applicaties, het MVVM patroon. Hier een versie van Olaf Monien en hier een versie van Kouraklis Het voordeel van MVVM vind ik dat de view alleen het view-model kent en het view-model alleen het model, dit maakt het erg overzichtelijk, maar het kost wel iets meer moeite om het op te zetten. Het andere voordeel van MVVM is dat je aan een view-model ook meerdere models kunt hangen. Ook kun je veel makkelijker testen omdat je hier het view-model voor kunt gebruiken (Je forms bevatten bijna geen functionaliteit waar iets verkeerd kan gaan).

    Wat betreft het aantal units/datamodules in een project heb ik nooit problemen ondervonden, je moet ze denk ik alleen niet auto-createn.

    Voor Multi-tier architectuur voel ik niet zo veel.
    Het gebruik van middleware kost wel iets aan performance, maar dit zou bij een goed ontwerp in de meeste gevallen geen beperking zijn.

  5. #5
    Fornicatorus Formicidae VideoRipper's Avatar
    Join Date
    Mar 2005
    Location
    Vicus Saltus Orientalem
    Posts
    5,469
    Quote Originally Posted by stevedeclerck View Post
    moet je dan nog datamodules gebruiken of breng je dan alles onder in gewone .pas files. Dan heb je de overhead niet van de .dfm files die met datamodules komen. Het vervelende aan flat files is dan wel dat je al de queries in code moet gaan aanmaken en de events koppelen. Ik vind dat op zich niet echt een probleem, maar een collega klaagt daar wel over.
    Queries komen "In principe" nooit bij mij in losse pas-bestanden, dit maakt ze vaak onleesbaar en soms ook onwerkbaar (ga je parameters met QuotedStr() en IntToStr() aan elkaar plakken? En je bent vaak geneigd om voor het gemak SELECT * FROM table te doen, dan alle benodigde velden expliciet te benoemen). Mijn voorkeur gaat dan echt uit naar datamodules (deze hebben echt niet zoveel overhead: de weergave die jij in de IDE ziet wordt niet meegenomen in de executable) met daarop losse queries, zodat je direct toegang (en overzicht) hebt tot de query zelf. Je kunt zo'n query dan ook meteen koppie-peesten in SSMS (of soortgelijke tool) om een query buiten de applicatie uit te proberen. Tijdens de meetup die we alweer een jaar geleden bij CoolBlue kregen zag ik ook een mooie oplossing: plaats queries buiten de applicatie en laat het framework het zelf automagisch (via "Virtual Interfaces") oplossen, zodat zelfs het framework zelf niet direct iets van de datastructuur hoeft te weten. Hoe het precies werkte ben ik even kwijt, maar ik vond het een mooi idee voor applicaties die heel erg data(base)-driven zijn.
    Last edited by VideoRipper; 04-Nov-19 at 12:30.
    TMemoryLeak.Create(Nil);

  6. #6
    John Kuiper
    Join Date
    Apr 2007
    Location
    Almere
    Posts
    8,643
    Voor een ERP applicatie die toch wel redelijk groot is vroeg ik me af wat ik het beste doe voor de data layer. Ik had gedacht van 1 form = 1 datamodule. Maar hier zie ik al een 1e probleem. Er zitten natuurlijk heel wat kleine formpjes in, die combo boxes moeten voorzien van data. Voorbeelden hiervan zijn: woonplaatsen, landen, betalingsvoorwaarden, vennootschapsvormen, betaalwijzen, BTW regimes, ........ Voor al die kleine forms gaan we al snel met een hoop datamodules zitten met 1 query op.
    Ik heb voor mijn ene applicatie daarvoor 1 datamodule gebruikt. Voor de lookups heb ik ook een aparte datamodule gebruikt. Voor 'grote' formulieren heb ik per form 1 datamodule. Alleen weet die form niet van de datamodule af. Het enige datacomponent op mijn form is TDatasource, om GUI DB componenten te koppelen in het formulier.
    Als die kleine formulieren allemaal de zelfde layout hebben, dan zal je zelfs maar 1 connectie moeten hebben. Dan kan op databaseniveau je query invoeren.
    Delphi is great. Lazarus is more powerfull

  7. #7
    Hallo,

    Ja, .pas bestanden met queries in, het lijkt me ook niet ideaal, dus dat idee is alvast opgeborgen. Ik wist niet dat er MVVM bestond voor Delphi. Ik gebruik het doorheen een andere toepassing (UWP, C#). Ik denk dat e-book te bestellen, ben wel benieuwd.
    Verder zou 1 datamodule voor de kleine datasets inderdaad mss niet slecht zijn.
    Ik vermoed niet dat er een technische limiet is wat de laatste versie van Delphi betreft? Bedoel stel nu dat ik op 100 datamodules en 100 forms eindig, dan vermoed ik dat dat ding wel zal gebuild geraken? En inderdaad, niks in de AutoCreate, met uitzondering van startup form en main data module.

    Bedankt voor de fijne reacties !

  8. #8
    We hebben recent een afgeleide van TDataModule gemaakt die reference counted is, als je 'm als interface gebruikt. Standaard zijn data modules dat niet.
    Door dat te doen kunnen we makkelijk interfaces maken om een bepaalde set data op te vragen. De DI container (van Spring4D) kent deze datamodules. De rest van de applicatie vraagt een instantie op van de interface, roept een method aan om die data op te vragen en/of een bewerking te doen, en zodra de interface uit scope gaat, is de datamodule weer weg.

    Dat maakt het erg eenvoudig om:
    1. de datamodules te designen zoals je dat normaal doet, met datasets, commands e.d. netjes design time gebouwd, met parameters persistent fields en wat je maar wilt.
    2. de applicatie onafhankelijk van de datamodule te bouwen. Met een andere implementatie kan je 'm redelijk eenvoudig inwisselen voor een service call, of iets anders.
    3. en je kan de interface ook makkelijk mocken en zodoende tests bouwen die helemaal niet afhankelijk zijn van de database.
    1+1=b

  9. #9
    De nadelen die je over middleware noemt (fetchen van alles in memory tabellen) is volgens mij iets waar je nog even over na moet denken, of je nu middleware gebruikt of gewoon classic client-server. Je moet per definitie alleen ophalen wat je nodig hebt op dat moment, in plaats van alles op te halen. Dat je bij client server oplossingen in veel gevallen de cursor in de database kunt misbruiken voor dat doel doet daar naar mijn mening niets aan af.

    In de huidige tijden zou ik een nieuwbouw ook nooit doen zonder een degelijke middleware laag. Het maakt het leven veel makkelijker als je klant ineens ook een web interface of mobiele app wil hebben, omdat je tegen dezelfde middleware met je business logica aan kunt praten.

    Wat datamodules betreft, zelf kies ik meestal voor een datamodule per form. Die datamodules maken soms gebruik van andere datamodules, generieke dingen voor een domein verzamel ik zoveel mogelijk bij elkaar op een datamodule.

    Voor de stamtabellen heb ik meestal een enkele datamodule waar alle stamtabellen op staan en die is ook gedurende de levensduur van de applicatie actief. Mijn schermpjes voor die stamtabellen zijn vaak ook generiek en gebruiken die datamodule. Ik gebruik zelf wel middleware (kbmMW) en mijn stamtabellen krijgen van mijn server een seintje als er iets in is gewijzigd. De eerstvolgende keer dat iemand dan die stamtabel gebruikt wordt die eerst ververst.

    Je had het erover dat je voorheen datasnap gebruikte. Dat staat ook bekend om zijn performance problemen en zou je eigenlijk niet moeten vergelijken met middleware zoals die zou moeten zijn.

  10. #10
    Bedankt lieve mensen !! :-)

    Thx voor alle reacties, allemaal goed gelezen.

    Wat de datamodules en/of middleware betreft, heb ik er heel wat tips kunnen uithalen. Nu moet ik helaas nog aan de slag
    Stamtabellen op 1 datamodule, ja dat lijkt me ook wel niet slecht, want die schermen zijn inderdaad generiek.

    Die datasnap beviel me inderdaad ook niet zo wat de performantie betrof. Sinds Delphi 7 heb ik die evolutie niet meer verder gevolgd. Dus ik ben niet meer up to date wat middleware betreft. Als ik misschien nog 1 iets mag vragen? Is er buiten datasnap nu iets in de huidige delphi. Voor de 10 release heb ik RAD server gezien, maar dat is als ik me niet vergis betalend en verder waarschijnlijk niks standaard meegeleverd met Delphi. Sorry als dit een domme vraag is, maar dat deel van Delphi volg ik al vele jaren niet meer.

    Bedankt !!

  11. #11
    Aansluitend bij de vorige post, nog dit vergeten te vermelden. Ik heb reeds een webservice voor de toepassing (met bijlange nog niet alles erin, maar toch al heel wat). Waarschijnlijk kan ik die webserver gebruiken als application server? Maar geen idee hoe dat zou zitten naar scaling toe, als je simultaan met heel wat gebruikers requests stuurt...

  12. #12
    Bij mijn weten alleen RAD Server. Er zijn wel 3th party componenten als alternatief voor DataSnap. Zelf gebruik ik kbmmw naar alle tevredenheid, alleen duurt het wat lang voordat je het onder de knie hebt. Ik hoor ook redelijk goede verhalen over TMS en dan met name dat het wat toegankelijker is dan kbmmw. Persoonlijk ben ik niet zo een TMS fan. Je kunt ook je eigen middleware maken, op zich een leuke uitdaging, maar ik zou daar zelf niet zo snel aan beginnen vanwege de complexiteit.

  13. #13
    Ik heb zelf een JSON parser gemaakt, in combinatie met een indy socket - en heb een api op php, met database. Vind dat zelf een hele lekkere combinatie, omdat ook ik direct een website er op kan draaien - voor vuejs en delphi kan ik dezelfde php endpoint gebruiken. Maar misschien is dat met 50-100 tabellen wat minder "doenbaar"

  14. #14
    Senior Member
    Join Date
    Jul 2008
    Location
    Ertvelde, Belgi?½
    Posts
    158
    Quote Originally Posted by GolezTrol View Post
    We hebben recent een afgeleide van TDataModule gemaakt die reference counted is, als je 'm als interface gebruikt. Standaard zijn data modules dat niet.
    Door dat te doen kunnen we makkelijk interfaces maken om een bepaalde set data op te vragen. De DI container (van Spring4D) kent deze datamodules. De rest van de applicatie vraagt een instantie op van de interface, roept een method aan om die data op te vragen en/of een bewerking te doen, en zodra de interface uit scope gaat, is de datamodule weer weg.

    Dat maakt het erg eenvoudig om:
    1. de datamodules te designen zoals je dat normaal doet, met datasets, commands e.d. netjes design time gebouwd, met parameters persistent fields en wat je maar wilt.
    2. de applicatie onafhankelijk van de datamodule te bouwen. Met een andere implementatie kan je 'm redelijk eenvoudig inwisselen voor een service call, of iets anders.
    3. en je kan de interface ook makkelijk mocken en zodoende tests bouwen die helemaal niet afhankelijk zijn van de database.
    Ik heb eigenlijk voor mijn eigen een gelijkaardig systeem opgezet. Een afgeleide van een Datamodule die reference counted is. Met mijn 'views' heb ik iets gelijkaardigs gedaan maar dan op basis van forms. Dan heb ik ook een aantal wizards ontwikkeld die ik gemakkelijk kan gebruiken om een nieuwe 'entiteit' aan te maken. Heb ik bijvoorbeeld 'Klanten' nodig, dan start ik de wizard ... doorloop ik die ... en eindig ik met een Klanten datamodule, een Klanten list view en een Klanten detail view. Voor orders ... nog eens door de wizard ... Wil ik dan op Klanten ook de Orders van die klanten zien, dan koppel ik op de Klanten datamodule de Orders datamodule als een detail met de KlantID als 'foreign key'. Mijn framework kan er dan voor zorgen dat bij het openen van een Klanten detail scherm automatisch een orders datamodule gemaakt wordt, gefilderd op klant id, de bijhorende Orders List View gemaakt wordt, gekoppeld wordt aan die orders datamodule intantie en dan als detail gedocked wordt in de klanten detail view.

    Klinkt misschien wat complex, maar zorgt voor eenvoudig hergebruik van een aantal zaken, zonder dat ik visueel dus ook de Orders lijst in de Klanten Detail form moet toevoegen. Dat gebeurt 'dynamisch'.

  15. #15
    Bedankt voor alle tips, leuk te weten hoe anderen het aanpakken !

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •