Powiedzmy, że buduję rozszerzenie Magento 2, które działa ... cóż ... nieważne. Powiedzmy, że robi super niesamowite rzeczy.
Chcę jednak upewnić się, że jest on budowany przy użyciu odpowiednich standardów, aby inni programiści mogli go rozszerzyć.
Kiedy powinienem używać DI w połączeniu z interfejsami, a kiedy nie?
Wyjaśnienie tego jest kluczowym przykładem.
Klasa Magento\Core\Helper\Data
ma taki konstruktor:
public function __construct(
\Magento\Framework\App\Helper\Context $context,
\Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Framework\App\State $appState,
PriceCurrencyInterface $priceCurrency,
$dbCompatibleMode = true
) {
parent::__construct($context);
$this->_scopeConfig = $scopeConfig;
$this->_storeManager = $storeManager;
$this->_appState = $appState;
$this->_dbCompatibleMode = $dbCompatibleMode;
$this->_priceCurrency = $priceCurrency;
}
Moje pytanie koncentruje się na var \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
(wiem, że są inne w tym samym konstruktorze, ale jedno wyjaśnienie będzie pasować do wszystkich przypadków, które moim zdaniem).
Według di.xml
modułu podstawowego var będzie instancją Magento\Framework\App\Config
:
<preference for="Magento\Framework\App\Config\ScopeConfigInterface" type="Magento\Framework\App\Config" />
ale mogę to łatwo zmienić, jeśli zajdzie taka potrzeba.
Kiedy powinienem używać takich interfejsów w kodzie?
Stworzyłem ten niekompletny moduł przykładowy (przepraszam za reklamę), w którym korzystałem z takich interfejsów, ale wszystkie pochodzą z rdzenia. Nie stworzyłem własnego. Czy powinienem?
Odpowiedzi:
Imho to nie jest pytanie specyficzne dla Mage2, bardziej ogólnie „Kiedy używać interfejsów”. To zależy od tego, gdzie chcesz, aby ktoś mógł rozszerzyć twoje rozszerzenie. Powiedziałbym wszędzie, gdzie pracujesz z logiką biznesową, co może się zmienić. ;) Poza tym obiekty bez zachowania (np. Proste obiekty danych) zwykle się nie zmieniają.
Jeśli chcesz być w 100% elastyczny, jakoś musisz używać interfejsów wszędzie. Ale nie przeprojektowałbym tego. Osobiście lubię też http://odetocode.com/blogs/scott/archive/2009/06/08/when-do-i-use-interfaces.aspx jako wprowadzenie, gdy jest to naprawdę przydatne.
źródło
Magento2 promuje stosowanie zasad SOLID .
Zasada bezpośredniej inwersji zależności mówi, że kod powinien zależeć od abstrakcji (interfejsów).
Zasada segregacji interfejsów mówi, że wiele interfejsów specyficznych dla klienta jest lepszych niż jeden interfejs ogólnego przeznaczenia. Klasy mogą również definiować interfejs chroniony, więc interfejsy są bardziej preferowane z architektonicznego punktu widzenia.
Również PHP nie obsługuje wielokrotnego dziedziczenia klas, ale obsługuje wiele implementacji interfejsów. To jeszcze jedna kwestia dla interfejsów.
Można więc zastosować prostą zasadę: jeśli nie wiesz, czego użyć, ZAWSZE używaj interfejsów .
PS. Wydajność to nie powód, dla którego nie używam interfejsów
źródło