我是一名Laravel开发者,虽然我已经使用它一段时间了,我喜欢它在表面下自动绑定实现的魔法,通过IoC容器实例化类时。但现在,我正在尝试回到设计模式的基础,并学习事物如何实际工作。
所以,我从动物示例开始:
abstract class Animal
{
abstract function makeSound();
}
class Dog extends Animal
{
public function makeSound()
{
echo "Bark!\n";
}
}
class Cat extends Animal
{
public function makeSound()
{
echo "Bark!\n";
}
}
我正在阅读《Head First设计模式》一书,并尽力充分利用这本书。在此时,每当我创建一个新的动物时,我都必须实现发出声音的方法,而这种方法在大多数情况下都是不同的。
因此,书中告诉我应该编写一个Soundable接口,并在Animal扩展类中实现该接口。
最终我得到了以下代码:
interface Soundable
{
function sound();
}
class Bark implements Soundable
{
public function sound()
{
return "Bark!\n";
}
}
class Meow implements Soundable
{
public function sound()
{
return "Meow!\n";
}
}
class Animal
{
public $soundable;
public function __construct(Soundable $soundable)
{
$this->soundable = $soundable;
}
public function makeSound()
{
echo $this->soundable->sound();
}
}
class Dog extends Animal
{
}
class Cat extends Animal
{
}
function makeAnimal(Animal $animal){
return $animal;
}
// Making a dog
$animal = makeAnimal(new Dog(new Bark()));
$animal->makeSound();
// Making a cat
$animal = makeAnimal(new Cat(new Meow()));
$animal->makeSound();
现在当我有另一个会叫或喵喵叫的动物时,我可以简单地实例化该实现并制作一个动物。
现在我的问题是如何告诉PHP在实例化Dog类时自动传递new Bark(),因为它会叫,我不想每次实例化新的Dog对象时都编写它。
所以我应该如何使用类似Laravel使用的魔法来自动传递Bark对象,同时实例化Dog。
PS:我仍在学习,如果您知道更好的方法,请指导我。
makeAnimal()
是不必要的。只需要这样做:$animal = new Dog(new Bark())
。因为你的函数只是返回它所接收到的东西,所以这两种方法是一样的。 - M. Erikssonnew Bark()
。每次调用该方法时,您将收到Dog
实例(而不是类),其中包含Soundable
对象实例,例如,在Dog
的情况下为Bark
。 - brzuchalDog
实例在运行时/请求时是否是单个的,并且具有某些责任,或者可能有很多Dog
实例,每个实例都代表自己(它们不相等)? - brzuchal