Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[OO/Polyformisme] Onderscheid maken tussen verschillende obj

Pagina: 1
Acties:

  • IceM
  • Registratie: Juni 2003
  • Laatst online: 09:09
De topictitel is misschien wat vreemd, maar ik weet het niet beter te verwoorden. Wanneer er verschillende soorten objecten zijn, die qua eigenschappen/gedrag verschillen van elkaar, gebruik je (ik) polyformisme om de specifieke implementatie van een bepaalde methode te verbergen van de interface van een object. De interface van een bepaald soort object is voor alle afgeleide soorten hetzelfde, alleen de implementatie verschilt op sommige plekken (je zou kunnen zeggen het basic OO principe). Voorbeeld:
Java:
1
2
3
4
5
6
7
8
abstract class Car {
}

class Audi extends Car {
}

class Volvo extends Car {
}


Ik kom in de problemen wanneer er dingen gedaan moeten worden met/op een object waarbij de "dingen" die gedaan moeten worden afhangen van het type object én waarvan de kennis om dat te doen wat mij betreft niet in de klasse zelf horen.

Als ik voort borduur op het Car voorbeeld dan zou het starten van de auto prima in de Car (of afgeleide) klasse kunnen liggen, maar het repareren van een auto niet. Dat zou in mijn optiek thuishoren in een garage. Als er 1 soort garage zou zijn, is dat prima te scheiden zonder rare trucjes te doen:
Java:
1
2
3
4
5
class Garage {
    public void fixCar(Car c) {
        
    }
}


Het probleem begint voor mij wanneer ik aparte garages zou krijgen die alleen autos kunnen repareren van een bepaald merk. Ik kan in een bovenliggende klasse prima het type auto negeren en enkel praten tegen de interface van Car, totdat die auto kapot is en gemaakt moet worden. Ik moet dan ergens checken wat voor type auto dat is, en de juiste garage ophalen om de auto te fixen. Vaak kom ik dan uit op een soort van factory. Voorbeeld:
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
30
31
abstract class Garage {
    abstract void fix(Car car);
}

class AudiGarage extends Garage {
    public void fix(Car car) {
        System.out.println("Fixing audi");
    }
}

class VolvoGarage extends Garage {
    public void fix(Car car) {
        System.out.println("Fixing volvo");
    }
}
    

class GarageFactory {
    private Garage volvo = new VolvoGarage();
    private Garage audi = new AudiGarage();
    
    public Garage getGarageFor(Car c) {
        if (c instanceof Audi)
            return audi;
        
        if (c instanceof Volvo)
            return volvo;
        
        return null;
    }
}


Ik vind dat een wat vreemde constructie en het doet het OO/polyformisme principe ietwat teniet. Een andere implementatie zou kunnen zijn door elk Car object een (referentie naar) zijn eigen garage mee te geven en ofwel een methode te maken die de garage terug geeft, ofwel de aanroep van fix te implementeren in de Car klasse:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
    abstract class Car {
        private Garage garage;

        // optie 1
        public Garage getGarage() {
            return garage;
        }
        
        // optie 2
        public void fix() {
            garage.fix(this);
        }
    }


Maar dat druist een beetje in tegen mijn principes. Een auto moet wat mij betreft niet de kennis hebben over het repareren van zichzelf, en een auto zou ook niet moeten bepalen in welke garage hij gerepareerd wordt.

Hoe los ik zoiets nu op de juiste manier op? Is er wel 1 juiste manier? Dit is natuurlijk maar een voorbeeld, ik kom dit soort dingen vaker tegen en ik heb het idee dat mijn oplossing altijd een beetje een klok/klepel verhaal wordt bij mij omdat ik niet de juiste architectuur en design patterns toe pas.

...


  • epic007
  • Registratie: Februari 2004
  • Laatst online: 17-11 15:31
Ik denk dat je na moet gaan denken over composition versus inheritance. Polyformisme is een erg krachtig gereedschap maar je moet het eigenlijk alleen gebruiken waar het echt nodig is.
http://www.artima.com/designtechniques/compoinh.html

Zou het leven niet een stuk makkelijker worden als het merk van de auto gewoon een eigenschap van Car is?

Java:
1
2
3
class Car { 
    private string brand;
}

of zoiets:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
class Brand { 
    public Garage getGarage();
}

class Audi extends Brand
{
....
}

class Car { 
    private Brand brand;
}

[ Voor 12% gewijzigd door epic007 op 18-11-2012 11:49 ]


  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Als ik het goed begrijp zoek je iets van visitor / double dispatch: Wikipedia: Visitor pattern .

Ook is het goed om na te denken of je inheritance structuur wel klopt als je veel dingen moet doen die afhangen van het type. inheritance is evil use composition Het is vaak beter om Wikipedia: Strategy pattern te gebruiken ipv inheritance.

[ Voor 15% gewijzigd door Zoijar op 18-11-2012 12:32 ]


  • Hydra
  • Registratie: September 2000
  • Laatst online: 06-10 13:59
Het Car voorbeeld is gewoon verkeerd. Welk type auto je hebt is een kenmerk van een instance, het is geen klasse. Je hebt denk ik of een verkeerd voorbeeld gezien ergens of een goed voorbeeld (zowel een fiets als een auto is een voertuig) verkeerd geinterpreteerd.
epic007 schreef op zondag 18 november 2012 @ 11:45:
Zou het leven niet een stuk makkelijker worden als het merk van de auto gewoon een eigenschap van Car is?
Sterker nog, dat is m.i. binnen dit voorbeeld de enige juiste optie. Zou jij in je database voor elke merk auto een andere tabel aanmaken? Denk het niet.

[ Voor 41% gewijzigd door Hydra op 18-11-2012 14:22 ]

https://niels.nu


  • IceM
  • Registratie: Juni 2003
  • Laatst online: 09:09
Dat klopt, het voorbeeld is nogal ongelukkig (verkeerd) gekozen. De topicstart zou misschien aangepast moeten worden naar zoiets:
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
30
31
32
33
34
35
36
37
38
39
40
41
42
abstract class Vehicle {
    public boolean isBroken() {
        return true;
    }
}

class Car extends Vehicle {
    
}

class Bicycle extends Vehicle {
    
}

abstract class VehicleShop {
    public abstract void fixVehicle(Vehicle v);
}

class BikeShop extends VehicleShop {
    public void fixVehicle(Vehicle v) {
        // Vervang ketting, trappers, ...
    }
}

class CarShop extends VehicleShop {
    public void fixVehicle(Vehicle v) {
        // Check motor etc
    }
}   

public void test() {
    List<Vehicle> vehicles = new ArrayList<>();
    vehicles.add(new Car());
    vehicles.add(new Bicycle());
    
    for (Vehicle v : vehicles) {
        if (v.isBroken()) {
            //... met de huidige implementatie moet de shop bepaald worden a.d.h.v. 
            // het type voertuig, en daar zit een "geurtje" aan
        }
    }
}


Hierbij gelden mijn initiële vragen nog steeds en dit is m.i. een structuur die je zou kunnen implementeren middels inheritance. Ik heb nog niet voldoende tijd gehad om de inheritance vs compositie verhalen goed door te lezen en uit te testen, maar ik vermoed dat daar wel (een deel van) de sleutel ligt.

...


  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Je kan zoiets doen:

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
abstract class Vehicle {
    public boolean isBroken() {
        return true;
    }

   public abstract VehicleShop getShop();
}

class Car extends Vehicle {
    public VehicleShop getShop() {return CarShop();}
}

class Bicycle extends Vehicle {
    public VehicleShop getShop() {return BikeShop();}
}

abstract class VehicleShop {
    public void fixVehicle(Car car) {// output error: can't fix this type of vehicles}
    public void fixVehicle(Bicycle bicycle) {// output error: can't fix this type of vehicles}
}

class BikeShop extends VehicleShop {
    public void fixVehicle(Bicycle bicycle) {
        // Vervang ketting, trappers, ...
    }
}

class CarShop extends VehicleShop {
    public void fixVehicle(Car car) {
        // Check motor etc
    }
}   

public void test() {
    List<Vehicle> vehicles = new ArrayList<>();
    vehicles.add(new Car());
    vehicles.add(new Bicycle());
    
    for (Vehicle v : vehicles) {
        if (v.isBroken()) {
            v.getShop().fixVehicle(v);
        }
    }
}

(ik geloof dat dit Visitor + Factory Method is)

[ Voor 7% gewijzigd door Zoijar op 18-11-2012 15:53 ]


  • IceM
  • Registratie: Juni 2003
  • Laatst online: 09:09
Dat gaat, in iedergeval in java, niet werken omdat er geen methode fixVehicle(Vehicle) bestaat in een VehicleShop, enkel fixVehicle(Car) en fixVehicle(Bicycle). Om dat te laten werken zou je zoiets krijgen:
Java:
1
2
3
4
5
6
7
8
9
for (Vehicle v : vehicles) { 
    if (v.isBroken()) { 
        if (v instanceof Bicycle) {
            v.getShop().fixVehicle((Bicycle)v);
        } else if (v instanceof Car) {
            v.getShop().fixVehicle((Car)v); 
        }
    } 
}


En dan moet je dus alsnog exact bepalen welk type object het is. Daarbij moet in deze implementatie de concrete Vehicle implementatie weten hoe hij een een nieuwe shop instantie aan moet maken en dat lijkt me daar niet thuishoren. In het voorbeeld heeft een shop geen eigenschappen maar in het echt zal dat wat ingewikkelder zijn en die kennis hoort m.i. niet thuis in een Vehicle.

Een mogelijke oplossing zou dit zijn, waarbij een Vehicle een shop heeft:

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
abstract class Vehicle {
    private VehicleShop shop;
    
    public Vehicle(VehicleShop shop) {
        this.shop = shop;
    }
    
    public VehicleShop getShop() {
        return this.shop;
    }
    
    public boolean isBroken() {
        return true;
    }
}

class Car extends Vehicle {

    public Car(VehicleShop shop) {
        super(shop);
    }
    
}

class Bicycle extends Vehicle {

    public Bicycle(VehicleShop shop) {
        super(shop);
    }
    
}

abstract class VehicleShop {
    public abstract void fixVehicle(Vehicle v);
}

class BikeShop extends VehicleShop {
    public void fixVehicle(Vehicle v) {
        // Do bike specific stuff. Replace chain etc.
    }
}

class CarShop extends VehicleShop {
    public void fixVehicle(Vehicle v) {
        // Do car specific stuff. E.G. Check engine, ...
    }
}   

public void test() {
    VehicleShop carShop = new CarShop();
    VehicleShop bikeShop = new BikeShop();
    
    List<Vehicle> vehicles = new ArrayList<>();
    vehicles.add(new Car(carShop));
    vehicles.add(new Bicycle(bikeShop));
    
    for (Vehicle v : vehicles) {
        if (v.isBroken()) {
            v.getShop().fixVehicle(v);
        }
    }
}


Vaak zal het echter zo zijn dat ik, op het moment dat ik een concrete Vehicle aanmaak, ik geen lijst heb (of niet altijd) van bestaande shops, en ook niet elke keer een nieuwe shop aan wil maken voor elk vehicle. Ik kom dan uit op een (soort van) factory:

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
class VehicleShopFactory {
    
    public VehicleShop getShop(String type) {
        switch(type) {
            case "bike":
                return new BikeShop();
            case "car":
                return new CarShop();
            default:
                return null;
        }
    }
}

public void test() {
    VehicleShopFactory shopFactory = new VehicleShopFactory();
    
    List<Vehicle> vehicles = new ArrayList<>();
    vehicles.add(new Car(shopFactory.getShop("car")));
    vehicles.add(new Bicycle(shopFactory.getShop("bike")));
    
    for (Vehicle v : vehicles) {
        if (v.isBroken()) {
            v.getShop().fixVehicle(v);
        }
    }
}


Die factory bepaald nu a.d.h.v. een naam welke shop hij moet maken en teruggeven. Misschien is het wel zo dat er niet elke keer een nieuwe shop instantie aangemaakt moet worden, maar moet gewoon de juiste bestaande shop teruggegeven worden, bijvoorbeeld zoiets:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class VehicleShopFactory {
    private VehicleShop bikeShop = new BikeShop();
    private VehicleShop carShop = new CarShop();
    
    public VehicleShop getShop(String type) {
        switch(type) {
            case "bike":
                return bikeShop;
            case "car":
                return carShop;
            default:
                return null;
        }
    }
}


Er wordt nu gechecked op naam, maar in feite is dat niet veel anders dan wanneer je kijkt van welke concrete classe het Vehicle object is (instanceof). De factory lijkt nu heel veel op de "factory" uit de topicstart, alleen de plek waar de factory gebruikt wordt is anders.

Edit:
In plaats van een factory die shops maakt a.d.h. van het vehicle type is het waarschijnlijk een stuk logischer om een vehicle factory te maken die bepaald welke shop bij een vehicle hoort:

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
class VehicleFactory {
    private VehicleShop bikeShop = new BikeShop();
    private VehicleShop carShop = new CarShop();
    
    public Vehicle getVehicle(String type) {
        switch(type) {
            case "bike":
                return new Bicycle(bikeShop);
            case "car":
                return new Car(carShop);
            default:
                return null;
        }
    }
}

public void test() {
    VehicleFactory vehicleFactory = new VehicleFactory();
    List<Vehicle> vehicles = new ArrayList<>();
    vehicles.add(vehicleFactory.getVehicle("car"));
    vehicles.add(vehicleFactory.getVehicle("bike"));
    
    for (Vehicle v : vehicles) {
        if (v.isBroken()) {
            v.getShop().fixVehicle(v);
        }
    }
}

[ Voor 10% gewijzigd door IceM op 18-11-2012 17:39 ]

...


  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Oh ik maakte een fout idd... haalde even wat door elkaar. Dit idee bedoelde ik

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
abstract class Vehicle {
    public boolean isBroken() {
        return true;
    }

   public abstract void fixme(VehicleShop shop);

}

class Car extends Vehicle {
    public void fixme(VehicleShop shop) {shop.fixVehicle(this);}
}

class Bicycle extends Vehicle {
    public void fixme(VehicleShop shop) {shop.fixVehicle(this);}
}

abstract class VehicleShop {
    public void fixVehicle(Car car) {// output error: can't fix this type of vehicles}
    public void fixVehicle(Bicycle bicycle) {// output error: can't fix this type of vehicles}
}

class BikeShop extends VehicleShop {
    public void fixVehicle(Bicycle bicycle) {
        // Vervang ketting, trappers, ...
    }
}

class CarShop extends VehicleShop {
    public void fixVehicle(Car car) {
        // Check motor etc
    }
}   

public void test() {
    List<Vehicle> vehicles = new ArrayList<>();
    vehicles.add(new Car());
    vehicles.add(new Bicycle());
    
    for (Vehicle v : vehicles) {
        if (v.isBroken()) {
// get a shop somehow, probably some factory
            v.fixme(shop);
        }
    }
}

Dat is visitor, waarbij verschillende shops misschien ook car en bicycles kunnen maken. Het ligt er een beetje aan wat je precies wilt.

Verwijderd

Proberen een probleem uit te leggen adhv Foos / bars / cars en bikes werkt gewoon niet. nooit niet, altijd niet.
Elk domein is anders, en elk probleem domein vereist aan andere aanpak.

Vaak kan het uitleggen van je probleem, als in: het daadwerkelijke probleem domein waar je in zit, leiden tot nieuwe inzichten in de context van jouw probleem.
Dat gaat nooit werken met een Car/Bike voorbeeld, omdat 'wij' niet mee kunnen denken over het échte probleem waar je mee zit.

Foo en Bar is leuk voor het laten zien van class en flow diagrammen bij een bepaald pattern. Maar werkt gewoon niet om jou een echte code oplossing te geven.

Het kan namelijk zijn dat jouw 'probleem' gewoon even tegen een ander daglicht aangehouden moet worden, waardoor je in je code ook ineens dat 'ahha' moment krijgt.

Schroom niet om gewoon te vragen wat je écht wil weten. En in 99 van de 100 gevalllen kan het echt geen kwaad om in de termen te praten waar je mee zit (als in: je zal echt geen bedrijfsgeheimen lekken oid :))

edit: Als je probleem 'te moeilijk' is om uit te leggen via een forum, dan zit je met foo/bar analogieen sowiso verkeerd, want dan probeer je een moeilijk probleem al om te vormen tot een makkelijk probleem, en weten wij al helemaal niet waar je uiteindelijk terecht wil komen 8)7

[ Voor 12% gewijzigd door Verwijderd op 18-11-2012 19:20 ]


  • Sebazzz
  • Registratie: September 2006
  • Laatst online: 23-11 19:04

Sebazzz

3dp

Vaak komt een school met dit soort brakke voorbeelden en cases aan.

[Te koop: 3D printers] [Website] Agile tools: [Return: retrospectives] [Pokertime: planning poker]


Verwijderd

Sebazzz schreef op zondag 18 november 2012 @ 19:19:
Vaak komt een school met dit soort brakke voorbeelden en cases aan.
Zelfs de (goede) boeken, jep..

mijn 'software architecture' docent zei altijd: software architect wordt je pas na 10 jaar in het veld gewerkt te hebben. minimaal...
(bij wijze van)

ik ben nu zo'n 8 jaar verder. en nope, ik heb nog steeds niet zoveel ervaring dat ik mezelf een senior, laat staan proffesional software architect noem.. (oh wat een zelf kennis :D)

Leuke serie posts over 'design patterns in the test of time': http://ayende.com/blog/tags/design-patterns-test-of-time

Edit: ik weet nog heel goed dat ik tiiiiiiiijden heb zitten stoeien met het doorkrijgen van patterns.
Allemaal 'nep' apps maken om te kijken hoe het nou echt in elkaar steekt.

Ik raad het je af, ga er niet eens over nadenken gewoon en:
- Lees de boeken, 'weet' dat er bepaalde patterns zijn.
- ga lekker verder met je werk (of school?) en wacht tot het moment dat je bij jezelf denkt, WTF hoe los ik dit mooi op.
- kom dan pas weer terug bij patterns :)
- Zoals de blog posts die ik niet noemde al een beetje aangeven. 90% van die mooie patterns in het Gang of Four boek, zul je nooit gebruiken. Probeer ze dus ook niet te begrijpen adhv Foo/Bar voorbeelden, daar raak je alleen maar gefrustreerd en verward van.

[ Voor 43% gewijzigd door Verwijderd op 18-11-2012 19:29 ]


  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
Verwijderd schreef op zondag 18 november 2012 @ 19:22:
ik ben nu zo'n 8 jaar verder. en nope, ik heb nog steeds niet zoveel ervaring dat ik mezelf een senior, laat staan proffesional software architect noem.. (oh wat een zelf kennis :D)
Dan ben je al ver op weg. het merendeel van de mensheid heeft niet door dat het bijna niks weet. :P

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


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

H!GHGuY

Try and take over the world...

Ik denk dat Zoijar voor veel situaties al een goeie oplossing aandraagt.

Maar, soms kan/mag het ook gewoon expliciet:
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
abstract class Vehicle {
    public boolean isBroken() {
        return true;
    }
   void goto(VehicleShop shop);
}

class Car extends Vehicle {
  void goto(VehicleShop shop) { shop.fix(this); }
}

class Bicycle extends Vehicle {    
  void goto(VehicleShop shop) { shop.fix(this); }
} 

abstract class VehicleShop {
  void fix(Car car) { // error; }
  void fix(Bicycle cycle) { // error; }
  Type[] canFix();
}

class CarShop extends VehicleShop {
  CarShop() { ShopRegister.RegisterShop(this); }
  void fix(Car car) { // whatever; }
  Type[] canFix() { return Type[](Car) } // wat is het javaans hier ook weer voor?
}
class BikeShop extends VehicleShop {
  BikeShop() { ShopRegister.RegisterShop(this); }
  void fix(Bicycle cycle) { // whatever; }
  Type[] canFix() { return Type[](Bycicle); }
}

static class ShopRegister { // naam kan wat beter; kunnen static classes in Java?
  Dictionary<Type, VehicleShop> shops;
  // naast Type, zou je hier ook een enum of zo kunnen gebruiken

  void RegisterShop(VehicleShop shop) {
    foreach (Type t : VehicleShop.canFix())
      shops.add(t, shop)
  }
  VehicleShop getShop(Vehicle v)
  {
    return shops[v.getType()];
  }
}

public void test() {
    CarShop cshop = new CarShop();
    BikeShop bshop = new BikeShop();

    List<Vehicle> vehicles = new ArrayList<>();
    vehicles.add(new Car());
    vehicles.add(new Bicycle());
    
    for (Vehicle v : vehicles) {
        if (v.isBroken()) {
            v.goto(ShopRegister.getShop(v));
        }
    }
}


Deze oplossing kan misschien zelfs extra waardevol zijn als je in de ShopRegister bijvoorbeeld ook adressen bijhoudt en dan de dichstbijzijnde garage van een type kan opzoeken. Of als 1 garage soms meerdere types kan fixen, etc.
Hier hebben we switch-case op een type of enum eigenlijk vervangen door een search in een dynamisch gemaakte dictionary. Zie het misschien meer in de richting van het Service-Locator pattern (met dit voorbeeld zelfs letterlijk te nemen :+ )

Maar zoals hierboven al aangehaald, zonder het echte voorbeeld kunnen we je echt wel de verkeerde richting uitsturen. In veel gevallen zou ik Zoijars approach kiezen, maar sommige dingen die "vies" lijken (getType() anyone?) kunnen in bepaalde gevallen echt wel waarde hebben.

ASSUME makes an ASS out of U and ME


  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Erg eens met Skafa hier.

Vroeger heb ik ook DP gelezen (en pattern hatching, modern C++ design, etc, etc) en dacht ik alle code meteen in patterns en hele structuren... en altijd werd het veel te ingewikkeld en was ik eigenlijk alleen maar bezig ingewikkelde structuren op te zetten in plaats van....software bouwen. En vrijwel altijd als ik het dan uit wilde breiden kon het toch alsnog niet en moest ik alsnog alles ombouwen.

Nu doe ik het anders: schrijf gewoon eerst code die werkt. Ik gebruik zo min mogelijk inheritance (composition is echt zo veel flexibeler), ik probeer niet van te voren alle interfaces te bouwen... dat doe ik pas als ik weet wat alles doet. Lelijk en vies dat schoon je later op, als je weet wat je ongeveer wilt. Maar.... negen van de tien keer schoon ik niks meer op, omdat het gewoon werkt en duidelijk is; wat wil je dan eigenlijk nog meer?

Je kan niet alles zo opschrijven dat je altijd alles uit kan breiden. In de praktijk kan je ook bijna nooit daadwerkelijk een klasse overerven -- tenzij je met zulke goed-begrepen problemen als GUIs werkt oid.

(en zat grote frameworks zitten vol met if (dynamic_cast<X>(y)) ... inheritance... je kan altijd net niet genoeg met alleen de base class :P )

[ Voor 6% gewijzigd door Zoijar op 18-11-2012 20:01 ]


Verwijderd

Zoijar schreef op zondag 18 november 2012 @ 19:58:
Nu doe ik het anders: schrijf gewoon eerst code die werkt. Ik gebruik zo min mogelijk inheritance (composition is echt zo veel flexibeler), ik probeer niet van te voren alle interfaces te bouwen... dat doe ik pas als ik weet wat alles doet. Lelijk en vies dat schoon je later op, als je weet wat je ongeveer wilt.
Agile ? :)

Nu ik m'n post terug lees, is de toon misschien een beetje hard naar de op... dat was niet helemaal de bedoeling. Blijf vooral bezig met kennis vergaren :)
Uiteindelijk moet je wel die boeken (of blogs) een keer gelezen / bekeken hebben, om te weten dat er zoiets als patterns en algoritmes bestaan en in welke richting je eventueel moet zoeken áls je er zelf even niet uit komt.

Maar behoed je er wel voor, zoals Zoijar ook zegt, dat je niet te ver moet gaan met het tot op detail uitdenken van een goede architectuur.

Overigens werkt een probleem bedenken om een bepaald pattern te 'oefenen' of uit te proberen niet echt, vandaar ook de jip & janneke voorbeelden in veel boeken en op sites.

Een uitzondering vind ik wel de boeken van Martin Fowler (vooral http://martinfowler.com/books/eaa.html) waarin er tot op bepaalde hoogte 'echte' domein problemen worden aangepakt. Deze strekken dan ook wat verder dan de GoF patterns. (veelal combinaties / variaties op, toegespitst op een bepaalde situatie)

  • Waster
  • Registratie: September 2006
  • Laatst online: 14-04 17:49
Het belangrijkste van design is dat je complexiteit reduceert. Loose coupling is belangrijk, omdat je dan je modules ook in isolatie kan begrijpen. Inheritance is eigenlijk het tegenovergestelde, want je koppelt de klasses aan de superklasses. In de meeste gevallen voldoet object compositie gewoon. Als classes een methode delen, betekent dat ze dan een superklasse moeten delen of is een static helper functie in een utility class voldoende?

Om op het voorbeeld in te gaan. Waarom moet de fix methode eigenlijk in een andere class? Ik kan me voorstellen dat een fix methode door een andere persoon wordt aangeroepen dan een move functie. Maar waarom zou dat betekenen dat de fix methode niet in de Car class thuishoort. Fix is gewoon een methode op de class Car. Het is vrij onvermijdelijk denk ik, want waarschijnlijk worden internals daarin aangepast die verder niet zichtbaar zijn voor de buitenwereld. Ik denk dat het hele issue verdwijnt als je de fix methode in de juiste class zet.

  • alienfruit
  • Registratie: Maart 2003
  • Nu online

alienfruit

the alien you never expected


  • EddoH
  • Registratie: Maart 2009
  • Niet online

EddoH

Backpfeifengesicht

Om nog even een totaal onconstructieve bijdrage te leveren: het is volgens mij 'polymorfisme' en niet 'polyformisme'
Mijn woordenboek kent polyformisme in ieder geval niet :+

[ Voor 26% gewijzigd door EddoH op 19-11-2012 11:27 ]


  • Hydra
  • Registratie: September 2000
  • Laatst online: 06-10 13:59
En dan vraagt men zich af waarom Java developers de reputatie hebben zaken te complex te maken...

https://niels.nu


  • alienfruit
  • Registratie: Maart 2003
  • Nu online

alienfruit

the alien you never expected

Precies daarom krijgen ze ook nooit wat af ;)

Verwijderd

Hydra schreef op maandag 19 november 2012 @ 11:35:
[...]


En dan vraagt men zich af waarom Java developers de reputatie hebben zaken te complex te maken...
Zoals deze: YouTube: Ruby on Rails vs Java - Commercial #1 of 9 ahaha

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

haha, vertel me aub dat dat artikel sarcastisch bedoeld is? :/

  • Hydra
  • Registratie: September 2000
  • Laatst online: 06-10 13:59
Als iets dichtgetikt is, is het de RoR community wel.

https://niels.nu


Verwijderd

Hydra schreef op maandag 19 november 2012 @ 12:50:
[...]


Als iets dichtgetikt is, is het de RoR community wel.
ik werk er ook niet mee, maar vond hem wel van toepassing daar :-)

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Ik ken al die termen toch niet; ik ben een self-made man O-)

Maar na het even opgezocht te hebben: ja, dat klinkt wel goed.

  • Herko_ter_Horst
  • Registratie: November 2002
  • Niet online
Wordt daar niet gewoon closures beschreven door iemand die niet weet wat closures zijn?

[ Voor 32% gewijzigd door Herko_ter_Horst op 19-11-2012 18:48 ]

"Any sufficiently advanced technology is indistinguishable from magic."


  • Hydra
  • Registratie: September 2000
  • Laatst online: 06-10 13:59
Sinds wanneer heeft Java closures dan?

https://niels.nu


  • Herko_ter_Horst
  • Registratie: November 2002
  • Niet online
Hydra schreef op maandag 19 november 2012 @ 19:04:
Sinds wanneer heeft Java closures dan?
Nog niet. Waarschijnlijk in Java 8. Maar dat is nog geen reden om niet één van de bestaande closure libraries te pakken, in plaats van een eigen, niet uitbreidbaar, niets toevoegend framework te bouwen om een for-loop te vermijden.

[ Voor 9% gewijzigd door Herko_ter_Horst op 19-11-2012 19:14 ]

"Any sufficiently advanced technology is indistinguishable from magic."


  • Killemov
  • Registratie: Januari 2000
  • Laatst online: 25-09 11:11

Killemov

Ik zoek nog een mooi icooi =)

Even terug naar de startpost ...

OO/Jave-technisch gezien:
  1. Als een Audi wezenlijk ander gedrag vertoont dan een Volvo dan kun je inheritance gebruiken.
  2. Als een AudiGarage wezenlijk ander gedrag vertoont dan een VolvoGarage dan kun je inheritance gebruiken.
  3. Als je een Audi specifiek wilt koppelen aan een AudiGarage dan kun je o.a. met generics gaan goochelen.
  4. Met de factory is ipc niets mis.
  5. Je kan in fix( Car ) een test doen op de juiste class.
Vanuit het probleemdomein bekeken ben ik ik het gedeeltelijk eens met epic007. Als een merk slechts een attribuut is van een auto of een garage, dan heeft het geen zin om daar dan nog inheritance voor te gebruiken.

Dus krijgt een Car:
code:
1
private final String brand;
(Vullen in de constructor)

En een Garage:
code:
1
private final ArrayList<String> brands = new ArrayList<String>();
( En uiteraard een method om te testen of een bepaalde Garage een bepaalde Car kan repareren.)

Hey ... maar dan heb je ook wat!

Pagina: 1