2

I have a task where I need to output an object of class Honda or BMW or Tesla, all of which extend the abstract class Car. The output should be based on what input is entered by the user, but no conditional statements are allowed in any part of the code (if-else, switch-case, ternary).

The input options are "Japan", "Germany" and "America", which should respectively output an object of Honda, BMW or Tesla.

What I did initially was try to use ternary operators, but I was told to rework it as ternary operators are still considered conditional.

hon = new Honda;
bmw = new BMW;
tes = new Tesla;

newH = hon->objectify();
newB = bmw->objectify();
newT = tes->objectify();

myCar = newH ?: newB ?: newT;
return myCar;

This was what I did, where objectify() is basically an abstract function implemented differently by each child class, returning null if the input doesn't match, or an object of itself if the input matches.

This submission was rejected. Please what's a better way to make this work?

ADyson
  • 57,178
  • 14
  • 51
  • 63
Lucky Uche
  • 21
  • 5
  • Perhaps your instructor wants you to implement the [Bridge pattern](https://designpatternsphp.readthedocs.io/en/latest/Structural/Bridge/README.html?highlight=printer). – Álvaro González Sep 23 '22 at 12:15

2 Answers2

1

So make use of associative arrays then like below based on your input and use your input as the key.

<?php

$input = "Japan";

$map= ["Japan" => new Honda(), "Germany" => new BMW(), "America" => new Tesla()];

return $map[ $input ]->objectify();
nice_dev
  • 17,053
  • 2
  • 21
  • 35
  • 2
    That creates instances of _all three_ classes, when only one is actually needed - not very efficient. – CBroe Sep 23 '22 at 10:23
  • @CBroe But it is negligible, like say 25 ms instead of 5 ms. – nice_dev Sep 23 '22 at 10:24
  • We know _nothing_ about what these classes actually do. For all we know, they could each create a hundred database records on initialization, or create a 500 MB file ... (Construed examples, of course, but it should illustrate why this is not a very good way to go about it.) – CBroe Sep 23 '22 at 10:26
  • @CBroe _Constructed examples_ Exactly. I have never seen anyone do any heavy lifting inside a constructor. – nice_dev Sep 23 '22 at 10:31
1

You could use the value input by the user to look up which class to instantiate using an array to map from one to the other. For example:

$carTypes = array("Germany" => "BMW", "Japan" => "Honda", "America" => "Tesla");
$country = "Germany"; //replace this with actual user input, in your version

$car = new $carTypes[$country]();
$car->objectify();

Demo: https://3v4l.org/0WSLO

See also instantiate a class from a variable in PHP?

ADyson
  • 57,178
  • 14
  • 51
  • 63