Bycie developerem Salesforce nie jest proste. Codziennie musimy zmagać się z limitami platformy oraz dostarczać rozwiązania, które wpisują się w jej specyfikę. Nie inaczej jest z Apexem, językiem programowania, którym w głównej mierze się posługujemy.

Apex jako język silnie typowany i wywodzący się z głównego nurtu języków obiektowych, takich jak Java czy C#, przejął po nich pewną właściwość – możliwość posługiwania się wartością null. W dokumentacji możemy zatem przeczytać, że: „Wszystkie typy w Apexie niejawnie dopuszczają wartość null oraz mogą ją zwracać„.

Jest to jedna z tych właściwości języka, której nieumiejętne stosowanie może doprowadzić do poważnych konsekwencji. Na przestrzeni lat przekonało się o tym wielu programistów, mierząc się z tzw. „Billion dollar mistake”. Frazę tę wprowadził w 2009 roku Tony Hoare, mówiąc o implementacji Null References w języku ALGOL w 1965. Jak sam wspomina po latach, zrobił to, ponieważ „było to proste do zaimplementowania”.

Dlaczego null  jest taki straszny?

Jako developerzy musimy więc świadomie zwracać wartość null lub umieć przewidzieć, gdzie może ona wystąpić i odpowiednio zabezpieczyć nasz kod.

W Apexie zazwyczaj zabezpieczamy się przed taką sytuacją za pomocą klauzuli if:

W powyższym przykładzie musimy sprawdzić, czy metoda getProfileUrl nie zwróci nam nulla, zanim zwrócony URL będziemy mogli poddać dalszej obróbce (w tym przypadku użyć na nim metody toExternalForm).

Gdybyśmy spróbowali wykonać przypisanie do zmiennej profileUrl bez sprawdzenia, co zwraca nam metoda getProfileUrl, moglibyśmy otrzymać wyjątek NullPointerException.

Innym przykładem może być zabezpieczenie kodu przed pobraniem elementu z pustej listy lub tablicy:

Jeżeli zapytanie do bazy nie zwróci nam żadnego rekordu, to lista będzie pusta, a tym samym pobranie z niej pierwszego elementu (o indeksie zero) spowoduje rzucenie przez system wyjątku List index out of bounds. Niezbędne jest więc sprawdzenie wielkości listy i ewentualnie przerwanie dalszego procesowania kodu, gdy będzie ona pusta.

 

Safe Navigation Operator na ratunek!

W Winter’21 release Salesforce postanowił nieco ułatwić życie developerom, wprowadzając Safe Navigation Operator. Dodanie nowego operatora do języka pozwala zredukować ilość pisanego kodu, a tym samym sprawia, że jest on czytelniejszy i bezpieczniejszy.

Składnia nowego operatora wygląda następująco:

 

Jak to działa? 

Jeżeli wyrażenie po lewej stronie jest nullem, to wyrażenie po prawej stronie nie jest w ogóle ewaluowane.

Pierwszy przykład można więc zapisać z wykorzystaniem nowego operatora w jednej linijce kodu:

Jeżeli lewa strona wyrażenia, w tym przypadku wartość zwracana z metody getProfileUrl, jest nullem, to prawa strona wyrażenia nie jest w ogóle ewaluowana, a tym samym mamy pewność, że nie użyjemy metody toExternalForm na nullu.

Używając tego operatora, drugi przykład możemy zapisać jako:

Tak jak poprzednio: jeżeli zapytanie do bazy nie zwróci nam rekordu, a tym samym lewa strona wyrażenia będzie nullem, to nie będziemy ewaluować wyrażenia po prawej stronie, w tym przypadku – wyciągać pola Name.

Inną ciekawostką związaną z nowym operatorem jest to, że działa on również w wyrażeniach łączonych, czyli w tzw. expression chaining.

Załóżmy, że mamy do wykonania metodę na elemencie listy:

Wszystko zadziała prawidłowo pod warunkiem, że tablica tab posiada element o indeksie x, na którym wywołanie metody method zwróci odpowiedni obiekt, a z niego da się wyodrębnić pole field. Jeżeli któryś z elementów łańcucha będzie nullem, to system rzuci wyjątek.

Jak widzieliśmy wcześniej, zabezpieczenie tablicy jest jedną z możliwości, jednak nadal możemy spodziewać się nulla jako wyniku działania metody. Tutaj z pomocą przychodzi łączenie operatorów:

Taka konstrukcja zapewni nam bezpieczne wywołanie kodu, ponieważ na każdym kolejnym etapie ewaluacji sprawdzamy, czy to, co mamy po lewej stronie wyrażenia nie jest nullem. Gdybyśmy chcieli zapisać to samo bez Safe Navigation Operatora, musielibyśmy każdą z sekwencji sprawdzić osobno, np.:

Należy zwrócić uwagę na jeszcze jeden aspekt powyższego zapisu. Metoda method wywołuje się dwa razy w przypadku, gdy spełnione są pierwsze dwa warunki! Można oczywiście odpowiednio zapisać rezultat działania tej metody i sprawdzić go w warunku w klauzuli if, ale często zdarza się, że w kodzie widzimy właśnie takiego oto potworka. Powinniśmy unikać podobnych zapisów.

 

Gdzie nie użyjemy nowego operatora?

Safe Navigation Operatora można używać w metodach, polach, w rzutowaniu, jako rezultat zapytania czy w łańcuchach wywołań. Jest jednak kilka przypadków, gdzie użycie operatora nie zadziała:

  • w typach i statycznych wyrażeniach z kropką, takich jak np. Trigger.new.
  • w wywołaniach zmiennych i metod statycznych, np. Klasa.metoda() lub Klasa.pole.
  • przy przypisywaniu wartości do wyrażenia, np. foo?.bar = 42; lub ++foo?.bar;
  • w przypisywaniu wyrażeń wewnątrz zapytania SOQL, np. [SELECT Name FROM Account WHERE Name = :someName?.query]

 

Podsumowanie

Nowoczesne obiektowe języki programowania są obecnie projektowane jako języki null-safety. Jest to pewien trend, który stara się ułatwić developerom zabezpieczanie kodu przed przypadkowym lub celowym wystąpieniem wartości null. Salesforce, wprowadzając nowy operator do Apexa, sprawił, że odwieczna walka z nullem stała się nieco łatwiejsza.

Autor
  • Kamil Golis
  • Salesforce Developer
  • W Craftware od 2017 roku jako programista Salesforce, jednak amatorsko programuje od czasu swojego pierwszego komputera – Commodore 64. Pasjonat technologii mobilnych oraz astronomii. Prywatnie fan horrorów i kina o tematyce zombie. W wolnych chwilach tworzy własne gry i majsterkuje.

Opracowanie redakcyjne:
Ania Sawicka
Opracowanie redakcyjne
Podobał Ci się mój artykuł?

Jeśli tak, zapraszam Cię do grona najlepiej poinformowanych czytelników bloga. Dołącz do naszego newslettera, a nie ominą Cię żadne nowości.