[Delphi] Algemene methode data controle

Pagina: 1
Acties:

  • FendtVario
  • Registratie: Januari 2002
  • Laatst online: 12-05-2025

FendtVario

The leader drives Vario!

Topicstarter
Voor een bestaande applicatie ben ik op zoek naar een eenduidige methode om controles uit te voeren op gegevens die naar een database geschreven worden, nu is de controle gefragmenteerd. Laat ik het probleem iets nader uitleggen.

De applicatie waar het om gaat biedt een aantal functionaliteiten. Nu komt het voor dat eenzelfde functionaliteit op meerdere plaatsen voor, wat op zich nog niet zo erg is, maar het is ook nog eens allemaal apart geprogrammeerd. De meeste onderdelen hebben ook nog eens allemaal een eigen datamodule (dus er meerdere dataset voor dezelfde gegevens). In alle vensters wordt invoer gecontroleerd, maar die controle verschilt wel eens voor dezelfde functionaliteit. Het kan dus voorkomen dat eenzelfde invoer op een plek niet geaccepteerd wordt en op de andere wel :X.

De applicatie, en bijbehorende modules, omschrijven gaat nu niet meer. Ik ben dus op zoek naar een manier om de schade te beperken en ook een oplossing die voor toekomstige projecten misschien gebruikt kan worden.

Naast Delphi werk ik ook graag met Java en de opzet van de DAO bevalt me wel. Alles via een object dat verantwoordelijk is voor de controle van de gegevens. Wat ik nu wil doen is een laag over een TDataSet heen leggen die de een interface biedt om nieuwe records aan te maken, te verwijderen en ook de verantwoordelijkheid heeft over de controle op de tabel. Ongeveer zo:

Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
type
  TRelationAgent = object(TObject)
  public
    constructor Create(ADataSet: TDataSet);
    function CreateRecord: Boolean;
    function DeleteRecord: Boolean;
    function Save(var Messages: TStrings): Boolean;
    function Validate(var Messages: TStrings): Boolean;
    { er mogen nog meer functies/procedures komen }
  end;

implementation
{ vervolg unit }


Bij de creatie wordt de dataset meegegeven waarover de Agent moet waken, de constructor nestelt zich ook in de BeforePost, AfterInsert etc event om ook de acties op te vangen die door de oude code nog niet door de Agent verlopen.

Mijn idee is door voor alle onderdelen zulke Agents te maken we nu nog kunnen ingrijpen, in de toekomst moet er een betere opzet komen voor onderdelen die op verschillende plaatsen in het programma terug komen (bijv TFrames). De agent zie ik nu als iets om de schade in oude onderdelen beperkt te houden.

Wat vinden jullie van de Agent om die alsnog een eenduidige controle te maken voor alle onderdelen, en hoe bouwen jullie met Delphi een applicatie waarin je de controle via een object laat verlopen?

www.fendt.com | Nikon D7100 | PS5


Verwijderd

Ehmm...
"TRelationAgent = object(TObject)" moet gewoon "TRelationAgent = class" zijn.
En CreateRecord zou ik niet public maken, de Save method kan prima zelf bepalen of 't een insert of een update, door eerst te checken of de primary key in je dataset is ingevuld en al bestaat. (Heeft iets overhead omdat je eerst een select op de primary key moet doen, maar vooral in een multi-user omgeving is dat een stuk safer).

Voor een nieuwe applicatie is die Agent aanpak prima te gebruiken, maar voor een bestaande applicatie met een hoop datasets die dan ook nog 's design time zijn aangemaakt (dat maak ik op uit je verhaal) betekent 't een hoop code aanpassen...
Bij een bestaande applicatie zou ik gewoon TRelationAgent laten inheriten van TDataSet, en dan de DoBeforePost method overriden en daar die Validate method implementeren.
Is nog steeds een hoop werk, maar sneller voor elkaar te krijgen dan jouw agent idee.

[ Voor 3% gewijzigd door Verwijderd op 07-01-2005 00:39 ]


Verwijderd

hoe bouwen jullie met Delphi een applicatie waarin je de controle via een object laat verlopen?
Een base class die een 100% representatie van 't record is, met een DBHelper (vergelijkbaar met jouw Agent idee, maar dan andersom) die de select, insert, update en delete queries samen kan stellen. Natuurlijk met een progje om de tabelstructuur om te zetten naar een Delphi class, en wanneer er validaties, etc. moeten worden toegevoegd is 't simpel om daar een inherited class voor in het leven te roepen.

Bij Delphi 7 / 8 / 2005 zijn dit soort dingen al meer gemeengoed, maar de basis van ons systeem stamt uit het Delphi 2 tijdperk. :)

  • FendtVario
  • Registratie: Januari 2002
  • Laatst online: 12-05-2025

FendtVario

The leader drives Vario!

Topicstarter
Voor een nieuwe applicatie is die Agent aanpak prima te gebruiken, maar voor een bestaande applicatie met een hoop datasets die dan ook nog 's design time zijn aangemaakt (dat maak ik op uit je verhaal) betekent 't een hoop code aanpassen...
Je zet toch meestal design-time de benodigde datasets op een datamodule :? De Agent is zoals die nu is, is run-time, maar direct laten overerven van TDataSet is denk ik lastig want de tabel componeten gebruiken dan toch nog steeds niet de TAgentDataset?
Een base class die een 100% representatie van 't record is,
Hoe ga je dan om met data-aware fields, die kun je alleen koppelen aan TDataSet descendants.

www.fendt.com | Nikon D7100 | PS5


Verwijderd

TTable gebruik ik sowieso al niet. Bij een SQL database (en dus geen Paradox of dBase) kun je eigenlijk alleen maar bij de inhoud van een tabel middels queries (Delphi's TTable doet dat 'onder de kap' ook zo), dus waarom die omweg gebruiken? Volgens mij heeft dat alleen zin als je applicatie zowel SQL- als file based databases moet kunnen ondersteunen...

Overigens is het met GExperts heel simpel om de class van componenten op een form/datamodule te vervangen door een andere class. Gratis, en een heel uitgebreide toolkit voor de IDE. Ik zou 'm niet meer willen missen! (vooral Grep search is ontzettend handig) :)
Maar je hebt wel gelijk: een TDataset afgeleide heeft niet automatisch alle fucties van een TTable of een TQuery. Je zult 't dan 2x moeten implementeren (TAgentTable, afgeleid van TTable, en TAgentQuery, afgeleid van TQuery). Of je maakt er een interface van, als je beschikt over de source van DB en DBTables, kijk dan maar 's naar hoe ze dat bij Delphi hebben gedaan voor de IProviderSupport interface.
Maar dan nog zul je 't 2x moeten implementeren...
Hier heb ikzelf geen last van, omdat ik toch alleen maar queries gebruik.

En data aware controls gebruik ik ook al niet, behalve soms een DBGrid, maar dan alleen read only. De koppeling tussen de edit controls en de fields in die base class worden door die base class zelf afgehandeld, en z'n DBHelper zorgt ervoor dat de database wordt bijgehouden.

  • FendtVario
  • Registratie: Januari 2002
  • Laatst online: 12-05-2025

FendtVario

The leader drives Vario!

Topicstarter
TTable gebruik ik ook al een tijde niet meer. Databases die ik voornamelijk gebruik zijn MySQL en Interbase. Voor MySQL zijn er de dbExpress componenten of de Zeos componenten (werkt wel lekker snel, maar heb er al verschillende bugs uitgehaald). Eigenlijk vindt ik de data-aware componenten wel makkelijk, als je de dataset goed instelt (DisplayFormat, EditFormat etc) kan het je een hoop werk schelen.

Descendants maken van de uiteindelijke componenten zoals TIBTable (etc) heb ik al eens geprobleerd. Mijn ervaring is dat de overerving dan op een te hoog niveau begint en daardoor meer problemen oplevert dan oplost. Met name de events gaven problemen.

www.fendt.com | Nikon D7100 | PS5

Pagina: 1