接口是不能直接用于代码重用。他们是为了抽象。它们启用使用该模板的类来检查接口而不是基本模板类。这样它就将接口声明中的实现分开了。
因此,如果您的方法对template
类执行了某些操作,那么检查实例template
的对象将难以编码对该类的依赖性。但事实上,你并不在乎你得到的是什么课程,你只是在乎它是否遵守了界面(因为这就是你所打的所有东西)。
public function foo(Template $template) {
VS:
public function foo(iTemplate $template) {
现在,只要代码复用,接口是不是真的设计了点。继承通常是。基本上认为继承是扩展抽象。让我举个例子:
如果你要为鸟类创建一组类,你可以通过继承来处理它,如果没有它的话。让我们来看看我们如何做到这一点没有:
interface iBird {
public function fly();
public function speak();
public function swim();
public function walk();
}
class Duck implements iBird {
public function fly() {
//Fly here
}
public function speak() {
// Quack here
}
public function swim() {
//Swim here
}
public function walk() {
//Walk here
}
}
class Turkey implements iBird {
public function fly() {
//Fly here, but limited
}
public function speak() {
//Make turkey sound here
}
public function swim() {
throw new Exception('Turkeys can not swim!');
}
public function walk() {
//Walk here
}
}
现在,这是一个简单的例子,但是你可以看到,在这两个鸟,walk()
功能将可能是相同的(并因此违反DRY)...
让我们来看看如何看起来与单层继承:
abstract class Bird implements iBird {
public function fly() {
//Fly here
}
abstract public function speak();
public function swim() {
//Swim here
}
public function walk() {
//Walk here
}
}
class Duck extends Bird {
public function speak() {
//Quack here
}
}
class Turkey extends Bird {
public function speak() {
//Make turkey sound here
}
public function swim() {
throw new Exception('Turkeys can not swim!');
}
}
现在,你可以看到,我们只是重新使用的方法3!我们没有声明speak()
,因为它会一直被覆盖(因为没有两只鸟听起来一样)。
听起来不错吧?那么,根据我们的需要,我们可能需要添加其他抽象类型。因此,我们可以说我们制作了许多不同类型的鸟类......我们会有一些不会游泳的,因此我们可能会创建一个抽象类NonSwimmingBird
,它扩展Bird
,但是会为我们引发异常。或者NonFlyingBird
或ShortRangeBird
...
现在,尽管代码重用,但我们在其他区域遇到了问题。假设我们有一只不会飞翔或游泳的鸟。我们继承什么课程?无论哪种方式,我们都在复制代码。所以我们需要找到另一条出路。那么,我们该怎么做呢?通过Design Patterns ...我们可以使用装饰器模式来实时添加这些特征,而不是直接继承。 (还有其他的模式可以用在这里,重点是要证明单独的继承并不适合所有的需求,单独的模式也不会,你需要一个好的架构来根据你的确切需求来使用两个世界) ...
问题是,这一切都取决于您的需求。如果你只有2个“班级”的对象,那么你将构建一个比如果你计划拥有数千个更简单的东西。我写在这里的目的是为了演示如何使用直接继承来实施一些DRY主体(但也包括直接继承如何导致代码重复)。最重要的是,不要因为你不想重复自己而坚持DRY。坚持DRY,但要确保你在合理的地方进行组合和扩展,否则你会造成自己的维护头痛。坚持Single Responsibility Principal,你应该没问题...
你能告诉我你在哪里找到那个代码吗?我正处于学习阶段,我希望通过实例学习。 – dole 2011-02-25 18:27:04