Czym są wzorce projektowe i jakie korzyści płyną z ich zastosowania, wie każdy programista. Fabryka jest jednym z bardziej klasycznych i najczęściej wykorzystywanych wzorców kreacyjnych. Czy warto jej używać? To zdecydowanie pytanie retoryczne. W tym artykule postaram się odpowiedzieć na inne: Czy da się zastosować fabrykę w Salesforce Lightning Web Components?

Klasyczne zastosowanie – do tworzenia obiektów – jest trochę na wyrost. W tym celu lepiej użyć uiRecordApi i metod takich jak generateRecordInputForCreate czy getRecordCreateDefaults.

Jak w takim razie powinna wyglądać i do czego ma służyć fabryka?

Fabryka w Lightning Web Components jako zbiór informacji o obiekcie

Pierwszym zastosowaniem jest zebranie w jednym miejscu wszystkich potrzebnych informacji opisujących obiekt.

opportunityFactory.js

Obraz 1 – opportunityFactory.js

Najprostsza fabryka zawiera informacje o obiekcie oraz jego polach. Importujemy w niej referencje do obiektów oraz pól. Następnie grupujemy je i eksportujemy, żeby były dostępne w innych modułach.

 import referencji

Obraz 2 – import referencji

Korzyści:

  • Kod jest uporządkowany, bo cały opis obiektu znajduje się w jednym miejscu, nie jest porozrzucany i powielany w innych modułach.
  • Ewentualne zmiany nazw pól wykonujemy tylko w jednym miejscu, bez konieczności refaktoryzacji kodu.
  • Nazwy referencji do pól i obiektów są wspólne dla całego projektu.

Jeżeli potrzebujemy różnych zestawów pól w różnych modułach, możemy w prosty sposób rozbudować fabrykę o nowe metody lub dodać parametr do metody getFields.

dodanie parametru do metody getFields

Obraz 3 – dodanie parametru do metody getFields

Fabrykę możemy również rozbudowywać o metody związane z obiektem: pobieranie pojedynczych rekordów, pobieranie list, jak również tworzenie i edycja.

 

Fabryka w Lightning Web Components związana z implementowaną funkcjonalnością

Drugi typ fabryk to te związane z implementowaną funkcjonalnością i ściśle powiązane z jedną klasą apexową. W tym podejściu zaczynamy wykorzystywać inne wzorce projektowe, w tym adapter. Zacznijmy od prostego przykładu:

contractFactory.js

Obraz 4 – contractFactory.js

Mamy tutaj dwie klasyczne metody – pobranie rekordu z parametrem typu ID oraz zapis rekordu z trzema innymi parametrami:

  • contract – rekord do zapisania;
  • products – lista rekordów do zapisu;
  • deletedProducts – lista z rekordami do usunięcia.

Stworzenie fabryki czy też adaptera jest łącznikiem pomiędzy warstwą LWC oraz warstwą danych, czyli w tym przypadku klasą apexową. Taki podział przynosi kilka korzyści. Po pierwsze, rozdzielenie warstw jest samo w sobie dobrą praktyką. W poszczególnych modułach nie musimy importować metody back-endowej, znać jej  struktury i parametrów. Oczywistą zaletą jest też przejrzystość oraz unikanie redundancji kodu.

Mniej oczywiste zalety można zauważyć w rzeczywistych sytuacjach w projektach. Przeanalizujmy bardzo częste zadanie programisty front-endowego: „Zaimplementuj funkcjonalność edycji rekordu”. Warstwa danych już istnieje i nie mamy możliwości jej zmiany.

Klasa zawierająca niezbędne metody wygląda następująco:

klasa zawierająca niezbędne metody

Obraz 5 – klasa zawierająca niezbędne metody

Funkcja saveIt ma jeden parametr wejściowy typu string, który jest deserializowany do klasy ContractWrapper. Nic nie znacząca nazwa oraz parametry to klasyczny przykład złych praktyk deweloperskich. Niby wszyscy o tym wiedzą, a jednak taki kod widujemy na co dzień, w szczególności w starych projektach. Najlepiej byłoby, realizując nasze zadanie frontowe, zmienić też warstwę danych. Niestety, z różnych względów nie zawsze jest to możliwe. W naszym zadaniu funkcję saveIt oraz inne z klasy EditContractController będziemy musieli wywoływać w różnych miejscach kodu. Wywoływanie za każdym razem metody saveIt oraz serializacja danych na pewno nie jest dobrym rozwiązaniem. W takim przypadku z pomocą przychodzi fabryka.

metoda saveContract

Obraz 6 – metoda saveContract

Kiedy mamy już tak zaimplementowaną fabrykę, wystarczy w modułach importować i wywoływać metodę saveContract. Metoda ta ma dwa oczywiste parametry, a  jej nazwa spełnia wymagania samodokumentującego się kodu.

Sytuacji podobnych do tych opisanych powyżej jest zdecydowanie więcej, ale zawsze rozwiązanie sprowadza się do modularyzacji i uwspólniania kodu. Zbudowanie fabryki – adaptera ułatwia nie tylko pisanie kodu. Dużo więcej zyskamy podczas zadań utrzymaniowych oraz takich, które wiążą się z refaktoryzacją kodu. Wróćmy do przykładu z metodą saveIt i odwróćmy sytuację. Programista back-endowy dostaje zadanie optymalizacji kodu klasy EditContractController. Dzięki istniejącej fabryce zmiany frontowe ograniczą się tylko do jednego miejsca, a to oznacza czystą oszczędność czasu oraz minimalizuje możliwość wystąpienia błędów.

 

Korzyści ze stosowania fabryk w Lightning Web Components

Reasumując, główne zalety fabryk to:

  • modularyzacja;
  • unikanie duplikowanego kodu;
  • standaryzacja nazewnictwa;
  • łatwość refaktoryzacji.

To tylko część możliwości wykorzystania zaproponowanego przeze mnie wzorca podczas pisania modułów Lightning Web Components. Nie pozostaje mi nic innego, jak zachęcić każdego dewelopera do wykorzystywania go na co dzień i odkrywania jego zalet.

Autor
  • Łukasz Czerwiński
  • Salesforce Developer
  • Swoją przygodę z programowaniem zaczynał od Delphi 7. Kolejnym krokiem w świecie kodowania był C# i niedługo póżniej Java oraz javascript. Obecnie zajmuje się głównie technologiami front-endowymi, a znajomość różnych języków programowania, technologii i frameworków, takich jak: ASP.NET, JSF, PrimeFaces, AngularJS czy Lightning, ułatwia mu pracę i dobór odpowiednich narzędzi do powierzonych zadań. Prywatnie miłośnik jazdy na rowerze, który wyznaje zasadę: kilometry same się nie zrobią.

Opracowanie redakcyjne:
Ania Sawicka
Opracowanie redakcyjne
Ola Pasek
Korekta językowa
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.