W tym tygodniu mam egzamin wzorców oprogramowania i jednym z tematów, które będziemy studiować, jest łączenie Efferent i Afferent.
Rozumiem, że pakiet ma wysokie Ce (połączenie eferentne), jeśli zależy od wielu innych typów.
Na przykład:
class Car{
Engine engine;
Wheel wheel;
Body body;
}
Ta klasa miałaby wysoko wydajne sprzęgło, ponieważ zależy od typu silnika, koła i nadwozia.
Natomiast typ „Koło” miałby wysoki Ca (sprzęgło aferentne), gdyby od niego zależało kilka innych opakowań (samochód, samolot, rower).
Jednym z możliwych pytań na naszym egzaminie jest, kiedy połączenie Efferent / Afferent jest dobre, czy złe? Wydaje mi się to dziwne, ponieważ logicznie program potrzebuje pakietów / klas z wysokim sprzężeniem Efferent / Afferent.
Czy ktoś ma przykład, kiedy / gdzie połączenie wysoko wydajne lub aferentne jest dobre / złe?
Dzięki !
źródło
Odpowiedzi:
Sprzężenie aferentne można najłatwiej ocenić pod kątem tego, ile bólu powoduje / oszczędza z powodu konieczności zmiany lub prawdopodobieństwa zmiany. Na przykład weź klasę koła i powiedzmy, że wiele innych modułów używa jej do budowy różnego rodzaju pojazdów. Jeśli klasa kół jest wyjątkowo stabilna, to sprzęgło aferentne jest korzystne, ponieważ pojazdy potrzebują kół i używają niezawodnego. Jeśli z drugiej strony klasa kół jest niestabilna pod względem konserwacji, to sprzęgło aferentne będzie stanowić problem, ponieważ wielokrotnie wprowadzasz przełomowe zmiany w wielu kodach.
Sprzężenie efektywne ma podobną koncepcję, ale będziesz patrzył na nieco inną propozycję wartości. Jeśli masz klasę samochodu, która zależy bezpośrednio od wielu pojedynczych części (w przeciwieństwie do powiedzenia „Silnik” i „Podwozie” i składają się one z innych części), klasa prawdopodobnie robi wiele i dlatego może być wąskie gardło konserwacji. Zmiany w tej klasie mogą być trudne i ryzykowne ze względu na jej złożoność. Z drugiej strony, jeśli połączenie eferentne jest wysokie, ale w rzeczywistości jest dość spójne i jasne, nie musisz się martwić o hierarchię obiektów i relacji.
Jeśli chodzi o architekturę / projektowanie, to naprawdę musisz wziąć pod uwagę niekończące się kompromisy i te parametry nie są inne. Jeśli chcesz znaleźć przykład czegoś dobrego lub złego, zagraj w grę „co jeśli”. Wyobraź sobie przykład i powiedz „a gdybym chciał zrobić X - ile by to było do bani?” Dla X, gdzie odpowiedź brzmi „dużo”, masz wadę, a dla X, gdzie odpowiedź jest „naprawdę łatwa”, masz przewagę.
źródło
Mówiąc ogólnie, luźne połączenie:
pozytywne : chroni część systemu przed zmianami w czymś, od czego to zależy (sprzężenie aferentne)
negatywne : związek może być trudniejszy do zrozumienia
Na przykład, gdy opracowuję system oparty na HTTTP, zdecydowałbym, czy muszę ściśle lub luźno połączyć się z HTTP. Gdybym myślał, że system prawdopodobnie przełączy się na inny protokół, mógłbym wybrać luźne połączenie z nim, a gdybym zaakceptował, że HTTP jest moim protokołem, mógłbym ściśle połączyć się z tym protokołem dla uproszczenia.
Weź pod uwagę, że niektóre zawiłości w WS * polegają na oddzielaniu od protokołu HTTP jako protokołu.
źródło
Dośrodkowy
Jeśli coś wykorzystuje wiele różnych rzeczy (duża liczba sprzężeń aferentnych), może to być podatne na zerwanie, jeśli którakolwiek z tych rzeczy się zmieni.
Niestabilność = 1
Efferent
Jeśli coś jest używane przez wiele różnych rzeczy (duża liczba połączeń odprowadzających), może to być podatne na zerwanie wielu rzeczy, jeśli to się zmieni.
Niestabilność = 0
Stabilność
Definicja „stabilności” Martina jest egzotyczną mieszanką „trudnych do zmiany” i „mających niewiele powodów do zmiany”. Jednak jego metryka niestabilności opisuje tylko „trudność zmiany”. „Powody zmiany” będą miały znacznie więcej wspólnego z czynnikami, których nie można łatwo obliczyć, na przykład z odpowiednim zaprojektowaniem interfejsów, na odpowiednim poziomie abstrakcji i wyraźniejszym zrozumieniem wymagań użytkownika końcowego.
Tak wysokie sprzężenie eferentne z niskim sprzężeniem aferentnym daje stabilność (jak w czymś trudnym do zmiany, ponieważ spowoduje pęknięcie wielu rzeczy), przeciwnie - niestabilność (jak w czymś łatwym do zmiany, ponieważ nie złamie wielu rzeczy) .
Duża liczba sprzężeń aferentnych może wskazywać, że projekt nie koncentruje się - wykorzystuje całą masę różnych rzeczy, więc może nie ma wyraźnej, szczególnej odpowiedzialności.
Wiele sprzęgieł odprowadzających można początkowo zinterpretować jako naprawdę dobrą rzecz, ponieważ wskazuje to, że projekt jest szeroko (ponownie) wykorzystywany. Byłoby jednak źle, gdybyś miał ochotę często zmieniać projekt w sposób, który wszystko psuje. Tak więc przy dużej liczbie sprzęgieł odprowadzających pojawia się potrzeba, aby takie pakiety miały „niewiele lub nie ma powodów do zmiany”. Projekty powinny być stabilne w idealnym sensie, ponieważ nie mają powodów do zmiany, ponieważ podobnie bardzo trudno będzie je zmienić.
Zasada stabilnych abstrakcji
Pojęcia takie jak inwersja zależności (która naturalnie wymaga wstrzykiwania zależności) i SAP (zasada stabilnych abstrakcji) sugerują, że zależności płyną w kierunku abstrakcji. I jest prosty powód, dla którego rozważa się „stabilność” w kontekście „niewielu powodów do zmiany”. Abstrakcyjny interfejs nie wymienia żadnych konkretnych szczegółów, skupia się tylko na „co robić” zamiast na „czym są”, a zatem ma mniej powodów do zmiany. Przyspieszony port graficzny na naszych płytach głównych (interfejs abstrakcyjny) ma mniej powodów do zmiany projektu niż GPU, które się do niego podłącza (konkretny szczegół).
Wielokrotnego użytku a ponowne użycie
Moim osobistym miernikiem, jeśli mogę zasugerować taki, który nieco koliduje z Martinem, jest to przekonanie, że lubię naciskać, aby biblioteki wielokrotnego użytku starały się minimalizować ponowne użycie innego kodu. Powoduje to niestabilność w kierunku twardego 0. To z praktycznych powodów minimalnych powodów do zmiany, ale także w celu promowania najłatwiejszej do wdrożenia biblioteki. Powszechnie używana, powszechnie używana biblioteka, która zależy od kilkunastu różnych bibliotek, ma wiele powodów do zmiany, a także nieporęcznie spakowaną dystrybucję, która może być trudna do wdrożenia. Różnica polega na tym, że „powody zmiany” w moim przypadku obejmują nawet implementację, ponieważ pochodzi ona z widoku zorientowanego na bibliotekę, który ma na celu wydanie stabilnych wersji biblioteki. Martin może zdyskontować wdrożenie jako bardzo oddzielną część,
Z punktu widzenia dystrybucji implementacja i interfejs rozmazują się, aby zapewnić zależności użytkowników od stabilnej lub niestabilnej biblioteki. Z punktu widzenia interfejsu używany jest tylko interfejs, a powiązane szczegóły implementacji są całkowicie oddzielne.
źródło