Bardziej po ludzku

Podejście obiektowe zrewolucjonizowało i zdominowało w ostatnich latach branżę tworzenia oprogramowania. ABAP – ze względu na swoją wysokopoziomowość, wygodę i prostotę – długo opierał się rewolucji, jednak już od SAP w wersji 4.6C elementy obiektowości zagościły w środowisku SAP na dobre.

Główną cechą programowania zorientowanego obiektowo jest łatwiejsze odzwierciedlanie rzeczywistości poprzez opisywanie jej w sposób prosty i jednocześnie bardzo zbliżony do intuicyjnego postrzegania rzeczywistości przez człowieka.

Co więcej, wykorzystując język UML (ang. Unified Modeling Language), można w sposób graficzny prezentować badany problem, a uzyskane modele implementować wprost w dowolnym języku programowania (istnieją nawet specjalne narzędzia, które służą automatyzacji tego procesu).

Łatwiej tworzyć, testować, zarządzać

Dzięki zastosowaniu podejścia obiektowego w bardzo przejrzysty i czytelny sposób można oddzielić warstwę logiki biznesowej od warstwy prezentacji.

Używanie osobnych obiektów odpowiedzialnych za przetwarzanie danych oraz osobnych odpowiedzialnych za ich prezentację (np. standardowe klasy dostarczane przez SAP – CL_GUI_ALV* umożliwiające tworzenie raportów ALV) w dużym stopniu ułatwia tworzenie programu i późniejsze zarządzanie kodem, które jest niezbędne w perspektywie nowych wymagań i zmian w aplikacji.

Zawarcie odrębnych funkcjonalności w poszczególnych metodach obiektu umożliwia automatyczne testowanie różnych funkcjonalności programu.

Klasy, obiekty, instancje

Podstawowym elementem w programowaniu obiektowym jest klasa – abstrakcyjne przedstawienie elementów występujących w rzeczywistości. Konkretnym przedstawieniem elementu rzeczywistości jest instancja klasy, czyli obiekt. 

Definiując klasę, ustalamy, jakie właściwości będą miały obiekty stworzone na jej podstawie (jakie będą przechowywać dane) oraz jakie metody będą obsługiwały (jakie będzie zachowanie poszczególnych obiektów z danych klas). Definiujemy też zasięg elementów, decydując o zewnętrznym „wyglądzie” przyszłych obiektów.

Utworzywszy definicję klasy, tworzymy na jej podstawie obiekty – instancje klasy. Z jednej klasy możemy uzyskać nieskończoną liczbę wzajemnie niezależnych obiektów. Obiekty będą implementowały interfejs klasy, udostępniając właściwości i metody zdefiniowane w klasie.

Poszczególne klasy mogą dziedziczyć po sobie. Dzięki dziedziczeniu klasa dziedzicząca zawiera analogiczne metody i właściwości i może wykonywać te same akcje. Dla klasy dziedziczącej możemy też zdefiniować metody i atrybuty specyficzne tylko dla niej. Dziedziczenie znacznie ułatwia programowanie (zmiana dokonana w klasie nadrzędnej propaguje się na wszystkie klasy podrzędne), a w wielu przypadkach pozwala zrezygnować z korzystania z warunków logicznych.

Przykład: Z klasy Samochód jesteśmy w stanie utworzyć obiekt fiat lub opel. Zakładając,
że klasa Samochód zawiera definicję metod Włącz() – Wyłącz(), możemy „włączyć” fiata, a „wyłączyć” opla przez proste wywołanie metod na obiektach: fiat->Włącz, opel->Wyłącz. Obiekty klas Osobowy i Ciężarowy będą miały metody Włącz() i Wyłącz() oraz atrybuty marka i model, odziedziczone po klasie Samochód.

Choć programowanie obiektowe porządkuje strukturę aplikacji, nie jest gwarancją uzyskania czytelnego i łatwo zarządzalnego kodu. Aby w jak największym stopniu wykorzystać atuty, jakie daje programowanie obiektowe, zaleca się przyjęcie kilku podstawowych zasad programowania.

Zunifikuj nazewnictwo

Pierwszą zasadą programowania (wartą stosowania nie tylko w podejściu obiektowym) jest przyjęcie jednolitej konwencji kodowania. To zalecenie ułatwia tworzenie kodu, jak i jego rozwijanie. Dzięki standardowi nazywania zmiennych, metod czy klas programu wystarczy chwila, aby zorientować się w źródle (zarówno swoim, jak i tworzonym przez innego programistę).

Dotyczy to np. przedrostków stosowanych przy zmiennych globalnych i lokalnych, sposobu nazywania zmiennych, metod – nazwy powinny mówić, do czego służy metoda, co zawiera zmienna.

Dzięki jednolitej konwencji nazewniczej kod programu staje się przejrzysty i czytelniejszy. Jednak nie jest to równoznaczne z uporządkowaną strukturą programu.

Zarządzaj widocznością

Zastosowanie programowania obiektowego daje twórcom programu możliwość zarządzania „widocznością” poszczególnych metod i właściwości obiektów. Dzięki rozszerzaniu zasięgu można decydować o tym, które funkcjonalności klasy będą widoczne „na zewnątrz”, a które będą dostępne tylko dla niej samej.

Jako zasadę powinno się przyjąć deklarowanie poszczególnych elementów klasy z jak najmniejszym zasięgiem. Dzięki temu zewnętrzny interfejs zostanie zmniejszony do koniecznego minimum – co znacznie ułatwi późniejsze programowanie.

Oczywiście w przypadku gdy jakaś metoda jest potrzebna „na zewnątrz”, należy rozszerzyć jej zakres widoczności, upewniając się, że to nie wpłynie źle na logikę programu.

Twórz osobne interfejsy

W przypadku dużej klasy, z dużą liczbą metod, jej interfejs może stać się mało przejrzysty. Metody odpowiedzialne za poszczególne „grupy funkcjonalności” zostaną ze sobą wymieszane, dlatego warto w takim przypadku wyłączyć pewne „grupy funkcjonalności” do osobnych interfejsów

Podczas pisania programu możliwe jest rzutowanie obiektów klasy na poszczególne interfejsy implementowane przez tę klasę, co zawęża liczbę widocznych metod do aktualnie potrzebnych. Dodatkowo dzięki interfejsom można poszczególne „grupy funkcjonalności" przypisywać więcej niż jednej klasie obiektów.

Wyodrębnij metody

Aby jeszcze bardziej uporządkować kod programu zaleca się traktowanie poszczególnych metod jako odrębnych całości. Tworząc metodę, należy się skupić się na funkcjonalności, którą ma implementować.

Jeśli konieczne jest wykonanie innego działania, najlepiej odwołać się do osobnej metody, w której jest zawarta logika dotycząca tego działania. To podejście dodatkowo umożliwia tworzenie testów automatycznych. Dzięki nim na bieżąco można sptawdzać tworzone rozwiązanie pod kątem zgodności z założeniami. Dodatkowo przy każdej zmianie w kodzie testy automatyczne pomagają sprawdzić, czy nie „popsuliśmy” czegoś, co wcześniej działało poprawnie.

W idealnej sytuacji testami automatycznymi powinno być pokryte 100% kodu programu. W rzeczywistości jest to oczywiście niemożliwe, jednak trzeba pamiętać, że każdy dobrze napisany test automatyczny zwiększa poprawność programu.

Do 50 linii

Przy dzieleniu programu na klasy i metody ważne jest zwrócenie uwagi, by same metody również były czytelne. Stosuje się oczywiście przyjętą konwencję kodowania i nazywania metod, jednak trzeba też zadbać o łatwe zrozumienie samej logiki metody.

Znacznie ułatwia to ograniczenie wielkości metody do maksymalnie 50 linii kodu – tak aby po wydrukowaniu metoda mieściła się na jednej kartce. Jeśli istnieje taka możliwość, należy wyłączać całe bloki logiczne do osobnych metod, w ten sposób zmniejszając rozmiar metody.

Zatem stosując podejście obiektowe w budowie rozszerzeń ABAP i zachowując dobre praktyki programowania, można istotnie poprawić jakość rozwiązania. Otrzymane rozwiązanie będzie logicznie zbudowane, łatwiejsze do zarządzania i rozbudowy.