首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PHP:如何重用代码(oop)?

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

Stack Overflow用户
提问于 2010-09-14 00:12:22
回答 5查看 3.1K关注 0票数 4

我在php oop中学习过,并且积累了可重用代码的概念。

我见过这样的例子

代码语言:javascript
复制
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接口中添加一个新函数时,我的模板类也需要更改。我不理解“重用”的概念。我很感谢你的帮助。谢谢。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2010-09-14 00:39:14

接口不直接用于代码重用。它们是用于抽象的。它们使使用模板的类能够检查接口,而不是基模板类。这样,它将实现从接口声明中分离出来。

因此,如果您的方法对template类执行某些操作,则检查实例template的对象将对该类的依赖项进行硬编码。但实际上,您并不关心您获得了什么类,您只关心它是否符合iTemplate接口(因为这就是您所调用的全部)。

代码语言:javascript
复制
public function foo(Template $template) {

vs:

代码语言:javascript
复制
public function foo(iTemplate $template) {

现在,就代码重用而言,接口实际上并不是为此而设计的。继承通常是。基本上,可以将继承看作是对抽象的扩展。让我给你举个例子:

如果您要为鸟创建一组类,则可以使用继承或不使用继承来处理它。让我们看看如何在没有以下代码的情况下完成此操作:

代码语言:javascript
复制
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)……

让我们看看使用单层继承时会是什么样子:

代码语言:javascript
复制
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(),因为它总是会被覆盖(因为没有两只鸟的发音是一样的)。

听起来不错,对吧?嗯,根据我们的需要,我们可能想要添加其他抽象类型。所以假设我们制造了许多不同类型的鸟。我们可能会有一些不能游泳的类,因此我们可能会创建一个扩展Bird的抽象类NonSwimmingBird,但是会为我们抛出异常。或者NonFlyingBird或者ShortRangeBird..。

现在,我们真的在代码重用的轨道上,但我们在另一个领域遇到了障碍。假设我们有一只不会飞也不会游泳的鸟。我们从哪个类继承?无论哪种方式,我们都是在复制代码。所以我们得另找出路。那我们该怎么做呢?通过Design Patterns。我们可以使用装饰器模式来动态添加这些特征,而不是直接继承。(这里还可以使用其他模式,重点是说明仅继承并不能满足所有需求。单靠模式也不行。你需要一个好的架构,根据你的确切需求使用两个世界)……

关键是,这完全取决于你的需求。如果你只有两个“类”的对象,你将会设计一些比你计划拥有数千个对象要简单得多的东西。我在这里写的重点是演示如何使用直接继承来强制执行一些枯燥的原则(但是直接继承也会导致代码重复)。最重要的是,不要仅仅因为你不想重复自己就坚持干下去。坚持DRY,但要确保在合理的地方组合和扩展,否则你会给自己带来一个令人头疼的维护问题。坚持Single Responsibility Principal,你应该没问题的.

票数 8
EN

Stack Overflow用户

发布于 2010-09-14 00:16:49

接口在开发开始时只写入一次。只有在此之后,才能编写此接口的其他类实现。接口-是一个基础。注意:方法setVariable不是必需的。在PHP中有一些很好的神奇方法,比如__get()__set()

票数 0
EN

Stack Overflow用户

发布于 2010-09-14 00:18:47

当你想要一些东西是可互换的时,接口通常是有用的。想象一下,你会构建一个插件感知的应用程序。然后您就有了接口iPlugin:

代码语言:javascript
复制
interface iPlugin {
   public function init();
   /* .. */
}

所有的插件都会实现这个接口。然后,插件管理器可以很容易地检查插件是否实现了该接口,并对其调用init()方法。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3702248

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档