Public, Protected, Private
Do czego służą modyfikatory dostępu? Do ograniczania dostępu do metod, pól i właściwości klas (C#). Ograniczenie to sprawdzane jest w trakcie kompilacji i gdy sięgasz za daleko taki komunikat pojawia się na ekranie:
Error CS0122 ‘Test.fooPrivate()’ is inaccessible due to its protection level.
Ale wystarczy odrobina refleksji tu i tam i można spokojnie olać modyfikatory:
Klasa Test (@21) to twór na potrzeby przykładu. Wcześniej (@9) tworzę informację o typie, następnie szukam konstruktora (@10), (@13-@15) wyciągam adresy do metod i ostateczna porażka modyfikatorów (@16-@18) wywołanie każdej z nich.
Interface
A jeśli tak, to po co się nimi męczyć? Podobny efekt można osiągnąć pisząc z wykorzystaniem interfejsów – o ile skupiamy się tutaj tylko na dostępności i widoczności metod.
Tutaj metody nieudostępnione przez interfejs można traktować jako nie udokumentowane API klasy, podobnie jak chronione i prywatne. I teraz dalej, skoro jest nieudokumentowane to znaczy, że inny zły programista sięgając po nie metody zgadza się na poniesienie pewnego ryzyka (podobnie z refleksją). W przypadku interfejsów dostęp jest prostszy, wystarczy zrzutować interfejs na odpowiednią klasę i ma się dostęp do metody.
Dlaczego warto pisać z interfejsami? Bo łatwo się tym zarządza, bo wprowadzają abstrakcje, bo łatwiej to testować, bo są bardzo fajnie wstrzykiwalne (jeśli takiego słowa nie było – to już jest) i w ogóle super.
Testować?
Skupiając się na łatwiejszym testowaniu, w przypadku gdy korzystamy z modyfikatorów (protected oraz private) wtedy, aby dobrze przetestować kod, można odziedziczyć po klasie i udostępnić metody chronione, poprzez nadpisanie ich publicznymi a następnie ich wywołanie, niestety taka sztuczka z prywatnymi nie przejdzie. Można celowo obniżyć ich zabezpieczenie do poziomu protected i dziedziczyć – ale znowu, po co się tak bawić, skoro można wykorzystać interfejs do udostępnienia tylko tych metody, które chcemy, a reszta publiczna.
W ten sposób nie trzeba tworzyć klasy pochodnej na potrzeby testów, nie trzeba zaniżać zabezpieczania metod 😉
Czyli
Olać modyfikatory, korzystajcie z interfejsów i w ten sposób definiujcie co udostępniacie a co ukrywacie. Takie moje zdanie o modyfikatorach. Póki co u mnie się to dobrze sprawdza i nie czują się źle pisząc wszędzie public.
A juz niedlugo nastepny artykul: jak zadeklarowac zmienna typu int i bonusowo: statyczne konstruktory. 😉
Wiem, że komentarz ma być złośliwy, ale jest wiele sposobów na to aby dobrze zdefiniować i zainicjować zmienną i można to zrobić źle.
Co do tych zmiennych private to ciekawostka jest taka, że mój kolega wiele lat temu “obszedł” w ten sposób zabezpieczenie jakiejś znanej biblioteki, która nie była obfuscowana. Wystarczyło refleksją ustawić odpowiednią flagę 🙂 Nie czerpał z tego oczywiście korzyści, ale trochę się z tego pośmialiśmy.