【问题标题】:Using a class to store constant values使用类来存储常量值
【发布时间】:2015-06-19 21:33:53
【问题描述】:

是否有更好的方法来存储以下示例所需的值。将字符串传递给工厂方法时,我试图避免任何可能的错误。

但是,这有什么问题吗?它是否易于测试,是否有更好的方法来实现相同的目标等。

abstract class Types
{
    const Car = 'car';
    const Boat = 'boat';
    const Bike = 'bike';
}

class VehicleFactory {

    public function make($type) 
    {
        if ($type === Types::Car) {
            // create new car
        }
        if ($type === Types::Boat) {
            // create new Boat
        }
        if ($type === Types::Bike) {
            // create new Bike
        }
    }
}

class Client
{
    public function createACar()
    {
        $vehicleFactory = new VehicleFactory();
        $car = $vehicleFactory->create(Types::Car)
    }
}

【问题讨论】:

  • 枚举是这里的正确选择。

标签: design-patterns constants factory


【解决方案1】:

这看起来像是一个与语言无关的问题,所以我假设像使用 enum 而不是 abstract 类这样的建议是行不通的。

您使用常量来表示创建的对象类型的方法是正确的。如果我必须更改任何内容,那将是您的 Client 类使用 VehicleFactory 以便在对您的代码进行单元测试时提供测试替身的方式:

class Client
{

    private $factory;

    public function __construct($factory){
        $this->factory = $factory;
    }    

    public function createACar()
    {
        $car = $factory->create(Types::Car)
    }
}

现在您可以传入VehicleFactory(比如VehicleMockFactory)的子类,它可以创建测试替身而不是创建实际对象:

class VehicleMockFactory extends VehicleFactory {

    public function make($type) 
    {
        if ($type === Types::Car) {
            // create new TestCar
        }
        if ($type === Types::Boat) {
            // create new TestBoat
        }
        if ($type === Types::Bike) {
            // create new TestBike
        }
    }
}

在单元测试时,您可以将VehicleMockFactory 传递给Client,而不是实际的VehicleFactory

【讨论】:

  • 是否也应该将 Types 类作为依赖项传递给工厂的构造函数?
  • 不,这不是必需的。 Types 本身不是依赖项。它没有任何行为,只定义了可以全局访问的常量。
猜你喜欢
  • 2019-02-19
  • 1970-01-01
  • 1970-01-01
  • 2011-11-26
  • 2013-04-06
  • 1970-01-01
  • 2014-04-20
  • 2017-05-26
  • 1970-01-01
相关资源
最近更新 更多