Ik worstel een beetje met het ontwerp van een paar klassen die ik aan het programmeren ben.
Om (HTML-)tabellen te genereren, heb ik een GridBuilder bedacht. Deze GridBuilder itereert over een verzameling gegevens en maakt voor iedere iteratie een Row aan. Voor iedere Row wordt er over een verzameling RowTransformer's geïtereerd. Zo'n RowTransformer voegt bijvoorbeeld één of meerdere kolommen aan de Row toe of verbergt of highlight de Row. Het eindresultaat is een Grid met Row's die Column's bevatten.
Dit is de (ingekorte) code van de GridBuilder:
Iedere RowTransformer is opgebouwd volgens een contract:
Zo ziet een concrete RowTransformer eruit:
So far geen problemen. Echter, nu heb ik deze specifieke UsersGridBuilder gemaakt:
Er is nu ook een UsersRowTransformer-interface om af te dwingen dat er een User-object wordt meegestuurd:
Dit is dus waar m'n problemen beginnen. Ik kan nu namelijk niet meer m'n generieke RowTransformer's gebruiken, zoals bijvoorbeeld een spacer.
Nu had ik zelf een twee mogelijke oplossingen bedacht:
Om (HTML-)tabellen te genereren, heb ik een GridBuilder bedacht. Deze GridBuilder itereert over een verzameling gegevens en maakt voor iedere iteratie een Row aan. Voor iedere Row wordt er over een verzameling RowTransformer's geïtereerd. Zo'n RowTransformer voegt bijvoorbeeld één of meerdere kolommen aan de Row toe of verbergt of highlight de Row. Het eindresultaat is een Grid met Row's die Column's bevatten.
Dit is de (ingekorte) code van de GridBuilder:
PHP:
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
| <?php class GridBuilder { private $rowTransformers; public function addRowTransformer(RowTransformer $rowTransformer) { $this->rowTransformers[] = $rowTransformer; } public function build(array $dataItems) { $grid = new Grid(); foreach($dataItems as $dataItem) { $row = new Row(); foreach($this->rowTransformers as $rowTransformer) { $rowTransformer->transformRow($dataItem, $row); } $grid->addRow($row); } return $grid; } } |
Iedere RowTransformer is opgebouwd volgens een contract:
PHP:
1
2
3
4
5
6
| <?php interface RowTransformer { public function transformRow($dataItem, Row $row); } |
Zo ziet een concrete RowTransformer eruit:
PHP:
1
2
3
4
5
6
7
8
9
| <?php class TextRowTransformer implements RowTransformer { public function transformRow($dataItem, Row $row) { $row->addColumn(new TextColumn($dataItem)); } } |
So far geen problemen. Echter, nu heb ik deze specifieke UsersGridBuilder gemaakt:
PHP:
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
| <?php class UsersGridBuilder extends GridBuilder { private $rowTransformers; public function addRowTransformer(UsersRowTransformer $rowTransformer) { $this->rowTransformers[] = $rowTransformer; } public function build(array $users, array $rowTransformers) { $grid = new Grid(); foreach($users as $user) { $row = new Row(); foreach($this->rowTransformers as $rowTransformer) { $rowTransformer->transformRow($user, $row); } $grid->addRow($row); } return $grid; } } |
Er is nu ook een UsersRowTransformer-interface om af te dwingen dat er een User-object wordt meegestuurd:
PHP:
1
2
3
4
5
6
| <?php interface UsersRowTransformer extends RowTransformer { public function transformRow(User $user, Row $row); } |
Dit is dus waar m'n problemen beginnen. Ik kan nu namelijk niet meer m'n generieke RowTransformer's gebruiken, zoals bijvoorbeeld een spacer.
Nu had ik zelf een twee mogelijke oplossingen bedacht:
- De specifieke UsersRowTransformer's schrappen en iedere RowTransformer een 'universele' $payload meegeven. De RowTransformer moet dan zelf maar uitvogelen of het de correcte data heeft meegekregen.
- Een Spacer maken die de interface UsersRowTransformer implementeert. Lijkt me vrij lelijk.