我经常提出以下案例,我不确定这是否是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个单独的文件中,并使用一个简单的数组......好吧......数组非常简单。
但我想知道的是......对于这个问题,有没有“最佳实践”? 任何模式?你会建议什么?
答案 0 :(得分:2)
鉴于这两种方法都有效,它归结为可读性和实用性。我个人认为第一种方法更加用户友好。您可以轻松地在给定的数组中看到水果与其属性之间的关系。
我可能会看到的唯一问题是,如果添加更多属性,类可能会变得太大,并且可能会使Fruits类中的其他变量和函数相形见绌。您也可以创建另一个用于存储规则的类:
class Fruit extends Rules {//...
然后让你的水果类扩展它:
$('#GameType').append($('<option>', {
value: 'All',
text: 'All'
}));
这会给你带来两个好处:
清洁代码。
如果由于某种原因将来你需要在另一个班级中使用这些规则,你也可以简单地扩展它。