OOP syntaxen en werkingen

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Pagina: 1 2 3 4 volgende »

Reshad F

Reshad F

10/06/2012 21:08:30
Quote Anchor link
oke na uitstekende hulp zoals altijd hier van onder andere Wouter en Erwin heb ik maar even geprobeerd om zonder tutorials etc een class te bouwen. (wel kijken naar de linkjes van wouter) want het was idd nog een beetje kopieren en plakken met OOP maar ik ben nu wel op de goede weg denk ik. heb begin gemaakt met een class 'databaseConfig' hier staat de database configuratie in. dan heb ik vervolgens een class gemaakt genaamd 'databaseConnect' hier ga ik connecten met de database. maar nu. snap ik een paar dingen niet.

wat is het verschil tussen

abstract class ...
en
class ...

en moet ik nu de databaseConnect extenden uit de databaseConfig of moet ik hier de __construct gebruiken zoals __construct(databaseConfig)? of denk ik nu helemaal verkeerd?
 
PHP hulp

PHP hulp

29/03/2024 02:42:16
 
Terence Hersbach

Terence Hersbach

10/06/2012 21:16:04
Quote Anchor link
abstract class is een class die abstracte functies kan bevatten. Deze functies moeten ingevuld worden door de classes die die class extenden.

2e vraag: Je configuratie geef je mee in je construct en sla je op een 'property'. Deze configuratie is een eigenschap van de verbinding.

Tip: met classes kun je zo denken:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
<?php
abstract class Auto
{
  abstract public function getBrand();

  abstract protected function startMotor();

  public function start()
  {

    $this->startMotor();
  }
}


class Renault_Twingo extends Auto
{
  public function getBrand()
  {

    return new Brand('Renault');
  }


  protected function startMotor()
  {

    $this->turnKeys();
    $this->runFuelPump();

    ..
  }
}

?>


oftewel: een Renault Twingo is in algemenere zin een auto met een standaard set eigenschappen en methoden.
Gewijzigd op 10/06/2012 21:18:44 door Terence Hersbach
 
Jeroen VD

Jeroen VD

10/06/2012 21:24:24
Quote Anchor link
Waarom doe je de connect los van de configuratie? Dat is er toch een deel van, dus in 1 class. Die dan weer extenden in elke mapper.

De connect doe je dan in de construct van de configuratie.
 
Terence Hersbach

Terence Hersbach

10/06/2012 21:30:35
Quote Anchor link
Nee Jeroen, een configuratie heeft niks met een connectie te maken. Configuratie is een onderdeel van je verbinding, maar een configuratie is niet je verbinding. Dat zijn 2 totaal verschillende objecten.
 
Wouter J

Wouter J

10/06/2012 21:31:57
Quote Anchor link
Een extend relatie (extenden) moet je zien als een IS_EEN relatie. Extenden doe je als iets ietsanders is. Bijv. een hond IS EEN dier, een Renault Twingo IS EEN auto, een sessie IS EEN opslagmethode.

In al deze dingen heb je de superklasse: dier, auto, opslagmethode. En je hebt de subklassen: hond, renault twingo, sessie. De subklassen extenden de superklasse.


OO bestaat eigenlijk uit 2 onderdelen:
- Object Geörienteerd scripten
- Flexibel en aanpasbaar maken van je code

Interfaces en abstracte klassen hebben met dat 2e te maken. Je wilt nooit iets dubbel hoeven schrijven. Daarmee bedoel ik dat je dit niet wilt:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
<?php
class Admin
{
    protected $name;
    protected $rang;

    public function __construct($name)
    {

        $this->name = $name;
        $this->rang = 10;
    }


    public function getName()
    {

        return $this->name;
    }


    public function getRang()
    {

        return $this->rang;
    }
}

class User
{
    protected $name;
    protected $rang;

    public function __construct($name)
    {

        $this->name = $name;
        $this->rang = 1;
    }


    public function getName()
    {

        return $this->name;
    }


    public function getRang()
    {

        return $this->rang;
    }
}

?>

De meeste van deze klassen bevatten dubbele code. Dat kan je oplossen door een superklasse te maken waarvan beide de methoden extenden:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
<?php
class Person
{
    protected $name;
    protected $rang;

    public function __construct($name)
    {

        $this->name = $name;
        $this->rang = 10;
    }


    public function getName()
    {

        return $this->name;
    }


    public function getRang()
    {

        return $this->rang;
    }
}

class Admin extend Person
{
    // ...
}
class User extend Person
{
    // ...
}
?>


Alleen nu hebben we een probleem. Hoe gaan we het nu oplossen met de rangen? Nu hebben ze beide 10 als rang, terwijl de User rang 1 moet hebben.
De oplossing is werken met een abstracte klasse. Hiermee kun je sommige methoden vaststellen (zoals getName, getRang) en andere open laten, die moet de subklasse invullen. Deze methoden zijn de abstracte methoden. Het mooie daarvan is dat we verplichten dat de subklasse die methode moet hebben, maar wat hij doet dat gaat de superklasse niet aan.

Om deze code nog wat meer flexibel te maken gaan we de laatste duplicated code (de constructor) in 2 stukken splitsen: Het setten van de naam en het setten van de rang.
Het setten van de naam doen we in de constructor, alleen het setten van de rang doen we in een private method setRang. Hierdoor kunnen we in de abstracte superklasse alle dubbele code overnemen uit de subklassen en hebben we in de subklassen alleen unieke code:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
<?php
class Person
{
    protected $name;
    protected $rang;

    public function __construct($name)
    {

        $this->name = $name;
        $this->setRang(); // roep onze, door de subklasse aangemaakte, setRang method aan
    }

    public function getName()
    {

        return $this->name;
    }


    public function getRang()
    {

        return $this->rang;
    }


    // laat deze method invullen door de subklasse
    abstract private function setRang();
}

class Admin extend Person
{
    // voeg rang = 10 toe
    private function setRang()
    {

        $this->rang = 10;
    }
}

class User extend Person
{
    // voeg rang = 1 toe
    private function setRang()
    {

        $this->rang = 1;
    }
}

?>
 
Reshad F

Reshad F

10/06/2012 21:32:56
Quote Anchor link
@terence ah nu snap ik de nut van abstractie. in dit geval kan de databaseConfig geen abstrace class worden omdat geen enkele andere class de configuratie kan gebruiken die daar in zit. heb ik dit goed?

maar het databaseConnect kan databaseConfig wel extenden toch omdat het de info daaruit gebruikt om een verbinding op te zetten. denk ik nu zo goed?

ff wat ik tot nu toe heb voor deze 2 class. http://pastebin.com/qZTDL7ut

@jeroen ja ik dacht wat als ik nu de configuratie nodig heb voor een andere sql type bijv mysqli of pdo. dan moet ik de configuratie kunnen gebruiken in die classes toch? hoef ik niet weer alles erin te tikken. of geld dit hier niet voor op een of ander manier?
Gewijzigd op 10/06/2012 21:55:02 door Reshad F
 
Erwin H

Erwin H

10/06/2012 21:35:06
Quote Anchor link
In wat meer worden.
Een abstracte class kan zoals Terence al zegt abstracte methodes bevatten. Belangrijker echter is dat een abstracte class niet geinstantieerd kan worden, je kan de abstracte class zelf dus niet gebruiken, je kan er alleen een afgeleide class op schrijven die de eventuele abstracte functies erin implementeert en verder uitbreid.

Het nut van een abstracte class is dat je bepaalde functionaliteit die je in verschillende classes wil inbouwen al kan definieren en dus kan gebruiken op meerdere plekken. De abstracte functies erin kan je dan weer gebruiken om af te dwingen dat bepaalde functies zullen worden geimplementeerd door de afgeleide classes. Als je dat namelijk op die manier afdwingt, kan je functies in de abstracte class al aanroepen, zonder dat je weet hoe het geimplementeerd gaat worden.

En voor de duidelijkheid, een abstracte class kan abstracte functies bevatten, maar hoeft niet. Als echter een class een abstracte functie bevat, dan moet de class abstract zijn.

Edit: beetje mosterd na de maaltijd. Ik zie nu pas de hele lap tekst van Wouter :-)
Gewijzigd op 10/06/2012 21:37:09 door Erwin H
 
Reshad F

Reshad F

10/06/2012 21:43:43
Quote Anchor link
@wouter ik had je reactie nog niet gelezen omdat ik weer reactie aan het tikken was maar heb het nu doorgelezen en je legt het wederom keurig uit! keurige voorbeeldjes. zo leer ik het nog te snel ;)

@Erwin ik snap het helemaal. alles wat je verwacht te gebruiken ( zoals een rang setten dan weet je dat je een abstracte class gaat gebruiken) en voor bijv de auto klasse een fuel abstracte ( gaat er bijv in een auto diesel in en in de andere petrol )

maar bijv in een database connection classe die ik nu aan het maken ben kan ik dus absoluut geen abstractie gebruiken toch? want er is maar 1 manier om te connecten. maar ik denk nu dus bij mezelf. nee het kan wel. want je hebt verschillende databases dus dan kan je daar een abstractie voor maken. denk ik nu zo goed of..?
 
Wouter J

Wouter J

10/06/2012 21:51:59
Quote Anchor link
Reshad, ja dat heb je goed. En met die gedachte stap je al over het de 2e stuk van OO: Het flexibel maken van code met patterns. Want je bent nu bezig met het Adapter Pattern.

Even een vraag voor je: Probeer eens een goed overzicht te tekenen van deze klassen. Welke is abstract en welke niet en welke extends welke?


Merk overigens op dat je ook nog een interface hebt. Hiermee kan je klassen aan elkaar koppelen. Je weet dan eigenlijk nog geen 1 methode hoe je ze moet afhandelen, alleen je weet wel dat je straks zeker wilt zijn dat klassen bepaalde methoden bevatten. Later kun je in andere klassen dan kijken of ze afstammen van die Interface, waarmee je zeker weet welke methoden ze bevatten. Wat die methoden precies doen boeit je dan niks, als ze maar doen wat ze moeten doen.

En dan ga je komen naar 1 van de ontwerpprincipes: Programmeer naar een interface/superklasse i.p.v. naar een implementatie/subklasse. Probeer dus altijd superklassen te vinden en probeer zo min mogelijk over te laten aan de subklassen.
 
Reshad F

Reshad F

10/06/2012 22:14:05
Quote Anchor link
oke hier heb ik echt veel aan bedankt iedereen! :)

wouter ik heb het even op papier gezet (digitaal dan) :p

link

is de denkwijze voor deze klasse zo goed?
Gewijzigd op 10/06/2012 22:14:20 door Reshad F
 
Erwin H

Erwin H

10/06/2012 22:21:22
Quote Anchor link
Als je kijkt naar die connectie class moet je denk ik niet zozeer rekening houden met mysql, mysqli of pdo. Dat is een technische keuze waar je als het eenmaal werkt, niet veel meer aan hoeft te doen. Je zal de een of de ander gebruiken.
Wat mijns inziens zinvoller is, is om na te denken over wat voor soort database te gaat gebruiken. Op het moment gebruik je waarschijnlijk MySQL, maar bij een volgend project is dat misschien MSSQL, of nog later Oracle of DB2.
Dan wordt het van belang om ervoor te zorgen dat je verschillende connectie objecten kan hebben voor de verschillende database systemen. De rest van je classes zal het worst zijn (met een kleine slag om de arm voor specifieke SQL verschillen), die willen gewoon een connectie kunnen maken en queries kunnen uitvoeren.

Wat je dan kan doen is een interface schrijven die bepaalt welke methodes de verschillende connection classes moeten implementeren. Zo kan je ervoor zorgen dat je andere database classes altijd de connection class kan aanspreken, voor welke DB het ook is.
Gewijzigd op 10/06/2012 22:21:39 door Erwin H
 
Reshad F

Reshad F

10/06/2012 22:26:55
Quote Anchor link
hmm heb je hier een klein voorbeeldje van misschien erwin? hoe de interface er uit hoort te zien. dit ben ik nog niet tegengekomen in tutorials tot nu toe. althans dat denk ik.. ben wel dingen tegengekomen met

.... implements ... weet niet of dat het is?

edit: heb het even uitgevogelt op php.net dat is het inderdaad. maar hoe ziet zown implement er dan uit wanneer de database verschilt?
Gewijzigd op 10/06/2012 22:32:53 door Reshad F
 
Wouter J

Wouter J

10/06/2012 22:42:24
Quote Anchor link
Reshad, je bent goed opweg. Alleen zeg je nu dat dbConfig de superklasse is en dbConnect de subklasse. Die relatie moet dan een IS_EEN relatie zijn, kan je zeggen dbConnect IS_EEN dbConfig? Nee toch? Dus moet je die relatie weghalen. Het is meer een HEEFT_EEN relatie (dat betekend niet meer dan een relatie in je hoofd en niet in de code). Want dbConnect HEEFT EEN dbConfig is wel juist.

Ook moet je even goed gaan nadenken. De dbConfig klasse slaat waardes op als user, pass, dbname, host, enz. Verschillen die per adapter?
En het maken van de verbinding in dbConnect, verschillen die per adapter?

Welke klasse moet dus meerdere subklassen hebben en welke niet?


En nu wil ik nog even wat structuur aanbrengen in je tekeningen, aangezien dat heel belangrijk gaat worden. Dit doen we namelijk allemaal met UML diagrammen. Een voorbeeld tekening van mijn voorbeeld hierboven kun je hier vinden. Wat uitleg:
- Blokken bevatten eerst de klassenaam, is dit een abstracte klasse dan is deze cursief.
- Daarna komt de sectie met properties en eventuele types, vooraan staat de access (+ is public, # protected en - private).
- Dan de method met eventuele argumenten en access, abstracte methods zijn cursief
- een doorgetrokken lijn met een open hoek aan het eind is een IS_EEN (extend) relatie tussen klassen.
- een stippellijn met een open hoek aan het eind is een IMPLEMENTEERT (met interfaces) relatie.
- een doorgetrokken lijn met 2 streepjes als een hoek aan het eind is een HEEFT_EEN relatie.
Gewijzigd op 10/06/2012 22:46:46 door Wouter J
 
Reshad F

Reshad F

10/06/2012 23:35:27
Quote Anchor link
hmm als ik het nu goed begrijp is

- databaseConnect apart van de databaseConfig. maar het moet niet extend worden. terwijl de een de ander wel nodig heeft.
dit kan ik gewoon oproepen dmv de constructor. >> __construct(databaseconfig)

- dbconfig slaat waardes op maar dit zijn volgens mij voor elke database gelijk of het per adapter verschilt. ik denk het niet?
staan ze zo dan goed in hun eigen klasse of moeten ze dan op een andere manier verwerkt worden?

- het maken van een verbinding is volgens mij per adapter wel verschillend maar dit weet ik niet omdat ik tot op heden alleen met mysql gewerkt heb dus ik weet niet hoe het bij andere databases gaat en of ik daar dan dezelfde manier voor kan gebruiken.

al met al ben ik zover gekomen met de code afgeleid van wat ik op papier heb staan. --> http://pastebin.com/uXr6Y5Md

pak ik het zo goed aan?
 
Jordi Kroon

Jordi Kroon

11/06/2012 01:03:21
Quote Anchor link
Mij lijkt databaseConnect eerder een functie naam dan een klasse naam.

Zou je niet beter Database als Class kunnen gebruiken. En er is een regel dat een class altijd met een hoofdletter moet beginnen.
 
Wouter J

Wouter J

11/06/2012 07:49:45
Quote Anchor link
Jordi, het is geen regel, alleen alle standaarden houden zich eraan en schrijven het voor.

Ook doet Reshad het denken in objecten nu goed, qua connect apart. Je kan ook een Database klasse maken, maar dan heb je het niet meer over objecten maar over een verzameling functies. Ook handig soms, alleen Reshad wil nu OO leren.

Reshad, nee je bent niet goed bezig. Voor de helft zit je goed, voor de andere helft niet. De Configuratie verschilt niet per adapter, dat is dus 1 config klasse.
De connection verschilt wel per adapter. Je maakt dus 1 superklasse die alle methods pakt die gelijk zijn bij alle adapters. Vervolgens heb je subklassen die speciaal per adapter zijn. Je krijgt dus zoiets:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
<?php
class DbConnect
{
    // methoden
}
class MySQLDbConnect extends DbConnect
{
    // ...
}
class MySQLiDbConnect extends DbConnect
{
    // ...
}
class PDODbConnect extends DbConnect
{
    // ...
}
class PDOMySQLDbConnect extends PDODbConnect
{
    // ...
}
class PDOMSSQLDbConnect extends PDODbConnect
{
    // ...
}
?>
 
Erwin H

Erwin H

11/06/2012 09:48:44
Quote Anchor link
Reshad F op 10/06/2012 22:26:55:
hmm heb je hier een klein voorbeeldje van misschien erwin? hoe de interface er uit hoort te zien. dit ben ik nog niet tegengekomen in tutorials tot nu toe. althans dat denk ik.. ben wel dingen tegengekomen met

Bedenk wat een config class zou moeten kunnen. De config class moet de verbinding met de database maken, de verbinding sluiten, een query uitvoeren op de database, uitkomsten terugsturen etc. Op basis daarvan kan je een interface opzetten om ervoor te zorgen dat elke class die zich wil voordoen als connectie class dit kan:

Dit is uiteraard een voorbeeld, in het echt zal je meer methodes nodig hebben en wil je misschien in de executeQuery methode al de resultaten teruggeven.
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
<?php
interface Connection_Interface{
  public function __construct( $host, $username, $password );
  public function connect();
  public function isConnected();
  public function disconnect();
  public function executeQuery( $sql );
  public function getResults();
}

?>


Vervolgens kan je een object deze interface laten implementeren:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
<?php
class MySQL_Connection_Class implements Connection_Interface{
 
  private $host;
  private $username;
  private $password;
 
  public function __construct( $host, $username, $password ){
    $this->host = $host;
    $this->username = $username;
    $this->password = $password;
  }


  public function connect(){
    //make the connection
  }

  public function isConnected(){
    //check if there is a connection, return a boolean
  }

  public function disconnect(){
    //close the db connection
  }

  public function executeQuery( $sql ){
    //execute the given query
  }

  public function getResults(){
    //return the results from the last executed query
  }
}

?>


Als je nu vervolgens een database class hebt die voor de rest van de applicatie alle database interactie verzorgt, dan kan je daarin een connection setter maken waarbij je via typehinting afdwingt dat het connection object ook echt de juiste interface implementeert.
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
<?php
class Database_Class{

  private $connection;

  public function setConnection( Connection_Interface $obj ){
    $this->connection = $obj;
  }
}

?>

Als je nu in die setter een object meegeeft dat de Connection_Interface niet implementeert, dan zal je een runtime error krijgen.
Gewijzigd op 11/06/2012 09:50:05 door Erwin H
 
Reshad F

Reshad F

11/06/2012 10:35:35
Quote Anchor link
oke, erwin zoals ik het nu begrijp volgens mij. dan heb ik zoiets?

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
<?php
interface Connection_Interface
{
  public function __construct($hostname, $username, $pass, $database, $table, $connector);
  public function openConnect();
  public function pingServer();
  public function closeConnect();
  public function startQuery( $sql );
  public function getResults();
}

?>


vervolgens maak ik een class die deze implementeert. dat wordt dan de databaseConnect iets zoals.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
63
64
65
66
67
<?php
class databaseConnect implements Connection_Interface
{
    /**
     * declareren van alle functies
     */

    private $hostname;
    private $username;
    private $pass;
    private $database;
    private $table;
    private $connector;

    public function __construct($hostname, $username, $pass, $database, $table, $connector)
    {

        $this->databaseConfig = $databaseConfig;
    }


    public function __destruct()
    {

        #destroy function
    }

    // open connectie
    public function openConnect()
    {

        try
        {
            if($this->databaseConfig->connector == "mysql")
            {

                $this->openConnect = mysql_connect($this->databaseConfig->hostname, $this->databaseConfig->username, $this->databaseConfig->pass);
                $this->databaseConnect = mysql_select_db($this->databaseConfig->database);
            }    
        }

        catch (Exception $e)
        {

            return $e;
        }
        
    }


    #run een query
    public function startQuery($runQuery)
    {
        
    }


    #sluit connectie
    public function closeConnect()
    {
        
    }


    /*
    * ping server om te zien of deze open verbinding heeft.
    */

    public function pingServer()
    {
        
        }


    public function getResults()
    {
        
    }
}

?>


ga ik zo de goede kant op hiermee?

Toevoeging op 11/06/2012 10:39:19:

en hier even hoe ik de volledige code heb met deze gedachte van die implement ( het is natuurlijk niet goed nog ) maar even om te zien hoe ik het heb.

http://pastebin.com/xZ9E0jML
Gewijzigd op 11/06/2012 10:37:06 door Reshad F
 
Erwin H

Erwin H

11/06/2012 10:47:57
Quote Anchor link
Je gaat de goede kant op, alleen moet je dit niet doen:
if($this->databaseConfig->connector == "mysql")

Het hele idee van het op deze manier opbouwen is dat je de verschillende databases (en verschillende technische methodes om ze aan te roepen) scheidt in verschillende connectie classes. Dus je hebt een class voor mysql, je hebt een class voor DB2, voor Oracle etc. En als je mysql_, mysqli_ en pdo wilt gebruiken heb je daar ook ieder een class voor. Binnen de connectie class gebruik je dus altijd maar 1 van die technieken en hoef je dus nooit te checken welke je gebruikt.
 
Reshad F

Reshad F

11/06/2012 11:38:46
Quote Anchor link
ja dat snap ik nu :) ik twijfelde er zelf ook al over. heb nu die controle weggehaald.

nu heb ik een klein vraagje. ik heb nu dus

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
interface Connection_Interface
{
}


class databaseConnectMySql implements Connection_Interface
{
}


// en

class databaseConfig
{
}

?>


maar wat is nu die class databaseConfig in dit geval? hoort dit een abstract class te zijn? want de gegevens ervan ( om een verbinding tot stand te brengen ) wordt pas later gegeven toch? en blijft dit dan een standalone class of moet deze extend worden?
Gewijzigd op 11/06/2012 11:44:03 door Reshad F
 
Erwin H

Erwin H

11/06/2012 13:49:39
Quote Anchor link
Als je databaseConfig als class wilt instantieren dan kan het geen abstracte class zijn. Als je het echter als superclass wilt gebruiken zoals Wouter aangaf en pas in afgeleide classes de functionaliteit wilt completeren dan zou ik er wel een abstracte class van maken. Op die manier voorkom je dat deze class op zichzelf gebruikt kan worden.

Of je het moet extenden of niet is geen antwoord op te geven. Dat ligt totaal aan hoe je er verder mee wilt werken.
 

Pagina: 1 2 3 4 volgende »



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.