I'm struggling with a few classes I'm designing. To generate (HTML) tables, I came up with a GridBuilder. This GridBuilder loops through a collection of items and creates a Row for each iteration. For each Row the code iterates over a collection of RowTransformer's. A RowTransformer adds one or more columns to a Row or highlights or hides the Row, for example.The result is a Grid with Row's that contains Column's.This is the (shortened) code of GridBuilder:<?phpclass 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;    }}Each RowTransformer must conform to this interface:<?phpinterface RowTransformer{    public function transformRow($dataItem, Row $row);}This is what a concrete RowTransformer looks like:<?phpclass TextRowTransformer implements RowTransformer{    public function transformRow($dataItem, Row $row)    {        $row->addColumn(new TextColumn($dataItem));        return $row;    }}So far so good. However, now I created this specific UserGridBuilder:<?phpclass 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 ($rowTransformers as $rowTransformer) {                $rowTransformer->transformRow($user, $row);            }            $grid->addRow($row);        }        return $grid;    }}I created a UsersRowTransformer-interface to enforce that each implementation has a User-object at its disposal:<?phpinterface UsersRowTransformer extends RowTransformer{    public function transformRow(User $user, Row $row);}This is where I run into trouble. I can't use my specific RowTransformer's anymore, such as a spacer.I came up with two possible solutions:Getting rid of UserRowTransformer's and using a generic $payload for each RowTransformer. Each RowTransformer can then figure out for themselves if the payload contains what they need and throw an InvalidArgumentException if they got send wrong data.Making a Spacer that implements UsersRowTransformer. Seems like a shitty solution.Neither of these solutions seems ideal to me. Can anyone suggest a better design?
Designing a specific class and using generic components
object oriented;php;object oriented design;class design;solid