Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/255.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP:如何重用代码(oop)?_Php_Oop - Fatal编程技术网

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

PHP:如何重用代码(oop)?,php,oop,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 = ar

我学习过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接口中添加新函数时,我的模板类也需要更改。我不理解“重用”的概念。谢谢你的帮助。谢谢

接口在开发开始时只写入1次。只有在编写了其他类之后,才能实现这个接口。界面-是一个基础。
注意:方法setVariable不是必需的。PHP中有一些很好的神奇方法,如
\uuuu get()
\uu set()
,接口通常在您希望某些东西可以互换的情况下很有用。想象一下,您将构建一个插件感知应用程序。然后就有了接口iPlugin:

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

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

代码不需要是OO就可以重用,尽管在许多情况下这会有所帮助

代码当然不需要使用接口就可以重用,尽管在某些情况下这会有所帮助

编写可重用代码的关键在于编写的代码要写得清楚、注释良好、使用一致的命名和调用约定,并且要比手头的问题严格要求的更通用

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

通常,一开始并不“打算”可重用的代码会变成您希望重用的代码。通常,代码从“内联”开始,然后您发现您需要在多个位置执行完全或几乎完全相同的操作。当您发现自己在复制和粘贴代码时,是时候将其重构为函数了

类似地,当您发现自己希望在文件X中定义的函数在文件Y中真正有用时,是时候将其移动到模块中了


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

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

因此,如果您的方法对
模板
类执行某些操作,那么检查实例
模板
的对象将硬编码对该类的依赖关系。但实际上,您并不关心得到的是什么类,您只关心它是否符合
iTemplate
接口(因为这就是您要调用的全部内容)

vs:

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

如果要为birds创建一组类,可以使用继承来实现它,也可以不使用继承。让我们看看如果没有:

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()
,因为它将始终被覆盖(因为没有两只鸟的声音是一样的)

听起来不错吧?嗯,根据我们的需要,我们可能需要添加其他抽象类型。让我们假设我们制造了很多不同类型的鸟。。。我们会有一些不会游泳的,所以我们可能会创建一个抽象类
nonswimingbird
,它扩展了
Bird
,但会为我们抛出异常。或
非飞行鸟
,或
短程鸟

现在,就代码重用而言,我们确实走上了正轨,但我们在另一个领域遇到了困难。假设我们有一只不会飞也不会游泳的鸟。我们从哪个阶级继承?不管怎样,我们都在复制代码。所以我们需要找到另一条出路。那我们怎么做呢?通过我们可以使用装饰器模式动态添加这些特性,而不是直接继承。(这里还可以使用其他模式,重点是要说明单靠继承并不能满足所有需求。单靠模式也不能满足所有需求。您需要一个良好的体系结构,根据您的具体需求使用两个世界)


关键是,这完全取决于你的需要。如果你只有两个“类”的对象,那么你将设计一个比你计划拥有数千个更简单的东西。我在这里写的重点是演示如何使用直接继承来强制执行一些干式主体(但也演示了直接继承如何导致代码重复)。重要的是,不要仅仅因为你不想重复你自己就试图保持干燥。坚持干燥,但要确保在合理的地方进行组合和扩展,否则会给自己带来维护方面的麻烦。坚持,你会没事的。

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

谢谢。但假设我们创建了另一个名为Product implement iTemplate的类。我仍然必须在类中键入setVariable和getHtml方法,无论是否实现接口,那么重点是什么呢?您能告诉我在哪里找到了这些代码吗?我正处于学习阶段,我希望通过例子来学习。
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
    }
}  
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!');
    }
}