【问题标题】:Is this PHP pseudo-DI pattern wrong / dangerous?这个 PHP 伪 DI 模式是错误的/危险的吗?
【发布时间】:2018-04-27 12:58:08
【问题描述】:

我有一个类,VehicleManager。 此类管理车辆类型对象的生命周期和调用。 Vehicles 充当模块并扩展了抽象的 Vehicle 基类。

所以,如果你制作一辆自行车,你永远不会做 new Bike(),你会做 VehicleManager->create('Bike',5);

我的问题是,我希望每辆车的构造都接收预定义的参数,并执行一些预定义的操作,所以我的 Vehicle 基类有一个私有的最终构造函数。

例子:

final private function __construct(Array $myCustomData){
  $this->customData = $myCustomData;
}

但我仍然希望每种车辆类型都有一些自定义初始化

所以做了之后

$newVehicle = new $ClassName($myCustomData);

我在做

$newVehicle->initialize(); 

这可以接受吗?谢谢

【问题讨论】:

  • 你知道你可以覆盖__construct 并且仍然调用基本实现吗? stackoverflow.com/questions/1557608/…
  • 您能详细说明一下吗? __construct 方法在我的基类中是最终的。我正在检查提供的类是否事先扩展了它。
  • 好吧,你可以让它不是最终的......我链接的问题包含很多关于这个的想法。我只是想我会把它作为替代品,这可能适合您的需求。

标签: php oop design-patterns dependency-injection constructor


【解决方案1】:

您可以在项目中使用多种模式来生成车辆,看看 AbstractFactory 或 FactoryMethod。可以根据您的程序上下文使用它们。这是 AbstractFactory 示例:

// Vehicle classes
class Vehicle
{
};

class Car extends Vehicle
{
};

class Bike extends Vehicle
{
};

//Abstract factory classes
abstract class VehicleFactory
{
    abstract protected function GetVehicle( $customData );
};

class CarFactory extends VehicleFactory
{
    public function GetVehicle( $customData )
    {
        //Do special init
        return new Car();
    }
};

class BikeFactory extends VehicleFactory
{
    public function GetVehicle( $customData )
    {
        //Do special init
        return new Bike();
    }
};
//Program context classes
class RaceTrack
{
    public function GenerateRacers( VehicleFactory $factory )
    {
        //$factory->GetVehicle(array());
    }
    public function AddRacers( Vehicle $vehicle )
    {
    }
};
$CarFact = new CarFactory();
$RaceTrack = new RaceTrack();
$RaceTrack->GenerateRacers($CarFact);

这是工厂方法的示例:

//Factory method pattern
class VehicleFactory2
{
    const BIKE_TYPE = 0;
    const CAR_TYPE = 1;

    public function GetVehicle( $type, $customData )
    {
        if ( $type == self::BIKE_TYPE )
        {
            return new Bike($customData);
        }
        else if ( $type == self::CAR_TYPE )
        {
            return new Car($customData);
        }

        return null;
    }
};

$VehicleFact = new VehicleFactory2();
$RaceTrack2 = new RaceTrack();
$RaceTrack2->AddRacers($VehicleFact->GetVehicle(VehicleFactory2::CAR_TYPE, array()));

DI 可以用作构造函数、方法、setter 注入。使用 DI 让您的项目更加灵活是一种很好的做法

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-25
    • 1970-01-01
    • 2010-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-17
    相关资源
    最近更新 更多