PHP:如何重用代码(oop)? [英] PHP: how to reuse code (oop)?

查看:55
本文介绍了PHP:如何重用代码(oop)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在php oop中进行了研究,并掌握了可重用代码的概念.

I have studied in php oop and stocked in the concept of reusable code.

我看到了类似的例子

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类也需要更改.我不理解重用"的概念.感谢您的帮助.谢谢.

I can understand the code but not sure why it is reusable. Every time I want to add a new function in iTemplate interface, my Template class needs to be changed too. I don't understand the concept of "reuse". I appreciate any help. Thanks.

推荐答案

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

Interfaces aren't directly for code reuse. They are for abstraction. They enable classes that use the template to check for the interface instead of the base template class. That way it separates implementation from the interface declaration.

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

So if your method does something with a template class, checking for an object of instance template would hard code a dependency on that class. But in reality you don't care what class you get, you just care if it adheres to the iTemplate interface (since that's all you're calling anyway).

public function foo(Template $template) {

vs:

public function foo(iTemplate $template) {

现在,就代码重用而言,接口并不是真正为此设计的.继承通常是.基本上将继承视为扩展抽象.让我举一个例子:

Now, as far as code re-use, interfaces aren't really designed for that. Inheritance typically is. Basically think of inheritance as extending an abstraction. Let me give you an example:

如果要为鸟类创建一组类,则可以在没有继承的情况下继承它.让我们看看如何在不使用以下代码的情况下做到这一点:

If you were to create a set of classes for birds, you could approach it with inheritance and without it. Let's see how we might do it without:

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)...

Now, this is a simple example, but you can see that in those two birds, the walk() functions will likely be identical (and hence violate DRY)...

让我们看一下单层继承的外观:

Let's see how that might look with a single tier inheritance:

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(),因为它将始终被覆盖(因为没有两只鸟听起来相似).

Now, you can see we just re-used 3 of the methods! We didn't declare speak(), since it will be always overriden (since no two birds sound alike).

听起来不错吧?好吧,根据我们的需求,我们可能要添加其他抽象类型.因此,可以说我们制造了许多不同类型的鸟……我们会有一些不会游泳的鸟,因此我们可以创建一个扩展了Bird的抽象类NonSwimmingBird,但会为我们抛出异常.或NonFlyingBirdShortRangeBird ...

Sounds good right? Well, depending on our needs, we may want to add other abstract types. So lets say we were making a lot of different types of birds... We would have some that didn't swim, so we might create an abstract class NonSwimmingBird that extends Bird, but throws the exception for us. Or a NonFlyingBird, or a ShortRangeBird...

现在,就代码重用而言,我们确实处于正轨上,但是我们正在碰壁另一个区域.假设我们有一只不会飞或不会游泳的鸟.我们是从哪一类继承的?无论哪种方式,我们都在复制代码.因此,我们需要寻找另一种出路.好吧,我们该怎么做呢?通过设计模式 ...我们可以使用装饰器模式来代替直接继承快速添加这些特征. (这里还可以使用其他模式,重点是表明仅继承不能满足所有需求.而模式本身也不适合.您需要一个基于您的确切需求同时使用两个世界的良好体系结构) ...

Now, we're really on the track as far as code re-use, but we're hitting a wall in another area. Suppose we have a bird that doesn't fly or swim. What class do we inherit from? Either way, we're duplicating code. So we need to find another way out. Well, how do we do it? Through Design Patterns... Instead of direct inheritance, we could use a decorator pattern to add those traits on the fly. (There are other patterns that can be used here, the point is to show that inheritance alone won't suit all needs. And Patterns alone won't either. You need a good architecture using both worlds based upon what your exact needs are)...

重点是,这完全取决于您的需求.如果您只有2个类"的对象,那么与要计划成千上万个对象相比,您要构造的东西要简单得多.我在这里写的重点是演示如何使用直接继承来强制执行某些DRY主体(以及直接继承如何也可以导致代码重复).最重要的是,不要仅仅因为不想重复自己就尝试坚持DRY.坚持使用DRY,但请确保在合理的范围内进行合并和扩展,否则会给您带来维护上的麻烦.坚持单一责任负责人,您应该没事...

The point is, it all depends on your needs. If you only have 2 "classes" of objects you're going to architect something much simpler than if you are planning on having thousands. The point of what I wrote here is to demonstrate how you can use straight inheritance to enforce some DRY principals (but also how straight inheritance can cause code duplication as well). The big thing, is don't try to stick to DRY just because you don't want to repeat yourself. Stick to DRY, but make sure that you're combining and extending where it's reasonable to, otherwise you're creating yourself a maintenance headache. Stick to the Single Responsibility Principal, and you should be fine...

这篇关于PHP:如何重用代码(oop)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆