[C#] OO aanpak

Pagina: 1
Acties:

  • Zyphrax
  • Registratie: September 2001
  • Laatst online: 04-04-2023
Ik vroeg mij af wat jullie van de volgende OO-constructie vinden:

Je hebt:
- Entity classes
- Entity Action classes
- Entity Data classes

Entity class
Kale klasse die alleen variabelen en properties bevat. Heeft maar 1 constructor die puur de variabelen initialiseert.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Auto {
   private Int32 _ID;
   private String _brand;

   public Auto {
      _ID = Int32.MinValue;
      _brand = String.Empty;
   }

   public string ID {
      get {return _ID;}
      set {_ID = value;}
   }

   public string Brand {
      get {return _brand;}
      set {_brand = value;}
   }
}


Entity Action class
Klasse die alle bewerkingen van een entiteit heeft.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class AutoAction {
   public Auto Create() {
      return new Auto();
   }

   public Auto FindByID(int id) {
      AutoData autoData = new AutoData();
      Auto result = autoData.SelectByID(id);
      autoData.Dispose();
      return autoData;
   }

   public void Save(Auto auto) {
      AutoData autoData = new AutoData();
      autoData.Save(auto);
      autoData.Dispose();
   }

   ...
}


Entity Data class
Klasse die alle database bewerkingen regelt
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class AutoData {
   public Auto SelectByID(int id) {
      ...
      AutoAction autoAction = new AutoAction();
      Auto result = autoAction.Create();
      result.ID = Convert.ToInt32(DataReader["ID"]);
      result.Brand = Convert.ToString(DataReader["Brand"]);
      autoAction.Dispose();
      ...
   }

   public void Save(Auto auto) {
      ...
   }

   ...
}



Mijn vraag
Deze aanpak heb ik niet zelf bedacht en ben het op een aantal punten er niet mee eens. Ik wil jullie vragen wat jullie van deze aanpak vinden. Zou je het zelf zo doen?

Any sufficiently advanced technology is equivalent to magic.


Verwijderd

Ben het in z'n geheel niet eens met deze aanpak om de volgende redenen:
- De action class kan niet bij de private members van de entity class.
- De data class leunt te sterk op de action class terwijl die m.i. een afgeleide van de entity class zou moeten zijn.

Je kunt m.i. beter de action class en de entity class samen laten gaan en de private members welke toegankelijk moeten zijn voor de data class protected maken en de data class afleiden van de entity class.

De door TS geschetste opzet is volgens mij geen goed voorbeeld van OO.

  • Zyphrax
  • Registratie: September 2001
  • Laatst online: 04-04-2023
Wat ik zelf ook heel raar vind zijn de instanties. Afgezien van de (naar mijn idee rare scheiding van Entity en Entity Action), je zou de Action en de Data klasses in deze situatie puur uit statische methoden kunnen laten bestaan, instanties hebben hier geen nut.

[ Voor 11% gewijzigd door Zyphrax op 03-11-2004 17:03 ]

Any sufficiently advanced technology is equivalent to magic.


  • Korben
  • Registratie: Januari 2001
  • Laatst online: 14-11-2025

Korben

() => {};

Verwijderd schreef op 03 november 2004 @ 16:56:
Ben het in z'n geheel niet eens met deze aanpak om de volgende redenen:
- De action class kan niet bij de private members van de entity class.
- De data class leunt te sterk op de action class terwijl die m.i. een afgeleide van de entity class zou moeten zijn.

Je kunt m.i. beter de action class en de entity class samen laten gaan en de private members welke toegankelijk moeten zijn voor de data class protected maken en de data class afleiden van de entity class.

De door TS geschetste opzet is volgens mij geen goed voorbeeld van OO.
Ik ben het met je eens dat het geen goed voorbeeld van OO is, maar ik ben van mening dat alle bewerkingen in de entity class zelf moeten. Jouw aanpak zou eventueel kunnen als er meerdere manieren zijn om die entities op te halen en weg te schrijven, maar zelfs in dat geval zou ik aparte klassen maken die daar over gaan.

.oisyn: Échte programmeurs haten PHP met een passie. Ben jij soms geen echte programmeur?


  • MaxxRide
  • Registratie: April 2000
  • Laatst online: 09-01 10:13

MaxxRide

Surf's up

Ik ben het eigenlijk wel met hvdberg eens. Ik zou eerder een afleiding voor de dataclass maken van de entity class (die overigens dus wel over zijn eigen "velden" beschikt en niet via een property class werkt). Op deze manier kun je makkelijk uitbreiding maken om b.v. geimporteerde classes uit XML te lezen en uit een DB zonder dat je hiervoor een hele niet action class hoeft te schrijven.


Door het gebruik van de aparte property class maak je ook nog eens onodige overhead terwijl dit altijd een 1 op 1 relatie met de action class geeft (voor een bepaalde instantie) -> in dat geval samennemen die hap. In principe kunnen de attributen dan best private zijn met wat getters en setters erbij.

If you are not wiping out you are nog pushing enough...


  • D4Skunk
  • Registratie: Juni 2003
  • Laatst online: 20-10-2025

D4Skunk

Kind of Blue

Ik veronderstel dat iemand je verplicht heeft deze aanpak te volgen....
Vanuit OO-standpunt wordt dit meestal niet als correct beschouwd; ik denk dat deze opspliting eerder gebeurd is om het overzichtelijk te houden.
Stel die persoon eens '#region' voor, en de opsplitsing v/d datalager in een aparte class. Dit is een aanpak die in veel situaties gebruikt wordt, en relatief goed blijkt te zijn...

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// class die alle instructies bevat die nix met de db te maken hebben
class Abc {
  #region Properties
     #region Vars
     int id;
     string name;
     #endregion

     #region Getters & setters
     int Id {
        Get { return id; }
        Set {id =value; }
     }
     string Name {
        Get { return name; }
        Set {name =value; }
     }
  #endregion

  #region Actions
  ....
  #endregion
}

// datamanager class ( singleton of  static) 
class DmAbc:DataManager {
...
}

  • Zyphrax
  • Registratie: September 2001
  • Laatst online: 04-04-2023
Idd dit is een aanpak die mij gevraagd wordt te volgen.
Ik vind het zelf alleen zo omslachtig.

Daarnaast vind ik het ook heel kwalijk bijvoorbeeld dat een ID (van een Entity class) ge-set kan worden via een Property (dit is in hier natuurlijk nodig, omdat de Entity gescheiden is van de Action klasse).

Technieken als statische methoden en constructors worden met deze techniek naar mijn idee ook aardig verwaarloosd.

Wat is bij C# doorgaans een goede OO-structuur, ook in verband met de DataSets die over alle lagen zo'n beetje heen springen?

Any sufficiently advanced technology is equivalent to magic.


  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

het business-object model?? (als dit toch is wat ik bedoel :) )

nl. je hebt de klasse auto, met al haar properties en memberss etc...
en je hebt een klasse die de auto's 'beheert'

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Auto
{
   private kleur k;
   private merk m;
   private int ID;
   
   //gettters en setters hier

   public void Save();
   ...
}

class AutoManager
{
    Auto FindAutoByID(int id);
    Auto CreateNew();
    ...
}


maw. de klasse Auto doet alles zelf wanneer hij gecreerd is
en de manager staat in voor het creeren en opvragen etc van Auto's

(dit is toch de methode die ik over het algemeen implementeer waar mogelijk
en het zou wel eens kunnen zijn dat'k hier een foutje maak)

[ Voor 17% gewijzigd door H!GHGuY op 04-11-2004 11:14 ]

ASSUME makes an ASS out of U and ME


  • Zyphrax
  • Registratie: September 2001
  • Laatst online: 04-04-2023
Maar dan heb je nog steeds de situatie dat je of ID van buiten moet zetten of Auto heeft een constructor waaraan je een ID mee mag geven :/

En naar mijn idee horen in verband met Data Integriteit IDs nooit van buiten een klasse ingesteld te worden. Als je Entiteit en Action klasse hier bijvoorbeeld samenneemt kan je werken met een Private constructor waarmee je het ID mag setten.

[ Voor 47% gewijzigd door Zyphrax op 04-11-2004 11:22 ]

Any sufficiently advanced technology is equivalent to magic.


  • whoami
  • Registratie: December 2000
  • Laatst online: 23:33
HIGHGuy: als je Save method in de Auto class zit, zit je dan niet met SQL (Data Access) code verspreid tussen 2 classes / lagen ?

https://fgheysels.github.io/


  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

Zyphrax schreef op 04 november 2004 @ 11:17:
Maar dan heb je nog steeds de situatie dat je of ID van buiten moet zetten of Auto heeft een constructor waaraan je een ID mee mag geven :/

En naar mijn idee horen in verband met Data Integriteit IDs nooit van buiten een klasse ingesteld te worden. Als je Entiteit en Action klasse hier bijvoorbeeld samenneemt kan je werken met een Private constructor waarmee je het ID mag setten.
het is de Manager die, wanneer mogelijk de ID zet dmv de constructor. zo weet je altijd dat er nergens een foute ID KAN meegegeven worden.
whoami schreef op 04 november 2004 @ 11:26:
HIGHGuy: als je Save method in de Auto class zit, zit je dan niet met SQL (Data Access) code verspreid tussen 2 classes / lagen ?
je hebt idd in beide klassen SQL code, maar als je een datalaag gebruikt, heb je niet meer nodig als een dynamishce query (in de vorm van een private const string)
waarmee je dan de juiste parameters gebruikt. en die 'doorgeeft' aan je datalaag.

ASSUME makes an ASS out of U and ME


  • Zyphrax
  • Registratie: September 2001
  • Laatst online: 04-04-2023
1. Wat is precies de best practice met DataSets/DataTables ivm lagenmodel?

Zou je Domein klasse dan eigenlijk een DataTable/DataRow moeten bijhouden in plaats van allemaal variabelen of moet er telkens conversie plaatsvinden van Objecten naar DataTables/Rows en omgekeerd?

2. Wat is de juiste manier van communicatie tussen de Domein en Data laag?

Uitwisselen van een klasse met variabelen/DataTable/DataRow/Object[]/ArrayList?

3. Methoden als FindByID van een Domein klasse, kunnen toch prima static zijn?

Auto a = Auto.FindByID(8);


Thnx voor de hulp

[ Voor 39% gewijzigd door Zyphrax op 04-11-2004 11:48 ]

Any sufficiently advanced technology is equivalent to magic.


  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

Zyphrax schreef op 04 november 2004 @ 11:44:
1. Wat is precies de best practice met DataSets/DataTables ivm lagenmodel?

Zou je Domein klasse dan eigenlijk een DataTable/DataRow moeten bijhouden in plaats van allemaal variabelen of moet er telkens conversie plaatsvinden van Objecten naar DataTables/Rows en omgekeerd?

2. Wat is de juiste manier van communicatie tussen de Domein en Data laag?

Uitwisselen van een klasse met variabelen/DataTable/DataRow/Object[]/ArrayList?

3. Methoden als FindByID van een Domein klasse, kunnen toch prima static zijn?

Auto a = Auto.FindByID(8);
1.
ik denk dat een stuk van je design afhangt op hoe de structuur van je programma is. bvb
server <-> 1 client
server <-> meerdere clients tegelijkertijd
client alleen
2. is een datalaag niet enkel en alleen om de specifieke eigenschappen van verschillende DB-systemen te verbergen? (zodat je ze altijd kan wijzigen) maw: is het niet de bedoeling dat je datalaag enkel database operaties kan verwerken?
3. goeie vraag :P

ASSUME makes an ASS out of U and ME


  • whoami
  • Registratie: December 2000
  • Laatst online: 23:33
Om data tussen lagen te versluizen kan je gebruik maken van DataSets of custom (serializable) objects.

https://fgheysels.github.io/


  • MrHighStone
  • Registratie: November 2001
  • Laatst online: 03-02-2023
Ten eerste ben ik van mening dat (OO) technisch elke mogelijk oplossing te realiseren, maar vaak is het afhankelijk van allerlei wensen (specs).

Een oplossing die goed werkt in een pure data retrieval/update applicatie is gebruik maken van Typed Datasets, welke dmv statische "DataAccessServices" worden geinstantieerd en weggeschreven (alle CRUD functies zeg maar).
Een voorbeeld is het gebruik van een OrderTDS en OrderListTDS, welke mbv statische methods in een OrderServices class gemanipuleerd kunnen worden.
Deze oplossing is eenvoudig te implementeren, zeker in combinatie met het DAAB en UIPAB block van Microsoft.

Een andere oplossing die het goed doet in meer OO omgevingen, en waar complexe business logica (die je typisch eenmalig in de bijbehorende klasse wilt onderbrengen) een rol speelt, is gebruik maken van (bv) een OO framework. Kijk eens naar het CSLA framework van Rockford Lhotka bijvoorbeeld. Dit in combinatie met de eerder genoemde application blocks van Microsoft.

Waar het gaat om OO oplossingen heb ik gemerkt dat hierover verschillende theorien/oplossingsrichtingen zijn. Kijk wat de eisen zijn, kijk naar de beschikbare ontwikkeltijd (in het begin langer bij OO, later aanzienlijk korter), en kijk naar de mogelijke OO paradigma's en patterns (zoals die bijvoorbeeld ook door Rational worden gepredikt).

Een file op de A12 is nooit grappig...


  • whoami
  • Registratie: December 2000
  • Laatst online: 23:33
Het CSLA.NET framework van Rockford is mooi opgezet, maar komt imo een beetje tekort als je meerdere verschillende databases wilt ondersteunen, tenzij je altijd gebrukt maakt van Stored Procedures en je de stored procedures een zelfde naam geeft.

https://fgheysels.github.io/


  • MrHighStone
  • Registratie: November 2001
  • Laatst online: 03-02-2023
Inderdaad, maar dat geldt volgens mij voor elke implementatie :?

En op het moment dat een bepaalde app meerde databases moet ondersteunen hebben volgens mij ook heel andere problemen dan enkel andere sprocs...

Een file op de A12 is nooit grappig...


  • whoami
  • Registratie: December 2000
  • Laatst online: 23:33
MrHighStone schreef op 04 november 2004 @ 20:46:
Inderdaad, maar dat geldt volgens mij voor elke implementatie :?

En op het moment dat een bepaalde app meerde databases moet ondersteunen hebben volgens mij ook heel andere problemen dan enkel andere sprocs...
Ik bedoelde er meer op dat je DAL eigenlijk in je BL objecten vervat zit.

Als je meerdere databases ondersteunt, dan moet je idd meerdere DAL gaan schrijven, maar dat is het probleem niet.
Het feit is dat je, als dat gebeurt, je in CSLA stored procedures moet gebruiken, en dat is niet altijd haalbaar. (maar we wijken eigenlijk af van het onderwerp).

Eigenlijk ben ik ook nog altijd best geinteresseerd in hoe andere mensen n-tier projecten aanpakken. En dat geldt ook voor distributed projecten. (Zie ook dit topic van mij: [rml][ Alg/.NET] n-tier ontwikkeling / data transfer objects[/rml] )

[ Voor 19% gewijzigd door whoami op 04-11-2004 20:56 ]

https://fgheysels.github.io/


  • whoami
  • Registratie: December 2000
  • Laatst online: 23:33
Zyphrax schreef op 04 november 2004 @ 11:17:
Maar dan heb je nog steeds de situatie dat je of ID van buiten moet zetten of Auto heeft een constructor waaraan je een ID mee mag geven :/

En naar mijn idee horen in verband met Data Integriteit IDs nooit van buiten een klasse ingesteld te worden. Als je Entiteit en Action klasse hier bijvoorbeeld samenneemt kan je werken met een Private constructor waarmee je het ID mag setten.
Evil trick:
Je kan de constructors van Auto private maken, en in de 'manager' class kan je dat object alsnog creeëren via reflection. Daarmee kan je die private constructors toch aanroepen.

https://fgheysels.github.io/


  • Zyphrax
  • Registratie: September 2001
  • Laatst online: 04-04-2023
Is er een website waar deze methodieken (zoals die van Rockford Lhotka) tegenover elkaar getoetst worden en de voor- en nadelen besproken worden?

Ik heb wat pagina's bij MSDN gezien over patterns, helaas blijven ze daar in sommige stukken heel oppervlakkig.


@Whoami:
Is die manier geen verkrachting van een principe?
If someting was meant to be private, it shouldn't be private whenever we like it to be, but always. Je kan dan naar misschien nog beter naar een protected/internal constructie gaan. Al met al, niet erg fraai.

[ Voor 45% gewijzigd door Zyphrax op 04-11-2004 23:32 ]

Any sufficiently advanced technology is equivalent to magic.


  • Orphix
  • Registratie: Februari 2000
  • Niet online
Zyphrax schreef op 04 november 2004 @ 23:29:
@Whoami:
Is die manier geen verkrachting van een principe?
If someting was meant to be private, it shouldn't be private whenever we like it to be, but always. Je kan dan naar misschien nog beter naar een protected/internal constructie gaan. Al met al, niet erg fraai.
Dit klopt wel. Het is wel een truukje. Echter kan je het ook enigszins relativeren. De methode die whoami noemt wordt ook gebruikt door Rockford. Het probleem zit hem in het feit dat zowel de data layer als de UI layer gebruik maken van hetzelfde business object.
Je wilt aan vooral de UI kant een interface presenteren die voor hen bedoeld is, dus geen toegang tot data-retrieval methodes en constructoren. De UI laag hoeft enkel acties uit te voeren op een bestaand business object. De data laag daarentegen moet gewoon de mogelijkheid hebben om dat businessobjet aan te maken, en te vullen met data.

Het is altijd een heikel punt geweest hoe de datalayer samenwerkt met de businesslayer, en Rockford heeft dit in C# opgelost dmv reflectie, die bepaald encapsulatie regels overtreed. Het is duidelijk dat dit in lang niet alle talen mogelijk is.

Een voordeel van deze methode is wel dat alle informatie: data members, operation methodes en data persistence, opgeslagen is op een enkele plek; namelijk in de business class. Daarnaast is de datalayer zo gemaakt dat deze slechts één keer, door de framework maker, hoeft te worden gedefinieerd. Het is daarom denk ik belangrijker om encapsulation toe te passen op de interface waarvan een UI developer of een business object developer gebruikt maakt, dan de interface naar de data layer.

  • whoami
  • Registratie: December 2000
  • Laatst online: 23:33
Zyphrax schreef op 04 november 2004 @ 23:29:
@Whoami:
Is die manier geen verkrachting van een principe?
If someting was meant to be private, it shouldn't be private whenever we like it to be, but always. Je kan dan naar misschien nog beter naar een protected/internal constructie gaan. Al met al, niet erg fraai.
Een protected of internal method laat niet toe dat je een object creeërt als de 'Manager' in een andere assembly zit.

Is het een verkrachting? Maybe. Echter, als je die klasses zelf geschreven hebt, vind ik het niet zo erg. Ik zou het zelf ook nooit doen om objecten van classes te instantiaten die door 3rd parties geschreven zijn. (En wat Orphix zegt).

[ Voor 3% gewijzigd door whoami op 05-11-2004 08:38 ]

https://fgheysels.github.io/


  • MrHighStone
  • Registratie: November 2001
  • Laatst online: 03-02-2023
Even schoppen tegen de gevestigde OO orde :O

Bedenk dat er verschillende OO methodieken/patterns zijn om dergelijke problemen op te lossen, in THEORIE.
In de PRAKTIJK betekent dit dat je hierme pragmatisch mee om moet gaan, en hebben praktische oplossingen soms prioriteit boven theoretische concepten...

Ook zo'n leuke in onze developperswereld is het normaliseren van een database...

Een file op de A12 is nooit grappig...


  • MrHighStone
  • Registratie: November 2001
  • Laatst online: 03-02-2023
Wat me net te binnen schoot, onlangs kwam ik deze link tegen http://www.adoguy.com/content.aspx?id=SampleChapter/Chapter7

Wellicht dat je daar iets mee kan, als het gaat om eenvoudige datamaintenance projecten, waarbij de objecten niet binnen een brede omgeving herbruikbaar hoeven te zijn.

Een file op de A12 is nooit grappig...


  • whoami
  • Registratie: December 2000
  • Laatst online: 23:33
*kick* :P
Gewoon dit topic nog ff onder de aandacht brengen. :Y)

https://fgheysels.github.io/

Pagina: 1