应用程序体系结构-何时为对象的属性值使用单独的类?

时间:2018-11-16 14:04:02

标签: php design-patterns

让我们留下两个对象,如下所示:

class State {
    const FRIENDLY = 1;
    const ANGRY = 2;
    const SAD = 3;
}

class Dog
{
    public $state_id;
}

// Usage
$dog = new Dog();
$dog->state_id = State::FRIENDLY;

注意: State对象可能会获得更多值,但可能性很小。

State对象将仅与Dog对象一起使用(请参见用法示例)。

您会编写类似 above 还是类似以下 的代码:

class Dog
{
    const STATE_FRIENDLY = 1;
    const STATE_ANGRY = 2;
    const STATE_SAD = 3;

    public $state_id;
}

// Usage
$dog = new Dog();
$dog->state_id = Dog::STATE_FRIENDLY;

请说明您的选择。

1 个答案:

答案 0 :(得分:0)

方法很多,一切都取决于您要遵循的应用程序和体系结构。

如果您要在不同的对象之间共享相同的状态(例如,您可以拥有不同的动物,比如说Cat,而Cat也可以友好/愤怒/悲伤->则完全有道理拥有一个具有所有可能的动物状态的State类。

在您的情况下,我不会$dog->state_id = ....,这很容易出错,因为任何人都可以分配任何东西。相反,最好使用三个函数集($dog->setAngry()$dog->setSad()$dog->setFriendly()),或者如果您有多个状态,例如$dog->setState($state);setState可以验证您是否传递了正确的参数(验证它是....之一)。

简而言之,如果这些常量只有一个使用者(在您的示例中为Dog),那么我就不用费心创建一个单独的类。当我有多个使用者时,我会考虑作为一个单独的类/接口或抽象类是否有意义。如果仅我的代码将使用这些常量(例如DogCat),则很可能会去一个抽象类。 如果我正在编写一个用于连接服务器的库,而其他一些用户将要使用该库(那么这些常数将同时由我的库和其他人的代码使用),我会将它们写为单独的文件/实例),以便例子

$request = MyLibrary\RequestBuilder::makeRequest($url);
if ($request->getStatus() == MyLibrary\Request::FAILED) {
    // handle failed request
}

在这种情况下,Request将是一个具有所有可能状态的接口,并且 用户不必考虑RequestBuilder返回哪个具体类,我只知道我可以使用Request界面来查找如何处理我得到的对象。

还有另一件事,有一个名为https://github.com/myclabs/php-enum的PHP插件,如果要使用它,您将内置验证,而恕我直言,为状态创建一个不同的类完全有意义,类似:

class DogState extends Enum {
    const FRIENDLY = 1;
    const ANGRY = 2;
    const SAD = 3;
}
class Dog {
    private $state_id;
    public function setState( DogState $state) {
        $this->state_id = $state;
    }
}

$dog->setState( DogState::FRIENDLY() );

对我来说,这是语法糖,我更喜欢使用纯PHP,但我知道有人喜欢这种方式。