PHP:如何重用代码(oop)?

时间:2010-09-13 16:12:22

标签: php oop

我已经在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;
    }
} 

我可以理解代码但不确定为什么它可以重用。每次我想在iTemplate界面中添加新功能时,我的Template类也需要更改。我不理解“重用”的概念。我感谢任何帮助。谢谢。

5 个答案:

答案 0 :(得分:6)

接口不直接用于代码重用。它们用于抽象。它们允许使用模板的类检查接口而不是基本模板类。这样它将实现与接口声明分开。

因此,如果您的方法使用template类执行某些操作,则检查实例template的对象将难以编写对该类的依赖关系。但实际上你并不关心你得到什么课程,你只关心它是否符合iTemplate界面(因为你无论如何都是这样)。

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,但抛出异常为了我们。或NonFlyingBirdShortRangeBird ...

现在,就代码重复使用而言,我们确实在轨道上,但我们正在另一个领域碰壁。假设我们有一只不会飞或游泳的鸟。我们从哪个班继承?无论哪种方式,我们都在复制代码。所以我们需要找到另一条出路。那么,我们怎么做呢?通过Design Patterns ...我们可以使用装饰器模式动态添加这些特征,而不是直接继承。 (这里可以使用其他模式,关键是要表明继承本身并不适合所有需求。而模式本身也不会。你需要一个基于你的确切需求的两个世界的良好架构) ......

重点是,这一切都取决于您的需求。如果你只有2个“类”的对象,那么你将要构建一些比你计划拥有数千个更简单的东西。我在这里写的内容是演示如何使用直接继承强制执行某些DRY主体(以及直接继承如何导致代码重复)。最重要的是,不要因为你不想重复自己而坚持干。坚持干,但要确保你合并并延伸到合理的地方,否则你会让自己陷入困境。坚持Single Responsibility Principal,你应该没事......

答案 1 :(得分:0)

接口在开发开始时只写入一次。并且只有在此之后才会编写此接口的其他类实现。界面 - 是一个基础。 注意:方法setVariable不是必需的。 PHP中有很好的法术方法__get()__set()

答案 2 :(得分:0)

在您希望某些内容可以互换的情况下,接口通常很有用。想象一下,您将构建一个支持插件的应用程序。然后你有了界面iPlugin:

interface iPlugin {
   public function init();
   /* .. */
}

并且所有插件都将实现该接口。然后,插件管理器可以轻松检查插件是否实现了接口并在其上调用init()方法。

答案 3 :(得分:0)

代码不需要是可重用的OO,尽管在许多情况下有帮助。

代码当然不需要使用可重用的接口,尽管在某些情况下会再次提供帮助。

编写可重用代码的关键是编写清晰编写,评论良好,使用一致命名和调用约定的代码,并且比手头的问题更加通用。

在PHP中编写可重用代码的最简单和最强大的技术之一是编写接受可变数量参数的方法,或接受参数的关联数组。

通常,没有开始“打算”可重用的代码原来是你想要重用的东西。通常,代码开始“内联”,然后您发现您需要在多个地方完全或几乎完全相同的事情。当您发现自己复制并粘贴代码时,就应该将其重构为函数。

同样地,当你发现自己希望在文件X中定义的函数在文件Y中真的有用时,是时候将它移动到模块中了。

学习这一切的最佳方式是通过经验。有些人会告诉你从一开始就设计这些东西,如果你有这样的洞察力和经验,这当然是个好主意,但是从下到上这样做也是有效的,这可能是最好的方法。学习。

答案 4 :(得分:0)

面向对象编程的可重用性是在当前类中使用先前的类或函数或方法,但没有前一类的问题。