Ostatnio zajmuję się bardziej „zorganizowanym” programowaniem i dowiaduję się, że powinienem programować interfejs, a nie implementację. Mając to na uwadze, czy lepiej byłoby „naszkicować” projekt w interfejsach przed napisaniem implementacji, jeśli to możliwe?
A jeśli tak jest, to w przypadku korzystania z bibliotek stron trzecich (tj. Lidgren), czy powinienem owijać je również w interfejsy i rozwiązywać je za pomocą kontenerów IOC, czy też jest w porządku, aby udostępnić je interfejsom?
Odpowiedzi:
Niestety, często sprowadza się to do osobistych preferencji.
To, co do tej pory opisałeś, wydaje się dobre. W rzeczywistości, jeśli chcesz (i polecam), możesz zastosować następujące podejście:
Koncentrujesz się na próbie napisania bardziej „zorganizowanego” kodu. Śledzenie TDD pomoże ci w tym.
Niektóre dodatkowe punkty:
źródło
Tak, powinieneś kodować interfejsy zamiast znanych implementacji i tak, powinieneś najpierw zbudować interfejsy, a nie wymyślać je z własnego kodu.
Przyczyny obu zaleceń są w dużej mierze takie same: programowanie komputerowe dotyczy głównie czynników ludzkich. Wielu uważa to za zaskakujące, ale zastanów się: istnieje prawie nieskończona liczba różnych sposobów rozwiązania tego samego problemu komputerowego, które działają równie dobrze. Prawie wszystkie z nich są całkowicie niemożliwe do zrozumienia dla każdego, kto ich nie napisał (lub w rzeczywistości autorowi wkrótce).
Wynika z tego, że dobra inżynieria oprogramowania polega w dużej mierze na tym, jak osiągnąć pożądany efekt (poprawne obliczenia z rozsądną wydajnością) w sposób, który pozwala na późniejszą obróbkę kodu źródłowego. Interfejsy i interfejsy API są kluczową częścią tej dyscypliny: pozwalają myśleć o problemie na jednym poziomie opisu na raz. Jest to o wiele łatwiejsze niż jednoczesne myślenie o regułach spójności biznesowej i implementacjach list połączonych, dlatego wymuszenie takiego oddzielenia obaw jest lepsze niż pozwolenie programistom klienckim na użycie twojego kodu w dowolny sposób.
Trudno w to uwierzyć wielu kowbojskim programistom, którzy są przekonani, że rozumieją wszystko, co piszą, są znacznie lepsi niż przeciętni myśliciele i potrafią poradzić sobie z całą złożonością, która sprawia kłopoty „mniejszym” programistom. Nieznajomość własnych ograniczeń poznawczych jest niezwykle powszechnym zjawiskiem - dlatego najlepsze praktyki w organizacji kodu są tak niezwykle ważne (i tak często ignorowane).
Powtarzając, interfejsy i bariery API są w dużej mierze dobre , nawet jeśli współpracujesz tylko ze sobą. Jeśli chodzi o biblioteki zewnętrzne, jeśli mają ze sobą dobrze przemyślany interfejs API, nie widzę problemu w korzystaniu z niego, ponieważ jest tak długo, jak długo nie przewiduje się zamiany tej biblioteki na inną. W przeciwnym razie owijka lub warstwa antykorupcyjna może być bardzo dobrym pomysłem.
źródło
IBlah
Zaimplementowane przezBlah
lubBlah
zaimplementowane przezBlahImpl
. Nie podoba mi się oba, i zwykle używająBlah
zaimplementowane przezOralBlah
,WrittenBlah
lubASLBlah
. Ale jak zwykle ważniejsze jest dostosowanie się do istniejącej bazy kodu i oczekiwań niż do jakiegokolwiek ogólnego standardu.Zamiast niewolniczego programowania tylko interfejsów, może warto przyjrzeć się rozwojowi / projektowaniu testowemu (TDD)?
Wiele osób uważa TDD za praktykę testowania, ale w rzeczywistości jest to podejście projektowe, w którym pozwalasz testom ujawnić, w jaki sposób twój kod będzie używany za pomocą testów (początkowo za pomocą testów jednostkowych, ale może być również przez testy integracyjne).
Programowanie interfejsów jest ważną bronią w twoim zestawie narzędzi, ale jak większość rzeczy, nie zawsze jest to odpowiednie rozwiązanie / technika / praktyka, ponieważ nie zawsze jest potrzebne. Powinieneś zaprogramować interfejsy tam, gdzie potrzebujesz.
Korzystanie z TDD zmusi cię do zbadania, gdzie takie interfejsy są ważne i gdzie, szczerze mówiąc, nie ma to znaczenia. Na koniec powinieneś mieć całkiem niezły zestaw testów jednostkowych w całej bazie kodu.
Jeśli chodzi o korzystanie z bibliotek stron trzecich, zdecydowanie polecam owijanie ich we własne abstrakty, tam gdzie to właściwe; i nie pozwól klientom Twojego interfejsu API „wiedzieć” o nich.
Powodzenia!
[edytuj: zobaczyłem odpowiedź megaflight - całkowicie się zgadzam]
źródło
Myślę, że to przesada. Jeśli użytkownik twojego API nie musi być zmuszany do implementacji / używania czegoś w określony sposób, to bym to pominął. Interfejsy to umowy, jeśli ich nie potrzebuję, to po co mi je dawać?
Myślę, że ludzie nadużywają interfejsów. Dodajesz warstwę złożoności, która w większości przypadków nie jest potrzebna.
źródło
Programowanie wbrew umowie jest prawie zawsze dobrym pomysłem. Umowa ta nie musi być interfejsem, może być wypełniona przez klasę. Moim zdaniem interfejsy stały się nieco nadużywane wraz z DI ze względu na obawy związane z testowaniem jednostkowym i szydzącymi ramami.
Osobiście wolę wprowadzać interfejsy tylko wtedy, gdy najprawdopodobniej mogę mieć lub mam więcej niż 1 realizację umowy. Interfejsy są świetne dla repozytoriów, w których chcę abstrahować dostęp do danych, ale prawdopodobnie mniej dla mojej standardowej logiki biznesowej, która prawdopodobnie będzie stosunkowo mało elastyczna.
Teraz brak interfejsu może powodować problemy z testowaniem jednostek, szczególnie dla purystów. Ale jestem zainteresowany wyśmiewaniem zewnętrznych zależności moich programów, a nie wewnętrznych zależności. Chcę, aby moje testy przeprowadzały sprawdzanie poprawności kodu, a nie echo struktury kodu.
źródło