为什么将依赖性与业务对象联系起来是错误的?

时间:2015-06-29 15:21:10

标签: php dependency-injection inversion-of-control separation-of-concerns

一般来说,有人告诉我应该注入依赖关系。这种担忧应该分开。应该颠倒那种控制。但为什么呢?

例如,如果我们使用关注点分离但不进行控制反转,该怎么办?为什么这么错?即请参阅下面的代码进行讨论..

class BusinessFunctionality
{
    public $motor;
    function doStuff()
    {
        //i.e. at creation time we are not injecting data 
        //into motor.  We create empty motor then set data to it later
        $this->motor = new Motor();

        //motor loads data into itself
        $this->motor->loadMotor(); 
    }
}

class Motor
{
    public $motorData;
    function loadMotor()
    {
        $motorData = new MotorData();

        //MotorData is another class created to 
        //separate concerns of Motor functionality 
        //from database details

        //we load up data acquired by MotorData, into Motor
        $this->motorData = $motorData->loadMotor();
    }
}


class MotorData
{
    function loadMotor()
    {
        //mock Database
        $type = "industrial";//$db->query("SELECT... FROM .. ");
        return $type;
    }
}

//invocation
$business = new BusinessFunctionality();
$business->doStuff();
print "Motor type is " . $business->motor->motorData;

问题:哪种问题会使上述方法容易出现问题?

DataMapper Pattern

为了进行比较,如果我使用依赖注入和控制反转以及关注点分离,我会采用更加倡导的方式,我已经实现了DataMapper模式,看起来像这样:

//business object
class MyMotor
{
    private $data;

    function __construct(MotorDataType $data)
    {
        $this->data = $data;
    }

    function getType()
    {
        return $this->data->getType();
    }

}

//data mapper object
class MyMotorMapper
{
    function getMotorWithData()
    {
        //get data. i.e from whatever source
        $data = (new DatabaseMock())->getData();

        //inject data into the object
        $motor = new MyMotor($data);

        //return motor to the caller
        return $motor;
    }
}

class MotorDataType
{
    private $motorType;

    function getType()
    {
        return $this->motorType;            
    }

    function setMotorType($type)
    {
        $this->motorType = $type;
    }
}


//database object
class DatabaseMock
{
    function getData()
    {
        $data = new MotorDataType();
        $data->setMotorType("industrial");
        return $data;
    }
}

//invocation
$motor = (new MyMotorMapper())->getMotorWithData();    
print "Motor type is " . $motor->getType();

我不完全确定我喜欢它的结果,但它展示了我试图展示的原则(DI,SOC,IofC)

0 个答案:

没有答案