Php 如何在不牺牲依赖注入的情况下简化API?

Php 如何在不牺牲依赖注入的情况下简化API?,php,oop,dependency-injection,Php,Oop,Dependency Injection,假设我有一个矩形类。要使用它,我会: $rectangle = new Rectangle( 100, 50, new Color('#ff0000') ); 然而,由于这将是一个公共API,我希望尽可能为最终用户简化它。最好只接受十六进制字符串: $rectangle = new Rectangle( 100, 50, '#ff0000'); 现在的问题是,我需要在矩形类中实例化Color对象 class Rectangle { protected $width; pro

假设我有一个矩形类。要使用它,我会:

$rectangle = new Rectangle( 100, 50, new Color('#ff0000') );
然而,由于这将是一个公共API,我希望尽可能为最终用户简化它。最好只接受十六进制字符串:

$rectangle = new Rectangle( 100, 50, '#ff0000');
现在的问题是,我需要在矩形类中实例化Color对象

class Rectangle {

    protected $width;
    protected $height;
    protected $fillColor;

    function __construct( $width, $height, $fillColor ){
        $this->width = $width;
        $this->height = $height;
        $this->fillColor = new Color( $fillColor );
    }
}

学习依赖注入后,这被认为是不好的。还是这样?最好的方法是什么?

我将使用一个工厂类,它接受(可能)参数数组并返回已实例化的矩形对象。根据您的设计和API规范,有许多可能实现这一点

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;
    }
}
此外,根据您的需要和设计,您可以在
工厂方法
抽象工厂
之间进行选择。假设您有一个
接口GeometricalShape
类矩形实现GeometricalShape
以及
类圆形实现GeometricalShape
,第一次您可以使用

class MyApiFactory
{
    public static function createRectangle(array $params) { /*...*/ }
    public static function createCircle(array $params) { /*...*/ }
}


使用工厂如何,它将实例化颜色并将其传递给矩形的构造函数。然后API的调用者只需要传递参数。我来这里也是这么说的。
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;
        }

    }
}