编程到接口,而不是php中的实现

编程到接口,而不是php中的实现,php,Php,主要的设计原则之一是程序到接口,而不是实现。这在php或任何其他弱类型语言中都是可能的 编辑: 我可能没有把问题写得那么清楚。我不是说php不能使用接口——它显然可以。我的意思是,在弱类型语言中,“编程到接口而不是实现”的设计原则是否变得多余。是的。定义接口: interface iTemplate { public function setVariable($name, $var); public function getHtml($template); } 并实施: //

主要的设计原则之一是程序到接口,而不是实现。这在php或任何其他弱类型语言中都是可能的

编辑:


我可能没有把问题写得那么清楚。我不是说php不能使用接口——它显然可以。我的意思是,在弱类型语言中,“编程到接口而不是实现”的设计原则是否变得多余。

是的。定义接口:

interface iTemplate
{
    public function setVariable($name, $var);
    public function getHtml($template);
}
并实施:

// 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;
    }
}
PHP接口手册:

我不知道为什么仅仅因为语言是弱类型的,就不可能有接口


编辑:拥有接口的意义(或多或少)在于,无论实际实现所述接口的类是什么,都可以重用代码

假设您的程序使用一个接口
Set
,该接口具有方法
addItem()
removietem()
contains()
。有了接口,您知道无论底层的
Set
实现是什么,您都可以调用这3个方法中的任何一个,无论是HashSet、TreeSet还是其他什么

如果您使用的是弱类型语言,这一点不会改变;您仍然可以像使用强类型语言一样编写代码。我知道我没有很好地解释这一点,但我希望你能理解。

php有,你可以对它们进行编程。你为什么不能这样做


编程到接口意味着您只需使用接口提供的功能,既不依赖实现细节,也不使用实现提供的其他功能,您只是碰巧知道它,因为实现可能会更改(接口不应更改).

取决于“接口”和“实现”的含义。这些是松散的术语,其含义可能会根据上下文发生变化


PHP5包含类似于Java和C#的OOP构造,例如对象,如引用、类、抽象类和接口。它还包含方法参数的类型提示。这些工具可以并且已经被用来为某些东西构建“接口”

最终目标是拥有一个每个组件都同意的接口

因此,例如,如果我正在构建一个JavaScript站点,它完全是在一个老式的MVC(非Rails/PHP)实现中完成的,并且完全是在AJAX中完成的,那么我将确保每个组件都实现了相同的接口以供观察

在每个模型/视图/控制器中,我可以将我的“subscribe”方法命名为完全不同的名称。 或者,我可以为每个应用程序实现一个标准接口

所以我可以在每个可能被调用的组件中实现一个public“.Register(事件类型,订阅类)”方法

同样,我可以在每个可能被调用的组件中实现一个public“.Update(event_type,data)”方法

.Register和.Update是我的观察者通信的接口。 在我的类中,每个类可能都有一个“.Subscribe(publisher,event\u type,self\u reference)”方法。 这种方法可能只是:

Class.Subscribe = function (publisher, event_type) {
    var self_reference = this;
    publisher.Register(event_type, self_reference);
};
每个可能都有一个内部的.Notify方法:

Class.Notify = function (type, data) {
    var subscribers = this.subscribers[type],
        i = 0, l = subscribers.length;

    for (; i < l; i++) { subscribers[i].Update(type, data); }
};

我可以自由地这样做,因为我知道我想要订阅的所有内容都将具有相同的公共界面。

如果不使用类型,那么这个原则的全部要点似乎就变得毫无意义了。当然你可以在php中使用接口,我显然没有异议,我更想说的是,当你不能使用对象类型时,这个原则是无效的。例如,在强类型语言中,您将使用:type t=new-ConcreteType-在php中,您只需说$t=new-ConcreteType。当然ConcreteType将实现接口,但实例化代码对此一无所知。也许我误解了这个原则。@David他们在弱类型语言中确实失去了一些优势,但如果使用正确,它们仍然有用。但是这个原则的目的是“一旦你只依赖接口,你就与实现脱钩”E Gama,但在弱类型语言中,在实例化时只需使用具体类。我就是看不出这个原则在这里是如何应用的。我可能只是很愚蠢,但出于某种原因,这让我感到不舒服。好吧,你不必自己实例化它们,是吗?你仍然可以有一个工厂这样做。请参阅我编辑的帖子。我不明白为什么会是“多余的”
Interface.Subscribe = function (publisher, evt_type) {
    var self_ref = this;
    publisher.Register(evt_type, self_ref);
};

Class_1.Subscribe = Interface.Subscribe.bind(Class_1);
Class_2.Subscribe = Interface.Subscribe.bind(Class_2);
Class_3.Subscribe = Some_Other_Interface.Subscribe.bind(Class_3);