Wizytator - upraszczanie zależności przy modyfikacji interfejsu klas

Dokument: pdf (443.8 KB)
  • 3 stron
Opublikowany 2017-07-23 02:03:14

04/201016 Programowanie C++ D odawanie nowej klasy do hierar- chii polega na utworzeniu tej klasy oraz nadpisaniu metod. Modyfiku- jemy jedynie fragment kodu źródłowego za- wierający implementację nowej klasy, najczę- ściej tworzymy nowy plik. Dodawanie meto- dy, która będzie nadpisywana, jest bardziej skomplikowane: modyfikujemy klasę bazo- wą oraz wszystkie klasy pochodne, dostar- czając odpowiednią funkcjonalność. W tym przypadku modyfikacja obejmuje wiele róż- nych fragmentów kodu. Taka asymetria po- między modyfikacją hierarchii klas a mody- fikacją interfejsu w tej hierarchii jest niewy- godna, zwłaszcza gdy częściej będziemy mo- dyfikować funkcjonalność niż strukturę. Ar- tykuł przedstawia wzorzec projektowy wizy- tatora (inna nazwa to odwiedzający), który pozwala uprościć zależności przy modyfika- cji funkcji operujących na hierarchii klas. W dalszej części artykułu przedstawiona zosta- nie zasada działania tego wzorca, przykład użycia oraz wykorzystanie wizytatora w bi- bliotece boost::variant. Niedogodności nadpisywania metod Wzorzec projektowy wizytatora (inna nazwa to odwiedzający), opisany między innymi w książce Gamma, Helm, Johnson, Vlissides ,,Wzorce projektowe'', pozwala sprawić, że modyfikacja funkcjonalności będzie prosta, natomiast złożona będzie modyfikacja struk- tury. Przykład ilustrujący omawianą techni- kę wykorzystuje hierarchię klas Unit, przed- stawioną na Rysunku 1, reprezentującą róż- ne oddziały wykorzystywane w grze strate- gicznej: jednostki piechoty, czołgi, wyrzutnie rakiet itd. Podczas tworzenia kolejnych wersji gry hierarchii tej prawie nie będziemy zmie- niać, typy jednostek będą ustalone we wcze- snych etapach implementacji. Spodziewamy się, że będą zmieniane funkcje operujące na jednostkach lub grupach jednostek. Funk- cje te będą obliczały wartość bojową jedno- stek, ich szybkość przemieszczania, będą au- tomatycznie rozmieszczać jednostki na da- nym obszarze, obrazować te jednostki, gene- rować statystyki itp. Zbiór tych funkcji bę- dziemy rozszerzali podczas tworzenia kolej- nych wersji aplikacji. Gdyby funkcje operujące na jednostkach implementować jako metody klas, tak jak po- kazano na Listingu 1, to wystąpi niedogod- ność, o której była mowa na początku, doda- wanie lub usuwanie metody wymaga mody- fikacji wszystkich klas w hierarchii. Przy ta- kim podejściu kod dotyczący tej samej funkcji będzie rozproszony, każda klasa będzie miała fragment funkcjonalności, zmniejsza to czy- telność kodu i utrudnia jego modyfikacje. Przykładowo, obliczanie statystyk (liczby żoł- nierzy, liczby czołgów itd.) wymaga, oprócz klasy przechowującej liczniki, dostarczenia metody w każdej klasie konkretnej, która aktualizuje te liczniki (Listing 1). Dodatko- wo klasy reprezentujące jednostki będą mia- ły wiele różnych metod, trudno będzie okre- ślić ich odpowiedzialność. Kod źródłowy będzie bardziej przejrzysty, jeżeli daną funkcję zrealizujemy w spójnym fragmencie kodu. Dla rozpatrywanego przy- kładu możemy aktualizację liczników prze- nieść do klasy, która je zawiera (patrz Listing 2). Klasy reprezentujące jednostki będą prost- sze, nie muszą zawierać metod związanych z obliczaniem statystyk. Kod realizujący da- ną funkcję jest umieszczony w jednym miej- scu, np. kod obliczania statystyk zawiera kla- sa Statistics (Listing 2). Niestety przedsta- wiona technika wymaga jawnego badania ty- pu obiektu za pomocą mechanizmów reflek- sji, co jest dosyć czasochłonne. Łańcuch in- strukcji warunkowych, który porównuje typ obiektu ze wszystkimi typami w hierarchii, nie jest eleganckim rozwiązaniem. Wzorzec wizytatora pozwala zachować za- lety wynikające z umieszczenia kodu realizu- jącego daną funkcję w jednym miejscu (poza klasami w hierarchii), usuwając konieczność badania typu obiektu za pomocą łańcucha in- strukcji dynamic_cast. Wizytator Operacje dla obiektów w hierarchii klas często implementujemy, wykorzystując funkcje wirtualne. Gdy liczba takich metod rośnie, klasy mają trudną do określenia odpowiedzialność, kod staje się mało przejrzysty. Przedstawiona technika rozwiązuje ten problem. Dowiesz się: • Co to jest wzorzec wizytatora; • Jak używać biblioteki boost::variant. Powinieneś wiedzieć: • Jak pisać proste programy w C++; • Co to jest dziedziczenie i funkcje wirtualne. Poziom trudności upraszczanie zależności przy modyfikacji interfejsu klas Szybki start Aby uruchomić przedstawione przykłady, należy mieć dostęp do kompilatora C++ oraz edy- tora tekstu. Niektóre przykłady korzystają z udogodnień dostarczanych przez bibliotekę bo- ost::variant, warunkiem ich uruchomienia jest instalacja bibliotek boost (w wersji 1.36 lub nowszej) Na wydrukach pominięto dołączanie odpowiednich nagłówków oraz udostępnia- nie przestrzeni nazw, pełne źródła dołączono jako materiały pomocnicze. Wizytator www.sdjournal.org 17 Wzorzec wizytatora Wzorzec wizytatora wykorzystuje pomocni- czą hierarchię klas, zwaną hierarchią wizytu- jącą lub odwiedzającą, która jest związana z hierarchią klas, dla której ...

Tagi:
  • przy
  • klas
  • Upraszczanie
  • interfejsu
  • modyfikacji
  • Wizytator

Komentarze do: Wizytator - upraszczanie zależności przy modyfikacji interfejsu klas • 0