[OO] welke van deze methodes is de beste OO techniek

Pagina: 1
Acties:

  • tyball
  • Registratie: December 2000
  • Laatst online: 31-07 14:32
Om bv een vierkant te tekenen in een window kan je dit op 3 manieren doen. Welke van deze
manieren verdient de voorkeur in de OO wereld en waarom?
ter voorbeeld 4 klassen:

klasse: Vierkant
klasse: Window
Klasse: MijnWindows extends Window
klasse: TekenKlasse

De manieren:

VierKant.teken(Window w)

of

MijnWindow.teken(VierKant : v)

of

TekenObject.teken(Window w, VierKant v)

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Persoonlijk vind het ik handig om objecten aan te maken waar je ook in loopt te denken. In dit geval ben je bezig met een vierkant en dan zou ik ook een object aanmaken vierkant. Nog beter is om een object figuur aan te maken en vierkant daarvan te laten extenden. Figuur geeft je dan een abstracte paint methode, en die implementeer je bij alle extendende classes (vierkant in dit geval).

Je kan nu ook weer een compositie maken uit meerdere figuren, en deze weer aanspreken als een figuur. Een dambord is bv niets anders dan een groot aantal vierkanten, dus als je dambord extends figuur laat doen, en je implementeerd hier de paint methode ook bij, dan kan je net zulke complexe figuren maken als je wilt.

Maar ik heb hier eigelijk te weinig info om te zeggen dat dit 'het' ontwerp is.

[ Voor 29% gewijzigd door Alarmnummer op 20-11-2003 11:20 ]


  • whoami
  • Registratie: December 2000
  • Laatst online: 11:10
Wat is een Window?

Wordt een vierkant getekend op een window?

https://fgheysels.github.io/


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 20-08 00:10
De logica om een figuur te tekenen hoort bij de figuur, lijkt me, en dan is de juiste oplossing om een methode toe te voegen aan de klasse die de figuur representeert.

Als je een teken-methode toevoegt aan een window-klasse dan betekent dat dat je geen figuren kunt toevoegen zonder ook de window-klasse aan te passen. Dat lijkt me niet de bedoeling.

Een aparte teken-klasse heeft een beetje hetzelfde probleem en voegt mijns inziens niet zoveel toe (je moet het object nog steeds koppelen aan een window- en figuur-object).

  • whoami
  • Registratie: December 2000
  • Laatst online: 11:10
Ik ben het met Soultaker eens.
De Teken logica hoort bij de figuur. Daarnaast kan je ervoor zorgen dat alle figuren (driehoeken, vierkanten, cirkels, etc...) een zelfde interface hebben (zie Alarmnummer). Het object waar je die figuur dan op tekent kan je meegeven aan de 'Teken' method.

https://fgheysels.github.io/


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 16-08 21:36
Tekenobject/TekenKlasse is typerend voor Java, waar je bij gebrek aan functies methods moet maken op onzinnige objecten. In C++ zou je zoiets als free function schrijven.

Wat je ziet is een behoefte aan multi-methods, zoals ze wel heten. Je functie is nu polymorph langs twee inheritance trees; Figuur (concreet:Vierkant) en Window (concreet:MijnWindow). Omdat dit praktische bezwaren met zich meebrengt (kwadratische groei in het aantal benodigde functies) is het handig om een concrete drawingbuffer te introduceren oid. Elk figure kan dan op deze buffer tekenen; elke window class kan deze drawingbuffer laten zien.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • McFreak
  • Registratie: December 2000
  • Laatst online: 27-04 21:09

McFreak

McFraGG de gekste !!

MSalters heeft wel gelijk, maar dan hangt het er wel weer vanaf wat voor prog je gaat bouwen.
Als het toch wel 'een uit de kluten gewassen' proggie is zou ik MSalters methode zeker gebruiken.

Anders zou ik het object zichzelf laten tekenen.
Ik verplaats me dan gewoon in het object zelf.
Als ik een fietswiel ben dan draai ik bv

[edit]
En abstracte klassen moet je gewoon alleen gebruiken wanneer je properties van afgeleide klassen verandert en veel instanties van maakt.
Anders vrij nutteloos en implementatieoverhead

[ Voor 25% gewijzigd door McFreak op 20-11-2003 12:28 ]

McFraGG de gekste !!


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

MSalters schreef op 20 november 2003 @ 12:18:
Tekenobject/TekenKlasse is typerend voor Java, waar je bij gebrek aan functies methods moet maken op onzinnige objecten. In C++ zou je zoiets als free function schrijven.
Ik vind het eerlijk gezegd niet zo`n probleem dat je binnen een object statische methodes gaat plaatsen. Je hebt al de functionaliteit dan gegroepeerd binnen 1 object. (Kijk maar eens naar Collections )

Verder kan je met de nieuwe import functionaliteit uit jdk1.5 ook statische methodes importeren, dus ipv Math.max(int,int) kan je zeggen max(int,int), waardoor de syntax een stuk fijner is.
Wat je ziet is een behoefte aan multi-methods, zoals ze wel heten. Je functie is nu polymorph langs twee inheritance trees; Figuur (concreet:Vierkant) en Window (concreet:MijnWindow).
Waarom zou je ook een class hierarchie moeten maken voor die window??

[ Voor 21% gewijzigd door Alarmnummer op 20-11-2003 12:36 ]


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

RaR schreef op 20 november 2003 @ 12:26:
En abstracte klassen moet je gewoon alleen gebruiken wanneer je properties van afgeleide klassen verandert en veel instanties van maakt.
Anders vrij nutteloos en implementatieoverhead
Je zou het eventueel ook kunnen gebruiken om een goed ontwerp neer te zetten. Als ik objecten heb die een belangrijke rol spelen binnen een api, dan stel ik hiervoor altijdj een interface op waarmee ik het contract opstel waar het object zich aan moet houden. En daarnaast kan ik mbv deze interface ook allerlei oo grappen erop los laten. Voor objecten waarvan ik weet dat ze beter in een class hierarchie kunnen, zal ik dit ook zeker niet laten.

Ik vind jouw argumentatie om abstracte classes te gebruiken niet goed.

[ Voor 9% gewijzigd door Alarmnummer op 20-11-2003 12:36 ]


Verwijderd

abstracte classe zijn best handig.... bijvoorbeeld voor je BO's even voorbeeldje....

abstract public class UseCaseBaseBO

public class UseCaseZoekDataBO extends BaseBO

nou ik ga echt nooit een instance maken van UseCaseBaseBO toch is deze classe belangrijk omdat ie een aantal methodes defined die belangrijk zijn voor alle UseCase classes.....

je kan dan wel zeggen waarom laat je abstract gewoon niet weg.... heeft dezelfde functionaliteit... het enige verschil is wanneer iemand dan toch een instance probeert te maken van deze abstracte classe zegt de compiler even dat ie dat niet mag... dit is handig en waarom?

omdat die classe niet is gemaakt om direct aan te spreken, met als gevolg dat de functionaliteit daar niet op berekend is... waardoor er vreemde dingen kunnen gebeuren.... ga dat maar eens debuggen... nou en als ik moet kiezen tussen dat debuggen en een abstracte classe defineren.... dan is de keuze gemakelijk gemaakt voor mij!

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

kick *hoopt nog op replies*

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 00:47
Wat je dan ook nog tegenkomt is, wat als ik hetzelfde figuur wil tekenen op iets anders dan een window.
Moet je dan een functie bij in je klasse gooien die de specifieke tekeninstructies voor dat andere object kent ?

In dit boek http://www.amazon.com/exe...-0854644-1982354?v=glance ( dat Alarmnummer me heeft aangeraden ) wordt gebruik gemaakt van een Bridge pattern om dit op te lossen.

In jouw concrete geval betekent dit dat je een Drawing object hebt, waarop je shapes zich kunnen tekenen. ( Shapes kunnen dus _alleen_ tekenen op een Drawing object )

Afhankelijk van het type Drawing ( Windowdrawing, PrinterDrawing, BlaatDrawing etc ) worden de instructies vertaald naar de specifieke instructies die dat 'device' nodig heeft.

Ik vind em erg mooi. :)

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • whoami
  • Registratie: December 2000
  • Laatst online: 11:10
Hmmm, 't ziet er een goed boek uit.
* whoami add's it to wish-list. :P

Dat 'Drawing' object is dan eigenlijk te vergelijken met de 'Device Context' oid in MFC ?

Daarnaast vraag ik me ook af waarom Alarmnummer zo consequent tegen abstract classes heeft? Interfaces zijn misschien wel beter vanuit het oogpunt van pure OO, maar je kan er toch niet vanuit dat abstract classes best wel handig zijn in sommige gevallen.
Soms moet je eens het puristische van je af laten vallen, en kiezen voor een meer pragmatische aanpak.
Denk pragmatisch, waarmee haal je het hoogste rendement

Let op: daarmee zeg ik niet dat er in dit geval abstracte classes moeten gebruikt worden, en geen interfaces.


Alhoewel, nu ik er aan denk: een van de doelstellingen van OO is om het hergebruik van code te bevorderen. Abstract classes zorgen ervoor dat je code kunt re-usen, dus zijn abstract classes wel degelijk pure OO.

[ Voor 13% gewijzigd door whoami op 21-11-2003 09:57 ]

https://fgheysels.github.io/


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

whoami schreef op 21 november 2003 @ 09:56:
Hmmm, 't ziet er een goed boek uit.
* whoami add's it to wish-list. :P
Het boek is erg interessant om te lezen, maar er worden geen andere patterns in behandeld dan het GoF boek. Ik vind het persoonlijk een stuk prettiger om te lezen als introductie op designpatterns dan het gof boek.
Daarnaast vraag ik me ook af waarom Alarmnummer zo consequent tegen abstract classes is? Interfaces zijn misschien wel beter vanuit het oogpunt van pure OO, maar je kan er toch niet vanuit dat abstract classes best wel handig zijn in sommige gevallen.
Als ik een gemeenschappelijk contract nodig hebt voor meerdere classes, maak ik hiervoor een interface. In deze interface staat exact beschreven wat het kan en waar het zich aan moet houden. Dus alleen al voor documentatie vind ik een interface al een stuk fijner dan een abstracte class. Verder kan je veel meer oo grappen op interfaces loslaten dan op abstracte classes (onnodige beperkingen).
Soms moet je eens het puristische van je af laten vallen, en kiezen voor een meer pragmatische aanpak.
Dit is geen kwestie van puristisch, maar van gemak. Ik ben een luie programmeur en ik doe graag extra werk om het mezelf makkelijker te maken ;) Als ik ook overeenkomstige methodes/data kan gebruiken voor die classes, dan maak ik ook een abstracte class die die interface implementeerd, en dan hoeven mijn eind classes alleen die abstracte class te extenden. Je hebt dan het ontwerp gemak van een interface, en het prog gemak van een abstracte class.

Ik zie dus niet in waarom je een abstracte class zou prefereren boven een interface.

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 00:47
whoami schreef op 21 november 2003 @ 09:56:
Hmmm, 't ziet er een goed boek uit.
Ik vind het een erg goed boek. Mn omdat je 'de andere uitleg' van het GoF boek krijgt voorgeschoteld in hele praktische situaties.
Dat 'Drawing' object is dan eigenlijk te vergelijken met de 'Device Context' oid in MFC ?
Correct. Het 'vertaalt' zogezegd het 'hoe teken ik een vierkant op een window' naar 'Hoe teken ik een viekant' + 'Hoe teken ik op een window'.

Om ook maar eens iets te ventileren over abstracte classes : Ik zie het meer als een interface met een default implementatie. Niets anders dan een Java adapter klasse volgens mij.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

farlane schreef op 21 november 2003 @ 10:09:
Om ook maar eens iets te ventileren over abstracte classes : Ik zie het meer als een interface met een default implementatie.
Als je class geen data bevat, dan zou je er zo tegen aan kunnen kijken, maar als het wel data bevat dan krijg je een probleem. Stel dat je een proxy wilt maken, en je gaat hiervoor een abstracte class extenden, dan bevat de proxy ook data, en het object waarnaar hij verwijst ook. Ik denk niet dat ik hoef te vertellen dat dit erg vervelend is.

Verder heb je geen multiple inheritance dmv classes bij de meeste oo talen (c++ uitgezonderd), dus als je gaat werken met een abstracte class, krijg je weer een onnodige beperking (tenslotte kan je maar van 1 class extenden). Met interfaces heb je dit probleem dus niet. Het werkt polymorfisme dus niet echt in de hand.

Ik moet er dan ook meteen bij zeggen, dat als het nodig is, je het ontwerp natuurlijk kan aanpassen, en als er geen andere developers op dezelfde code zitten, dat het probleem niet groot is. Maar als je een api hebt, waar veel dingen van afhankelijk zijn, dan heb je wel een groot probleem.

[ Voor 8% gewijzigd door Alarmnummer op 21-11-2003 10:25 ]


  • whoami
  • Registratie: December 2000
  • Laatst online: 11:10
Alarmnummer schreef op 21 november 2003 @ 10:22:
Verder heb je geen multiple inheritance dmv classes bij de meeste oo talen (c++ uitgezonderd), dus als je gaat werken met een abstracte class, krijg je weer een onnodige beperking (tenslotte kan je maar van 1 class extenden). Met interfaces heb je dit probleem dus niet.
Je kan toch inheriten van 1 class, en van één of meerdere interfaces?

https://fgheysels.github.io/


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

whoami schreef op 21 november 2003 @ 10:25:
[...]
Je kan toch inheriten van 1 class, en van één of meerdere interfaces?
Yep..

Maar stel dat je een class nodig hebt, waar op 2 manieren naar gekeken moet worden. Dan heb je een enorm probleem als die 2 manieren al vast liggen in abstracte classes.

Ik moet er eerlijkheidshalve wel bij vertellen dat het niet zo heel vaak voorkomt, dat ik een object meerdere interfaces laat implementeren. Meestal los ik dat op dmv een internal class. Hierdoor blijft mijn hoofdclass clean (niet al te veel methodes) en de taken zijn dan ook meteen fijn onderverdeeld in dejuiste object(en)

[ Voor 57% gewijzigd door Alarmnummer op 21-11-2003 10:31 ]


  • whoami
  • Registratie: December 2000
  • Laatst online: 11:10
Dan zie ik niet in wat die beperking kan zijn volgens jou als je met abstract classes werkt.
Je hebt wel een specifieke implementatie, maar dat is geen enkel probleem als alle classes die je van die abstract class inherit, die zelfde implementatie ook nodig hebben.

https://fgheysels.github.io/


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

whoami schreef op 21 november 2003 @ 10:29:
Dan zie ik niet in wat die beperking kan zijn volgens jou als je met abstract classes werkt.
Ik dacht dat ik dat hierboven al een aantal keren heb uitgelegd.
Je hebt wel een specifieke implementatie, maar dat is geen enkel probleem als alle classes die je van die abstract class inherit, die zelfde implementatie ook nodig hebben.
Ik heb absoluut geen enkel probleem met abstracte classes, begrijp me dus niet verkeerd. Code reuse dmv inheritance is een zeer goeie zaak (het zou stom zijn om het niet te doen, want redundantie in code is meestal een erg slechte zaak) Ik heb alleen een probleem met een abstracte class als hoofd van een class hierarchie.

Ik werk dan altijd met een interface, en maak een convenience abstracte implementatie waar de rest van de objecten van kunnen extenden. Ik heb dan het prog gemak van een abstracte class (reuse), maar ik kan met het ontwerp nog alle kanten op. Als ik een keer iets nodig ben (proxy bv) dan zit ik niet vast aan die abstracte class (stel dat deze abstracte class data bevat), maar kan ik fijn die interface implementeren.

Kijk anders maar eens naar het collection framework van Java/.NET, of de modellen voor de Swing componenten.

[ Voor 38% gewijzigd door Alarmnummer op 21-11-2003 10:40 ]


  • 6K
  • Registratie: September 2002
  • Laatst online: 19-01-2025

6K

is ook zo...

hm... zoals je zelf al aangeeft is het in C++ dus wel erg interessant om te doen, deze ondersteund nl wel multiple inheritance.
Ik werk met een OO-Generator (welke dus C++ genereerd) en hierbij is het ALTIJD zo dat ik 2 abstracte klasses als hoofd van mijn hierarchie maak:
1 voor de BM classes (Business model --> opgeslagen in database)
1 voor APP classes (welke dus NIET naar de database gaan)

(en achter de schermen is het zelfs zo dat zelfs die APP class afkomstig is van de BM class)

Kortom: in C++ is het wel handig om te doen mijns inziens.

٩(͡๏̯͡๏)۶ ٩(●̮̮̃•̃)۶


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

6K schreef op 21 november 2003 @ 10:40:
Kortom: in C++ is het wel handig om te doen mijns inziens.
In c++ kan je niet eens anders, omdat deze geen interfaces kent ;)

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 00:47
Alarmnummer schreef op 21 november 2003 @ 10:22:
[...]

Als je class geen data bevat, dan zou je er zo tegen aan kunnen kijken, maar als het wel data bevat dan krijg je een probleem. Stel dat je een proxy wilt maken, en je gaat hiervoor een abstracte class extenden, dan bevat de proxy ook data, en het object waarnaar hij verwijst ook. Ik denk niet dat ik hoef te vertellen dat dit erg vervelend is.
Daar heb je idd een punt. Mijn insteek in zou ook zijn dat de abstracte class alleen methodes zou bevatten met hun default implementatie.
Verder heb je geen multiple inheritance dmv classes bij de meeste oo talen (c++ uitgezonderd), dus als je gaat werken met een abstracte class, krijg je weer een onnodige beperking (tenslotte kan je maar van 1 class extenden).
Ik zat er zelf meer met een C++ blik naar te kijken, dus deze had ik over het hoofd gezien. Ik ben wel van menig dat als je ontwikkeld in een taal die deze 'beperking' ( dat is een discussie op zich :) ) niet kent, dat je er ook geen rekening mee hoeft te houden. Pragmatisch dus.... :)

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

farlane schreef op 21 november 2003 @ 10:42:
[...]
Ik zat er zelf meer met een C++ blik naar te kijken, dus deze had ik over het hoofd gezien.
Ook een beetje stom van mijn kant dat ik er meteen vanuit was gegaan dat iedereen in een oo taal met interfaces progt.
Ik ben wel van menig dat als je ontwikkeld in een taal die deze 'beperking' ( dat is een discussie op zich :) ) niet kent, dat je er ook geen rekening mee hoeft te houden. Pragmatisch dus.... :)
Tja.. Ik kan gelukking afdwingen dat een class puur virtueel is (dus geen data bevatten, en alle methodes abstract). Zo`n puur virtuele class heet bij ons dan een interface, en is een deel geworden van de taal (je kan er iets mee uitdrukken). Bij c++ zit dit alleen tussen de oren van de developer (of staat in de documentatie), maar het is geen taalelement. Ik denk dat dit wel een hele goeie zaak was geweest, omdat je er meer uitdrukkingskracht mee krijgt.

Verwijderd

Hoe's dit idee? :+ ;)

Java:
1
2
3
4
5
package nl.netforge.got.drawing;

public interface Shape
{
}


Java:
1
2
3
4
5
6
7
8
package nl.netforge.got.drawing;

import java.awt.*;

public interface DrawableShape extends Shape
{
  public void paint(Graphics g, Point location);
}


Java:
1
2
3
4
5
6
7
8
9
10
11
package nl.netforge.got.drawing;

import java.awt.*;

public interface DrawingRule
{
  public static final String GRAPHICS_CONTEXT_SCREEN = "printer";
  public static final String GRAPHICS_CONTEXT_PRINTER = "printer";

  public void paint(Graphics g, Point location);
}


Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package nl.netforge.got.drawing;

import java.awt.*;

public abstract class AbstractDrawableShape implements DrawableShape
{
  public AbstractDrawableShape()
  {
  }

  private Object getGraphicsContext(Graphics g)
  {
    // some context
    return DrawingRule.GRAPHICS_CONTEXT_SCREEN;
  }

  public void paint(Graphics g, Point location)
  {
    Object gc = getGraphicsContext(g);
    getDrawingRule(gc).paint(g, location);
  }

  protected abstract DrawingRule getDrawingRule(Object context);
}


Java:
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
29
package nl.netforge.got.drawing;

import java.awt.*;

public class Line extends AbstractDrawableShape
{
  private Point start = new Point(0, 0);
  private Point end = new Point(0, 0);

  public Line(Point start, Point end)
  {
    this.start = start;
    this.end = end;
  }

  protected DrawingRule getDrawingRule(Object context)
  {
    // ignore context
    return new DrawingRule()
    {
      public void paint(Graphics g, Point location)
      {
        Point startT = new Point( start.x + location.x, start.y + location.y);
        Point endT = new Point( end.x + location.x, end.y + location.y);
        g.drawLine(startT.x, startT.y, endT.x, endT.y);
      }
    };
  }
}

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Mij ontgaat eigelijk het nut van die DrawingRule volledig. En verder werk je ook met Object als return type en als argument. Hierbij krijg ik meestal ook zwaar de kriebels.

En verder lijkt het me dat ieder object gedrawed kan worden, dus ik zie niet in waarom je een aparte interface aanmaakt waarin deze methode niet zit.

[ Voor 31% gewijzigd door Alarmnummer op 21-11-2003 11:03 ]


  • whoami
  • Registratie: December 2000
  • Laatst online: 11:10
Alarmnummer schreef op 21 november 2003 @ 10:32:
[...]

Ik heb alleen een probleem met een abstracte class als hoofd van een class hierarchie.
Mja, idd. Een abstracte class als root van een hierarchie kan idd wel eens voor problemen zorgen en brengt idd met inflexibiliteit met zich mee. (Tenzij die class natuurlijk alleen maar uit pure virtuele/abstracte methods bestaat, maar dan is het eigenlijk een interface :+ )

https://fgheysels.github.io/


Verwijderd

Goed, goed, ik heb weer wat overdreven :)
Mij ontgaat eigelijk het nut van die DrawingRule volledig. En verder werk je ook met Object als return type en als argument. Hierbij krijg ik meestal ook zwaar de kriebels.
Die drawingrule doet in principe wat hierboven ergens werd beschreven, het biedt de mogelijkheid om een context gevoelige paint te implementeren terwijl het ook makkelijk is om gewoon één rule te gebruiken voor alle contexten, misschien had een andere class naam het wat duidelijker gemaakt.

Ik had eerst netjes een int (constante) gekozen voor de context, maar ik meen me te herinneren dat de Java graphics zelf al een of ander DeviceContext of zoiets hebben, vandaar m'n -toegegeven- vieze oplossing met die objecten, het ging zich om het idee.
En verder lijkt het me dat ieder object gedrawed kan worden, dus ik zie niet in waarom je een aparte interface aanmaakt waarin deze methode niet zit.
Ja, tis een beetje overbodig, maar ik was net aan m'n plugin API bezig toen ik dit topic zag. Daarin heb ik dus een super-interface genaamd Plugin die nog geen methods implementeerd, maar als ik een property ontdek die voor alle plugins van toepassing is kan ik die dan makkelijk enforcen door de methods ervoor in de Plugin interface op te nemen. Handig bij iterative prototyping.

[edit]
Ik heb alleen een probleem met een abstracte class als hoofd van een class hierarchie.
Met behulp van een abstracte class kun je bepaald gedrag van je subclasses afdwingen, in dit voorbeeld om een painting rule te geven voor een context. Om het helemaal af te maken had ik de paint method in AbstractDrawableShape final moeten maken maar goed.

[ Voor 13% gewijzigd door Verwijderd op 21-11-2003 13:13 ]


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 00:47
Verwijderd schreef op 21 november 2003 @ 13:09:
Met behulp van een abstracte class kun je bepaald gedrag van je subclasses afdwingen, in dit voorbeeld om een painting rule te geven voor een context. Om het helemaal af te maken had ik de paint method in AbstractDrawableShape final moeten maken maar goed.
Mja, maar dan gebruik je 'em als interface en de discussie ging een beetje over Interface vs Abstract class.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Verwijderd schreef op 21 november 2003 @ 13:09:
Goed, goed, ik heb weer wat overdreven :)
Daar kan ik ook wel handje van hebben ;) Maar probeer er meestal wel af te slopen wat er niet op hoeft. Het is vrij lastig om een goed ontwerp neer te zetten, maak je het te complex, dan werkt het niet fijn, maar je het niet complex genoeg, dan werkt het ook niet fijn. Na verloop van tijd lukt het me steeds beter.
Ja, tis een beetje overbodig, maar ik was net aan m'n plugin API bezig toen ik dit topic zag. Daarin heb ik dus een super-interface genaamd Plugin die nog geen methods implementeerd, maar als ik een property ontdek die voor alle plugins van toepassing is kan ik die dan makkelijk enforcen door de methods ervoor in de Plugin interface op te nemen. Handig bij iterative prototyping.
Ik ben thuis in prototyping, en ook in iterative development. Maar wat is iterative prototyping??
Met behulp van een abstracte class kun je bepaald gedrag van je subclasses afdwingen, in dit voorbeeld om een painting rule te geven voor een context. Om het helemaal af te maken had ik de paint method in AbstractDrawableShape final moeten maken maar goed.
Een template method ;) Maar het neemt nog steeds niet weg, dat het hoofd van een class hierachie beter een interface kan zijn. Het polymorfistische gedrag van DrawableThingy moet nog steeds werken als je een volledig andere (dus eentje die niet extends van AbstractDrawableThingy) implementatie levert.

Hierdoor heb je dus vrijheid om een willekeurige implementatie te leveren, waarbij je dus veel minder beperkingen hebt dan bij een verplichte abstract class. Snappie?

  • EfBe
  • Registratie: Januari 2000
  • Niet online
Het blijft geknoei in de ruimte, mede door single inheritence. Ik ben het met MSalters eens.

Verder vind ik het niet meer dan een persoonlijke smaak om te verklaren "interface moet de basis van een hierarchie zijn". Interfaces zijn een manier om in een single inheritence omgeving toch een zekere mate van 'meerdere gezichten' te krijgen, een abstract base class zorgt voor een goede hierarchie: de abstract base class is de basis, de interfaces zijn voor de 'meerdere gezichten'/polymorphism van de single inheritence tree.

(oh, en men moet niet zo bekrompen doen omtrent OO-hierarchien. Er is veelal geen 'beste' oplossing. Pragmatisme is in veel gevallen nl. te prefereren maar raakt volledig ondergesneeuwd door het purisme waarmee sommige OO hierarchien kapotgedesigned worden. Wat 'beste' dan nog inhoudt is direct gerelateerd aan de overtuiging van de designer: pragmatist of purist).

[ Voor 29% gewijzigd door EfBe op 21-11-2003 15:29 ]

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

EfBe schreef op 21 november 2003 @ 15:27:
Het blijft geknoei in de ruimte, mede door single inheritence. Ik ben het met MSalters eens.
De requirements zijn niet erg duidelijk en daaruit kan je nooit het juiste ontwerp afleiden (omdat er domweg niet genoeg info is).
Verder vind ik het niet meer dan een persoonlijke smaak om te verklaren "interface moet de basis van een hierarchie zijn". Interfaces zijn een manier om in een single inheritence omgeving toch een zekere mate van 'meerdere gezichten' te krijgen, een abstract base class zorgt voor een goede hierarchie: de abstract base class is de basis, de interfaces zijn voor de 'meerdere gezichten'/polymorphism van de single inheritence tree.
Tja, ik kan me inleven in jouw gedachte. Als je aan een object in een class hierarchie een hoofdroll geeft, dan is de 1e gedachte om dit door een abstract class te laten vervullen.

Helaas is dit een zeer beperkende gedachte, omdat je imho een onnodig zwak ontwerp neerzet. Met interfaces hou je vrijhoud om andere implementaties te leveren waarbij je 100% bewegingsvrijheid hebt.

Ik durf trouwens nog wel een stapje verder gaan door te zeggen dat een interface de basis hoort te zijn van ieder 'belangrijk' object in een api (dus niet alleen van een class hierarchie). Met een interface stel je een duidelijk contract op waarmee het systeem uit de voeten kan, en je kan later eenvoudig van implementatie wisselen. Dit krijg je met een gewone class veel minder snel voor elkaar.
(oh, en men moet niet zo bekrompen doen omtrent OO-hierarchien. Er is veelal geen 'beste' oplossing. Pragmatisme is in veel gevallen nl. te prefereren maar raakt volledig ondergesneeuwd door het purisme waarmee sommige OO hierarchien kapotgedesigned worden. Wat 'beste' dan nog inhoudt is direct gerelateerd aan de overtuiging van de designer: pragmatist of purist).
Het is erg gemakkelijk om 'gezond verstand gebruiken' onder de categorie puristisch te gooien. Ik ben zelf ook een praktisch iemand en ik hou van een goed ontwerp omdat me dat gewoon veel problemen bespaard, en ik veel bewegings ruimte hou. Ik doe dit niet omdat ik een oo-purist ben, maar omdat ik sneller met een beter product op de markt kan komen.

[ Voor 31% gewijzigd door Alarmnummer op 21-11-2003 16:09 ]


  • EfBe
  • Registratie: Januari 2000
  • Niet online
Alarmnummer schreef op 21 november 2003 @ 15:36:
Tja, ik kan me inleven in jouw gedachte. Als je aan een object in een class hierarchie een hoofdroll geeft, dan is de 1e gedachte om dit door een abstract class te laten vervullen.

Helaas is dit een zeer beperkende gedachte, omdat je imho een onnodig zwak ontwerp neerzet. Met interfaces hou je vrijhoud om andere implementaties te leveren waarbij je 100% bewegingsvrijheid hebt.
Dit is theoretisch geneuzel natuurlijk :) Interfaces zijn niet alleen een syntactisch middel maar ook een semantisch middel. Dit houdt in dat wanneer je IFoo.Bar() definieert, IEDERE implementatie van IFoo.Bar() dezelfde functionaliteit levert die is gedefineerd bij IFoo.Bar(). Je kunt nu wel zeggen dat iedere implementatie van IFoo.Bar() geoorloofd is, maar dat is onzin. Ik kan net zo goed Foo.Bar() implementeren in iedere derived class van Foo waar de abstract method Bar() in is gedefineerd. Als je de code samenstelt in een class hierarchie en die voorziet van interfaces dan kun je dmv die interfaces de objects gebruiken in verschillende andere code structures. Door de code middels al dan niet abstracte methods/classes te construeren is de complete code set in ieder geval correct. Subsets van die hierarchie kun je dan onder andere interfaces openen.
Ik durf trouwens nog wel een stapje verder gaan door te zeggen dat een interface de basis hoort te zijn van ieder 'belangrijk' object in een api (dus niet alleen van een class hierarchie). Met een interface stel je een duidelijk contract op waarmee het systeem uit de voeten kan, en je kan later eenvoudig van implementatie wisselen. Dit krijg je met een gewone class veel minder snel voor elkaar.
Erm, een class heeft OOK een interface, een abstract class met louter abstract methods is net zo dwingend als een interface. Ieder type gebruikt in een method signature bv impliceert een contract, of dat expliciet door een interface wordt gedefinieerd of indirect door de class definitie, dat maakt niet uit).
Het is erg gemakkelijk om 'gezond verstand gebruiken' onder de categorie puristisch te gooien. Ik ben zelf ook een praktisch iemand en ik hou van een goed ontwerp omdat me dat gewoon veel problemen bespaard, en ik veel bewegings ruimte hou. Ik doe dit niet omdat ik een oo-purist ben, maar omdat ik sneller met een beter product op de markt kan komen.
Wat houdt 'goed ontwerp' in? Ondefinieerbaar. Ik vind de kunstgrepen die ik hier zie langskomen zo langzamerhand op mierenneuken lijken, sorry. :) Ik bedoel, waar gaat het in gotsnaam over, 4 classes. :) Nou, pak een patterntje, bv strategy, (wat al abstract methods impliceert) en in 2 minuten kan ik dat zelfs designen. Voor de purist wellicht niet helemaal perfect (die prakt er wellicht 2 interfaces en 3 classes tussen), maar voegt dat WEZENLIJK iets toe? Je kunt ook ieder datamodel uitnormaliseren tot 5th form, (NIAM levert 3e) maar het is al een teken aan de wand dat weinig mensen weten hoe dat moet zodat je kunt aannemen dat tever doorschieten niet nuttig is, ja voor theoretische discussies, niet voor praktische oplossingen.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


Verwijderd

Hierdoor heb je dus vrijheid om een willekeurige implementatie te leveren, waarbij je dus veel minder beperkingen hebt dan bij een verplichte abstract class. Snappie?
Snap ik helemaal :) Maar als je een API voorbereidt wil je soms beperkingen opleggen, waarom zou Java anders faciliteiten zoals het final keyword hebben? In het voorbeeld dwing je dan mensen om jou logica te gebruiken voor subclasses. Zo voorkom je dat je classes gebruikt worden op een manier die je niet bedoelde.
k ben thuis in prototyping, en ook in iterative development. Maar wat is iterative prototyping??
Ze hebben mij geleerd dat er een software ontwikkel techniek is die rapid iterative prototyping heet. Prototype > evaluatie > nieuw protoype. Als het niet klopt ligt dat of aan mij of aan één mijn professors, ongetwijfeld het laatste ;)


Mijn voorbeeld is natuurlijk vrij overdreven om het ff helemaal volgens het boekje proberen te doen. Ik vind het handig om op deze manier zo duidelijk mogelijk te werken bij grote projecten en bij samenwerken met meerdere mensen aan één project, maar het blijft inderdaad natuurlijk een kwestie van smaak.

[ Voor 21% gewijzigd door Verwijderd op 21-11-2003 17:54 ]


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

EfBe schreef op 21 november 2003 @ 17:30:
[...]

Dit is theoretisch geneuzel natuurlijk :) Interfaces zijn niet alleen een syntactisch middel maar ook een semantisch middel. Dit houdt in dat wanneer je IFoo.Bar() definieert, IEDERE implementatie van IFoo.Bar() dezelfde functionaliteit levert die is gedefineerd bij IFoo.Bar(). Je kunt nu wel zeggen dat iedere implementatie van IFoo.Bar() geoorloofd is, maar dat is onzin.
Iedere implementatie die zich aan het contract houdt is geoorloofd. Dit leek me wel vrij voor de hand liggend.
Erm, een class heeft OOK een interface, een abstract class met louter abstract methods is net zo dwingend als een interface.
Idd. En een puur abstracte class is in principe een interface. Een interface kan alleen gebruikt worden bij multiple inheritance en een abstract class niet.
Ieder type gebruikt in een method signature bv impliceert een contract, of dat expliciet door een interface wordt gedefinieerd of indirect door de class definitie, dat maakt niet uit).
Mijn voornaamste probleem met een abstracte class die niet puur is, is dat je vast zit aan allerlei zaken van die abstracte class waar je zelf geen controle meer over uit kan oefenen. Niet dat dit altijd nodig is, maar ik heb regelmatig software van anderen van... hmmm. Had me nou even een interface gegeven, dan had ik makkelijk nog een paar toevoegingen kunnen doen, bv decorators, proxies, composition etc etc.
Wat houdt 'goed ontwerp' in? Ondefinieerbaar. Ik vind de kunstgrepen die ik hier zie langskomen zo langzamerhand op mierenneuken lijken, sorry. :) Ik bedoel, waar gaat het in gotsnaam over, 4 classes. :) Nou, pak een patterntje, bv strategy, (wat al abstract methods impliceert) en in 2 minuten kan ik dat zelfs designen. Voor de purist wellicht niet helemaal perfect (die prakt er wellicht 2 interfaces en 3 classes tussen), maar voegt dat WEZENLIJK iets toe?
Voor dit kleine ding maakt het geen klap uit, maar het ging over interfaces/abstract classes.
Je kunt ook ieder datamodel uitnormaliseren tot 5th form, (NIAM levert 3e) maar het is al een teken aan de wand dat weinig mensen weten hoe dat moet zodat je kunt aannemen dat tever doorschieten niet nuttig is, ja voor theoretische discussies, niet voor praktische oplossingen.
Tja. Ik zie dat ik je niet kan bekeren, en ik vind het nog steeds jammer dat je me ziet als purist. Ik lees idd veel over design patterns omdat ik anders niet zou weten hoe een goed ontwerp neer te kunnen zetten. En dat goeie ontwerp vind ik gedeeltelijk iets waar ik natuurlijk trots op ben, maar aan de andere kant.. het is in de praktijk gewoon makkelijk een goed ontwerp neer te zetten.

Een goed ontwerp heb je in de praktijk gewoon iets aan en bespaard je gewoon veel ellende. Ik zit ook niet tot in den treure te neuken over hoe iets precies moet. Als ik het vaker heb gedaan, dan neem ik dat over. Als een ontwerp begint te groeien dan begin ik een simpel ontwerp (dat op den duur begint te stinken) ook aan te passen zodat het volledig voldoet aan de eisen die eraan gesteld worden, niet meer.. en niet minder.

Ik ga niet van alles inbouwen waarvan ik denk... dat zou er misschien ooit nog eens mee gedaan kan worden. Het ontwerp blijft gewoon simpel. Alleen bij hulp libraries zorg ik er wel altijd voor dat ik alle belangrijke onderdelen opzet vanuit interfaces. Ik heb het al zo vaak meegemaakt dat ik heb lopen vloeken dat er geen interfaces beschikbaar waren (vooral uit een ander zijn stuff), dat deze kleine moeite me gewoon te veel ellende (lees tijd geld en hoge bloeddruk) kan besparen.

Ik denk verder ook niet dat we er echt uitkomen. Ik werk op de manier die voor mij het meest praktisch is, en dit geldt zonder twijfel ook voor jou.

[ Voor 5% gewijzigd door Alarmnummer op 25-11-2003 09:33 ]


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Verwijderd schreef op 21 november 2003 @ 17:50:
[...]
Snap ik helemaal :) Maar als je een API voorbereidt wil je soms beperkingen opleggen, waarom zou Java anders faciliteiten zoals het final keyword hebben? In het voorbeeld dwing je dan mensen om jou logica te gebruiken voor subclasses. Zo voorkom je dat je classes gebruikt worden op een manier die je niet bedoelde.
Als een class zich aan het contract van de interface houdt, dan mag je die implementatie op wat voor manier dan ook leveren.
Ze hebben mij geleerd dat er een software ontwikkel techniek is die rapid iterative prototyping heet. Prototype > evaluatie > nieuw protoype. Als het niet klopt ligt dat of aan mij of aan één mijn professors, ongetwijfeld het laatste ;)
Ik kan me er wel mee vinden, en dat is inwezen ook wat ik doe bij al mijn prototypes.
Mijn voorbeeld is natuurlijk vrij overdreven om het ff helemaal volgens het boekje proberen te doen. Ik vind het handig om op deze manier zo duidelijk mogelijk te werken bij grote projecten en bij samenwerken met meerdere mensen aan één project, maar het blijft inderdaad natuurlijk een kwestie van smaak.
Tja.. Ik lees veel over design patterns, en dan groei je automatisch een beetje naar de interface kant toe. Misschien komt het ook wel dat ik daardoor op een andere manier er naar ben gaan kijken, want ik zie dit ook terug bij de anderen die veel met patterns bezig zijn.
Pagina: 1