我已经学习了php oop并且存储了可重用代码的概念.
我见过一个例子
interface iTemplate
{
public function setVariable($name, $var);
public function getHtml($template);
}
And implement it:
// Implement the interface
class Template implements iTemplate
{
private $vars = array();
public function setVariable($name, $var)
{
$this->vars[$name] = $var;
}
public function getHtml($template)
{
foreach($this->vars as $name => $value) {
$template = str_replace('{' . $name . '}', $value, $template);
}
return $template;
}
}
Run Code Online (Sandbox Code Playgroud)
我可以理解代码,但不确定为什么它可以重用.每次我想在iTemplate界面中添加新功能时,我的Template类也需要更改.我不理解"重用"的概念.我感谢任何帮助.谢谢.
接口不直接用于代码重用.它们用于抽象.它们允许使用模板的类检查接口而不是基本模板类.这样它将实现与接口声明分开.
因此,如果您的方法对template类执行某些操作,则检查实例对象template将难以编写对该类的依赖关系.但实际上你并不关心你得到什么课程,你只关心它是否坚持iTemplate界面(因为你无论如何都是这样).
public function foo(Template $template) {
Run Code Online (Sandbox Code Playgroud)
VS:
public function foo(iTemplate $template) {
Run Code Online (Sandbox Code Playgroud)
现在,就代码重用而言,接口并不是真的为此而设计的.通常是继承.基本上认为继承是扩展抽象.让我给你举个例子:
如果你要为鸟类创建一组类,你可以用继承方法来处理它,没有它.让我们看看如何在没有:
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
}
}
Run Code Online (Sandbox Code Playgroud)
现在,这是一个简单的例子,但你可以看到,在这两只鸟中,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!');
}
}
Run Code Online (Sandbox Code Playgroud)
现在,你可以看到我们只是重复使用了3种方法!我们没有声明speak(),因为它总是被覆盖(因为没有两只鸟听起来相似).
听起来不错吧?那么,根据我们的需要,我们可能想要添加其他抽象类型.所以我们假设我们制作了许多不同类型的鸟......我们会有一些不会游泳的东西,所以我们可能会创建一个NonSwimmingBird扩展的抽象类Bird,但会为我们抛出异常.或者a NonFlyingBird或者ShortRangeBird......
现在,就代码重复使用而言,我们确实在轨道上,但我们正在另一个领域碰壁.假设我们有一只不会飞或游泳的鸟.我们从哪个班继承?无论哪种方式,我们都在复制代码.所以我们需要找到另一条出路.那么,我们怎么做呢?通过设计模式 ...我们可以使用装饰器模式动态添加这些特征,而不是直接继承.(这里可以使用其他模式,重点是表明继承本身并不适合所有需求.而模式本身也不会.你需要一个基于你的确切需求的两个世界的良好架构) ...
关键是,这一切都取决于您的需求.如果你只有2个"类"的对象,那么你将要构建一些比你计划拥有数千个更简单的东西.我在这里写的内容是演示如何使用直接继承强制执行某些DRY主体(以及直接继承如何导致代码重复).最重要的是,不要因为你不想重复自己而坚持干.坚持干,但要确保你合并并延伸到合理的地方,否则你会让自己陷入困境.坚持单一责任校长,你应该没事......