masyasmv / otus_adapter_generator
Домашка Адаптеры и Мост
Requires
- php: ^8.3
Requires (Dev)
- phpunit/phpunit: ^12.1
This package is auto-updated.
Last update: 2025-07-30 20:05:49 UTC
README
Автоматический генератор адаптеров для PHP-интерфейсов с помощью Reflection и простого IoC.
📦 Возможности
-
Генерация адаптеров по любому интерфейсу:
- Методы
getX()
вызываютIoC::resolve('X', "Interface:x.get", $obj)
и возвращают значение. - Методы
setX($v)
создают и выполняют командуICommand
через IoC:IoC::resolve(ICommand::class, "Interface:x.set", $obj, $v)->execute()
. - Остальные методы вызывают
IoC::resolve('<ReturnType>'|ReturnType::class, "Interface:method", $obj, ...args)
.
- Методы
-
Поддержка стилей имен интерфейсов:
IUser
→UserAdapter
UserInterface
→UserAdapter
Some
→SomeAdapter
-
Модульная структура: генератор разбит на мелкие хелперы для удобства тестирования и расширения.
-
Автосоздание папки назначения, если её не было.
-
Полный набор PHPUnit-тестов: покрываются все ветки генерации (геттеры, сеттеры, общие методы, наследование, отсутствие интерфейса).
-
CI на GitHub Actions: автоматическая проверка при каждом пуше и PR.
🛠 Требования
- PHP ≥ 8.0
- Composer
- Разработческие зависимости (phpunit/phpunit ^10)
⚡ Быстрый старт
-
Создайте интерфейс, например:
<?php namespace MyApp; interface IWidget { public function getPosition(): array; public function setPosition(array $pos): void; public function render(string $mode): string; }
-
Вызовите генератор в скрипте или тесте:
use Masyasmv\Adapter\AdapterGenerator; require 'vendor/autoload.php'; $gen = new AdapterGenerator(); $gen->generate( interfaceFqcn: MyApp\IWidget::class, outputDir: __DIR__ . '/src/AutoGenerated' );
-
В папке
src/AutoGenerated
появится файлWidgetAdapter.php
:namespace MyApp\AutoGenerated; use ICommand; use IoC; class WidgetAdapter implements \MyApp\IWidget { private object $obj; public function __construct(object $obj) { $this->obj = $obj; } public function getPosition(): array { return IoC::resolve('array', "MyApp\\IWidget:position.get", $this->obj); } public function setPosition(array $pos): void { IoC::resolve(ICommand::class, "MyApp\\IWidget:position.set", $this->obj, $pos) ->execute(); } public function render(string $mode): string { return IoC::resolve(string::class, "MyApp\\IWidget:render", $this->obj, $mode); } }
🔧 Интеграция с IoC
Пример для любого контейнера:
$container->set('AdapterFactory', function() { return function(string $iface, object $obj) { $short = (new \ReflectionClass($iface))->getShortName(); // Отбрасываем I- или Interface if (str_starts_with($short, 'I')) { $base = substr($short, 1); } elseif (str_ends_with($short, 'Interface')) { $base = substr($short, 0, -strlen('Interface')); } else { $base = $short; } $adapter = $base . 'Adapter'; $ns = (new \ReflectionClass($iface))->getNamespaceName() . '\\AutoGenerated'; $class = $ns . '\\' . $adapter; return new $class($obj); }; });
✅ Тестирование
vendor/bin/phpunit --colors=always
Кейсы в tests/Unit
покрывают все возможные ветки работы генератора.
📜 Лицензия
MIT © Masya Smv