Intereting Posts
Propel: как удалить ссылку, сделанную через отношение «многие ко многим» Как укоротить строку, не нарезая слова, сохраняя в пределах лимита символов в PHP обновить переменную сеанса сессии в yii Помощь Почему корзина пуста после добавления продукта Повторяющиеся символы регулярного выражения Php Как повторно сохранить объект как другую строку в Doctrine 2 Сортировка заголовка таблицы в порядке убывания страницы без сортировки всей таблицы базы данных Будет ли сокращение количества включений / требует повышения производительности? Лучший способ избежать строк для вставок sql? Пространства имен в PHP, предотвращающие использование статических функций Yii htaccess переписывание URL-адресов с несколькими косой чертой Аутентификация Kerberos в PHP Шифрование в Javascript, дешифрование на PHP, использование криптографии с открытым ключом Вставка таблицы MySQL

Программа для интерфейса не реализация в php

Одним из основных принципов проектирования является программа для интерфейса, а не реализация. Возможно ли это в 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: http://php.net/manual/en/language.oop5.interfaces.php

Я не знаю, почему было бы невозможно иметь интерфейсы только потому, что язык слабо типизирован.


EDIT: точка (более или менее) имеет интерфейс, поэтому вы можете повторно использовать свой код независимо от класса, который фактически реализует указанный интерфейс.

Скажем, ваша программа использует интерфейс Set , который имеет методы addItem() , removeItem() и contains() . С интерфейсами вы знаете, что сможете вызвать любой из этих 3 методов независимо от базовой реализации Set , будь то HashSet, TreeSet или что-то еще.

Это не изменится, если вы используете слабо типизированный язык; вы все равно можете использовать код, как если бы вы использовали строго типизированный язык. Я знаю, что я не очень хорошо объяснил это объяснение, но надеюсь, что вы поняли это.

php имеет интерфейсы, и вы можете запрограммировать их. Почему бы вам не сделать это?

Программирование на интерфейс означает, что вы просто используете функциональные возможности, предлагаемые интерфейсом, и не полагайтесь на детали реализации и не используете другие функции, предлагаемые реализацией, и вы просто знаете об этом, потому что реализация может измениться (интерфейс не должны).

Зависит от того, что вы подразумеваете под «интерфейсом» и «реализацией». Это свободные члены, значения которых могут меняться в зависимости от контекста.

PHP5 содержит конструкции ООП, подобные Java и C #, такие как объекты как ссылки, классы, абстрактные классы и интерфейсы. Он также содержит указания типа для параметров метода. Эти инструменты могут быть и использовались для создания «интерфейса» для чего-то.

Конечной целью является наличие интерфейса, на который соглашается каждый компонент.

Итак, если, например, я создавал сайт JavaScript, который был выполнен – ​​в основном – в реализации старой MVC (не Rails / PHP), и полностью в AJAX, я бы удостоверился, что каждый из компонентов реализовал тот же интерфейс для наблюдения.

В каждой модели / представлении / контроллере я мог бы назвать мой метод «подписаться» совершенно другим. Или я мог бы реализовать стандартный интерфейс для каждого.

Поэтому у меня может быть общедоступный метод «.Register (event_type, subscriptioning_class)», реализованный в КАЖДОМ одном компоненте, который можно было бы назвать вызываемым.

Аналогично, у меня может быть общедоступный метод «.Update (event_type, data)», реализованный в КАЖДОМ одном компоненте, который можно было бы назвать вызываемым.

.Register и .Update – это интерфейс для моей связи с Observer. Внутри моих классов каждый может иметь метод «.Subscribe (издатель, event_type, self_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); } }; 

Потому что я согласился, что ВСЕ мой интерфейс общения будет вести себя таким образом , неважно, как выглядят мои внутренности.

Моя модель может по-прежнему не обращать внимания на мой вид, и мой вид может продолжать оставаться в стороне моего контроллера.

Невозможно реализовать эти .Notify и .Subscribe таким образом – они не являются частью общедоступного интерфейса. Они могут быть тем, что я хочу.

.Subscribe может взять ARRAY издателей и проталкивать ее через цикл, чтобы подписаться на несколько точек данных. Или возьмите массив из {"pub": x, "type": y} литералы объектов и вызовите метод .Register для каждого из них, чтобы вы могли полностью отключить загрузку этого класса с помощью одного вызова функции.

То же самое происходит с созданием приложения для аудио-плееров. Мне все равно, какие общие свойства MusicPlayer разделяют. Я знаю, что он использует .Play (), .Pause (), .Stop (), .Load (track).

Если я убеждаюсь, что я ТОЛЬКО использую согласованные методы открытого интерфейса, программа будет работать. Зачем?

Потому что парень, который работает на MusicPlayer, может изменить внутренности MusicPlayer. Он мог бы полностью переписать их. Возможно, есть метод ._ precacheSong (track). Но что, если его заменит. _cueTrack (трек) по дороге?

Вы просто используете виджет какого-то чувака, и однажды ваш виджет выйдет из строя, потому что вы расширяете его или реализуете его на основе не-интерфейсных методов или данных без интерфейса, которые произошли с изменением версии v1.2.1

Так что даже в Loose Languages ​​интерфейс очень важен. Они дают вам карту того, как вы можете рассчитывать на вызов ЛЮБОГО компонента, который, как ожидается, будет иметь эту функциональность – и независимо от того, как работают внутренние компоненты этого компонента, входы и выходы будут одинаковыми (хотя больше проверки типов / ошибок требуется на входе).

Они позволяют вам «Duck-Type» очень легко (взять список разных экземпляров класса), сбрасывать один и тот же вызов функции на каждом из них, ожидая, что каждый из них имеет тот же метод и принимает тот же формат данных).

Еще лучше с JavaScript:

Мой код .Subscribe может даже быть написан только один раз, а затем привязан ко всему, что я хочу «наследовать».

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

И я могу делать это свободно, потому что я знаю, что все, что я хочу подписаться, будет иметь тот же публичный интерфейс.