Posts tagged ‘accessors’

Styl akcesorów

2009-11-16 18:46

Ponieważ w C++ nie ma mechanizmu właściwości, do kontroli dostępu do pól w klasie wykorzystuje się metody dostępowe, czyli akcesory. Od kiedy zajmuję się programowaniem w tym języku, starałem się wynaleźć jakąś sensowną konwencję odnośnie tego, w jakiej postaci metody te zapisywać i jak je nazywać.
Niektórzy preferują na przykład utworzenie tylko jednej funkcji postaci:

  1. Typ SetX(Typ x);

która ustawia nową wartość pola i jednocześnie zwraca nam poprzednią. Takie rozwiązania realizuje chociażby funkcja set_new_handler, ustawiająca procedurę obsługi błędu braku pamięci dla operatora new. Nie akceptuję tego sposobu z jednego prostego powodu: bardzo częsta operacja pobrania wartości wymaga tutaj aż dwóch wywołań, które wyglądają co najmniej dziwnie.

Akcesory muszą więc być dwa (get/set). Pozostaje wtedy kwestia: jak je nazywać? Tutaj doszedłem do trzech możliwości:

  1. Skorzystać z przeciążenia funkcji i obie metody nazwać tak samo, czyli po prostu X. Dla kompilatora będą one z łatwością odróżnialne, jako że getter jest bezparametrowy, a setter oczywiście nie.
  2. Użyć nazw GetX i SetX.
  3. Metodę zmieniającą nazwać SetX, ale getter po prostu X.

Chyba każdy z tych trzech sposobów widziałem w użyciu w jakiejś popularnej bibliotece, więc nie są to tylko teoretyczne propozycje. Sam zresztą wypróbowałem po kolei każdą z nich.

I tak rozwiązanie pierwsze jest na pewno najkrótsze, ale sprawia, że wywołania setterów wyglądają dziwnie. Widząc:

  1. scene->Camera (camera);

można zastanawiać się, co autor miał na myśli, a interpretacja “ustaw obiekt kamery dla sceny” nie musi być wcale tą, która nasuwa się jako pierwsza.
Z kolei drugi sposób (z Get/Set) jest całkowicie jednoznaczny, lecz w zamian potrafi wyprodukować łańcuszki w rodzaju poniższego:

  1. game->GetSubsystem(SS_GFX)->GetSceneManager()->GetRenderer()->GetDevice()->Reset();

Wszystkie te Gety trudno uznać za potrzebne do szczęścia, chociaż javowcy pewnie by się kłócili ;)

Dlatego też sposób trzeci polega na pozbyciu się ich (Getów, nie koderów Javy :>). Tę właśnie konwencję (SetX/X) wykorzystuję obecnie i jak dotąd stwierdzam, że sprawdza się dobrze. Dla ostatecznych wniosków byłby jednak potrzebny dłuższy okres, by przekonać się, czy po upływie pewnego czasu nadal mogę patrzeć na swój kod z zachowaniem równowagi psychicznej ;]

Tags: ,
Author: Xion, posted under Programming » 5 comments

Pola i akcesory wewnątrz klasy

2009-10-26 23:53

Zgodnie z zasadami programowania obiektowego pola klas nie powinny być bezpośrednio dostępne na zewnątrz. Należy jest zawsze opakowywać w akcesory: właściwości lub krótkie metody typu get i set. Z nich właśnie korzysta potem kod zewnętrzny, dzięki czemu nie może on (w dobrze napisanej klasie) niczego zepsuć poprzez – chociażby – ustawienie jakiegoś pola na nieprzewidzianą wartość.
Taka praktyka jest powszechnie przyjęta i raczej nie budzi wątpliwości. Inaczej jest z używaniem tychże pól lub akcesorów wewnątrz klasy, a więc w jej własnych metodach. Tutaj często mamy wybór: czy odwołać się do “gołego” pola, czy też poprzez odpowiednią właściwość/metodę.

Które podejście jest właściwsze? C#/.NET od wersji 3.0 zdaje się to rozstrzygać, umożliwiając półautomatyczne tworzenie właściwości:

  1. public class SomeClass
  2. {
  3.     public int Foo { get; set; }
  4. }

Nie ma tutaj nie tylko bloków get i set, ale i ukrytą pod tą właściwością pola. Przy korzystaniu z tego feature‘a żadnego dylematu więc nie ma.
Wydaje mi się jednak, że wybór nie jest taki oczywisty i że niekoniecznie należy używać akcesorów wewnątrz klasy. Argumentem przeciw, który od razu przychodzi do głowy, jest troska o wydajność – zwykle jednak przesadzona, bo proste gettery i settery są bez problemu rozwijane w miejscu użycia. Drugim ‘ale’ jest wygląd kodu w językach bez właściwości; zwłaszcza dotyczy to Javy, w której odpowiednik C#-owego:

  1. Foo.Bar.Baz.Qux.Thud = 5;

roiłby się od getów. W końcu można by się jeszcze pokusić o uzasadnienie na wpół merytoryczne: skoro bądź co bądź prywatne pole jest składnikiem klasy do jej wyłącznej dyspozycji, to dlaczego metody miałyby obchodzić je dokoła zamiast odwoływać się doń bezpośrednio? A może jednak lepiej jest skorzystać z tej dodatkowej warstwy pośredniczącej (mogącej np. wykrywać jakieś błędy)?…

Na razie – mimo całkiem przyzwoitego doświadczenia w programowaniu w językach wszelakich – trudno jest mi na te pytania odpowiedzieć. Ostatnio aczkolwiek skłaniam się ku bezpośredniemu dostępowi do pól w metodach klas. Chętnie poznałbym jednak opinie innych koderów na ten temat.

Tags: , , , , ,
Author: Xion, posted under Programming » 3 comments
 


© 2023 Karol Kuczmarski "Xion". Layout by Urszulka. Powered by WordPress with QuickLaTeX.com.