Приведу пример на коленке. Хотим, например, написать абстрактную файловую систему. Для начала, определим интерфейс, для ФС:
interface FileSystemInterface {
public function write($file, $data);
public function read($file);
}
Затем, хочу реализацию интерфейса ФС для работы с файликами:
class OSFileSystem implements FileSystemInterface {
public function write($file, $data) {
// открываем файлик, пишем данные
}
public function read($file) {
// открываем файлик, возвращаем данные
}
}
Вдруг, кому-то захотелось файловую систему в облаке. Окей, не проблема, реализуем это:
class CloudFileSystem implements FileSystemInterface {
public function write($file, $data) {
// открываем соединение с облаком, пишем данные
}
public function read($file) {
// открываем соединение с облаком, возвращаем данные
}
}
Пусть у нас есть кой-то код, работающий с файловой системой, назовем его "Хранилище файлов". Пусть он выглядит примерно так:
class FileStorage {
protected $Fs;
public function __construct(FileSystemInterface $Fs) {
$this->Fs = $Fs;
}
public function saveFile() {
$this->Fs->write('file.txt', 'file data');
}
public function getFile() {
return $this->Fs->read('file.txt', 'file data');
}
}
Отлично! Теперь мы можем хранилищу файлов отдать любой объект с реализованным интерфейсом
FileSystemInterface. Пример:
// Хранилище файлов работает с файловой системой ОС:
$FS = new OSFileSystem();
$FileStorage = new FileStorage($Fs);
$FileStorage->getFile();
// Хранилище файлов работает с файловой системой в облаке:
$FS = new CloudFileSystem();
$FileStorage = new FileStorage($Fs);
$FileStorage->getFile();
Использование интерфейса, в данном случае. позволяет нам писать только реализацию работы файловой системы, а бизнес-логика, работающая с файловой системой никак не меняется, она знает, что в любом случае файловая система реализует интерфейс
FileSystemInterface и может без опаски использовать методы этого интерфейса.