具有对象属性的预定义规则的php类

时间:2016-05-29 13:18:47

标签: php arrays oop attributes

我经常提出以下案例,我不确定这是否是OOP的好习惯。所以我想也许你可以帮我解决这个问题。

我将通过向水果篮添加水果的示例来简化这一点,例如:

$obj = new FruitBasket();
$obj->add(new Fruit('Banana'));
$obj->add(new Fruit('Apple'));
$obj->add(new Fruit('Kiwi'));
$obj->get();

“FruitBasket”类只是添加并输出数据:

class FruitBasket {
    private $fruits = [];

    public function add(Fruit $fruit)
    {
        $this->fruits[] = $fruit;
    }

    public function get()
    {
        foreach ($this->fruits as $fruit)
        {
            echo $fruit->get('type') .': '. $fruit->get('color') .' with '. ($fruit->get('seed') === true ? 'seeds.' : 'no seeds.') . '<br>';
        }
    }
}  

确定。 然后是“水果”课 - 这是我想要更好的练习的地方:

class Fruit {
    private $type;
    private $color;
    private $seed;
    // Is this cool(?):
    private $rules = [
        'Apple' => ['color' => 'red', 'seed' => true],
        'Banana' => ['color' => 'yellow', 'seed' => false],
        'Kiwi' => ['color' => 'green', 'seed' => true]
        // …
    ];

    public function __construct($type)
    {
        if (isset($this->rules[$type]))
        {
            $this->type = $type;
            $this->color = $this->rules[$type]['color'];
            $this->seed = $this->rules[$type]['seed'];
        }
    }

    public function get($attr = null)
    {
        if (isset($this->$attr) && !is_null($this->$attr))
            return $this->$attr;
    }
}

此类(Fruit)包含一个属性$rules,它是所有可能(或“允许”)水果的数组。在这个例子中只有3个,但在现实世界中它们也可能达到20个。该数组还包含每个水果的属性。属性不会改变,因为香蕉总是黄色的(让我们这样说)。所以这些属性是常量。 创建Fruit-object时,构造函数会设置所有这些属性。

所以我的问题是:拥有这一系列可能的水果及其属性是否合适?

...

我为每种类型的Fruit编写了Fruit类AND类的替代版本。在这里看到:

abstract class Apple {
    const color = 'red';
    const seed = true;
}

abstract class Banana {
    const color = 'yellow';
    const seed = false;
}

abstract class Kiwi {
    const color = 'green';
    const seed = true;
}

// …

class Fruit {
    private $type;
    private $color;
    private $seed;

    public function __construct($type)
    {
        $class = $type; // just to make it clear

        if (class_exists($class))
        {
            $this->type = $type;
            $this->color = $class::color;
            $this->seed = $class::seed;
        }
    }

    public function get($attr = null)
    {
        if (isset($this->$attr) && !is_null($this->$attr))
            return $this->$attr;
    }
}

这些类设置为“abstract”,因为我不想从它们创建对象。 (我知道(!)我可以使用Fruit-Class扩展那些Fruit-Classes,但是这并不适用于所有情况,这不是重点。) 我也不喜欢这个(第二个)版本,我需要为每个水果创建自己的文件(当使用自动加载...时)。

因此,如果我比较每个水果最多写20个类,再将它们放入20个单独的文件中,并使用一个简单的数组......好吧......数组非常简单。

但我想知道的是......对于这个问题,有没有“最佳实践”? 任何模式?你会建议什么?

1 个答案:

答案 0 :(得分:2)

鉴于这两种方法都有效,它归结为可读性和实用性。我个人认为第一种方法更加用户友好。您可以轻松地在给定的数组中看到水果与其属性之间的关系。

我可能会看到的唯一问题是,如果添加更多属性,类可能会变得太大,并且可能会使Fruits类中的其他变量和函数相形见绌。您也可以创建另一个用于存储规则的类:

class Fruit extends Rules {//...

然后让你的水果类扩展它:

$('#GameType').append($('<option>', {
    value: 'All',
    text: 'All'
}));

这会给你带来两个好处:

  1. 清洁代码。

  2. 如果由于某种原因将来你需要在另一个班级中使用这些规则,你也可以简单地扩展它。