How can I simplify the API without sacrificing dependency injection?
Let's say I have a Rectangle class. To use it, I would do:
$rectangle = new Rectangle( 100, 50, new Color('#ff0000') );
However, since it will be a public API, I want to keep it as simple as possible for end users. Preferably it will just accept the sixth line:
$rectangle = new Rectangle( 100, 50, '#ff0000');
Now the problem is I need to instantiate a Color object inside the Rectangle class
class Rectangle {
protected $width;
protected $height;
protected $fillColor;
function __construct( $width, $height, $fillColor ){
$this->width = $width;
$this->height = $height;
$this->fillColor = new Color( $fillColor );
}
}
Learning about dependency injection is considered bad. Or that? What's the best approach?
source to share
I would use a factory class that takes an array of (possibly) arguments and returns a finished Rectangle object instance. There are many possibilities for how to do this, depending on your design and API specification.
class MyAPIFactory
{
public function createRectangle($params)
{
// do some checks of the params
$color = new Color($params['color']);
Rectangle = new Rectangle($params['width'], $params['height'], $color);
return $color;
}
}
Further, depending on your needs and design, you can choose between Factory Method
or Abstract Factory
. Let's say you have interface GeometricalShape
and class Rectangle implements GeometricalShape
and also class Circle implements GeometricalShape
for the first you can use something like
class MyApiFactory
{
public static function createRectangle(array $params) { /*...*/ }
public static function createCircle(array $params) { /*...*/ }
}
or
abstract class ShapeFactory
{
/**
* @return GeometricalShape
*/
abstract public function createInstance(array $params);
abstract protected function checkParams(array &$params);
}
class RectangleFactory extends ShapeFactory
{
public function createInstance(array $params)
{
// ...
}
protected function checkParams(array &$params)
{
if(empty($params['width'])) {
throw new Exception('Missing width');
}
if (empty($params['height'])) {
throw new Exception('Missing height');
}
// you could even make color optional
if (empty($params['color'])) {
$params['color'] = Color::DEFAULT_COLOR;
}
}
}
source to share