Интерфейсы просто ОПИСЫВАЮТ, что должны делать реализации?

Я просто изучаю интерфейсы PHP, поскольку я никогда не использовал их раньше, но, насколько я понимаю, они являются лишь интерфейсом, как они называются, чтобы отчасти поддерживать, как классы, которые их реализуют, структурированы?

Например, если вы хотите создать два разных класса для двух разных баз данных, вы можете сделать следующее:

class mysql {

public function connect() {
// code here
}

public function getData() {
// code here
}

}

class mongoDB {

public function connect() {
// code here
}

public function getData() {
// code here
}

}

…и это будет технически так же, как:

interface database {

public function connect() {

}

public function getData() {

}

}

class mysql implements database {

public function connect() {
// code here
}

public function getData() {
// code here
}

}

class mongoDB implements database {

public function connect() {
// code here
}

public function getData() {
// code here
}

}

…я прав? Просто, используя интерфейс, он гарантирует, что вы не будете делать что-то подобное ниже и, следовательно, не сможете легко менять базы данных?

class mysql {

public function connect_mysql() {
// code here
}

public function getData() {
// code here
}

}

class mongoDB {

public function connect_mongo() {
// code here
}

public function getData() {
// code here
}

}

Это в значительной степени причина их?

0

Решение

Интерфейс стандартизирует то, на что может положиться ваш код, и в то же время отделяет его от конкретной реализации. Вау, это звучит сложно. Проще проиллюстрировать это с точки зрения пользователь интерфейсов:

function (MyDatabaseInterface $db) {
$db->connect();
$db->getData();
}

Типовые подсказки являются большой частью использования интерфейсов. Эта функция объявляет, что ее аргумент должен быть экземпляром MyDatabaseInterfaceдругими словами, любой объект, который implements MyDatabaseInterface, Это полностью зависит от вас, что это за конкретный объект, пока он implements MyDatabaseInterface, И так как в MyDatabaseInterface вы указали методы connect() а также getData(), вы можете быть уверены, что любой передаваемый объект имеет эти методы и что вы можете вызывать их.

С другой стороны, взгляните на эту функцию:

/**
* @return MyDatabaseInterface
*/
function foo() {
...
}

Не имеет значения, что эта функция делает внутренне, но она объявляет, что вернет объект типа MyDatabaseInterfaceдругими словами, какой-то объект, который implements MyDatabaseInterface, Когда вы звоните, вы знаете, на что вы можете положиться:

$bar = foo();
$bar->connect();
$bar->getData();

Эта функция может возвращать экземпляр mysql или из mongoDBэто не ваша забота. Вы просто придерживаетесь того, что было объявлено в интерфейсе, и ваш код будет работать независимо от того, какой конкретный объект вы получите.

Интерфейс буквально определяет интерфейс между кодом. Он определяет, какие методы кода могут безопасно вызывать другой код, не привязывая специфику к конкретным классам. Ваши конкретные объекты могут определять на большее количество методов, чем определено в интерфейсе; интерфейс не объявляет структуру класса. Класс может реализовывать несколько интерфейсов одновременно, то есть он реализует все методы всех интерфейсов; тогда каждый отдельный интерфейс будет просто представлять подмножество всех возможных методов, которые могут быть вызваны для объекта.

Вы должны описать конкретные «задачи» или «способности», которые могут быть выполнены в интерфейсе, а не «классы». Это хороший знак, если имена вашего интерфейса заканчиваются на «-able», например Iterable, Класс может затем реализовать несколько интерфейсов и тем самым описать все, что он «может делать». Затем вы можете требовать аргументы функции с определенной «способностью» в определенных точках, как показано в приведенном выше примере кода. Это изолирует и разъединяет части кода друг от друга, что делает ваш код более гибким, повторно используемым и адаптируемым к изменениям.


Для полезного сценария реального мира представьте большую команду разработчиков, которая работает над большим проектом. Есть несколько подгрупп, каждая из которых отвечает за свою часть приложения. Все они садятся вместе и придумывают общий план. В какой-то момент код этих отдельных команд должен взаимодействовать друг с другом. Они могут определить эти интерфейсы авансовые:

  • «Мне нужно вызвать какой-то метод для вашего кода, который даст мне учетные данные пользователя».
  • «Хорошо, тогда вам нужно дать мне какой-нибудь предмет, из которого я могу получить foobar».
  • «Тогда здесь мы должны поговорить с компонентом Джо, чтобы отправить данные базы».

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

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]