Przeczytaj wersję webową.

Rozszerzalny produkt – czyli jaki?

2024-07-25

Cześć!

Po poprzednich epopejach związanych z Pull Request Review bierzemy na tapet mniejszy temat. Co nie znaczy, że mniej istotny.

Porozmawiamy dziś o rozszerzalności. Co dla nas oznacza i jak ją definiować w ramach naszych produktów.

Standardowo czeka na Ciebie też Inżynierska prasówka.

A więc w dzisiaj mam dla Ciebie:

Miłego czytania 😀


Inżynierska prasówka

W dzisiejszym wydaniu chcę Ci polecić materiały z 3 zaprzyjaźnionych newsletterów – o AI, ewolucji architektury i długu technologicznym. A dodatkowo znalazło się też miejsce na wdrażanie multi-tenancy i Google, który ubija produkty ☠️

  1. Barriers to AI adoption – Adi Noda
    Wiele firm inżynierskich stara się wdrożyć AI do swojej codziennej pracy. Nie wszystkim się to jednak udaje.
    Adi Noda analizuje badanie naukowe „AI Tool Use and Adoption in Software Development by Individuals and Organizations”. Szczególnie wartościowy jest podział wyzwań na te ze strony indywidualnej i organizacyjnej. Jak się okazuje, organizacja ma kluczowy wpływ na to, czy inicjatywa AI w ogóle ruszy.
    https://newsletter.getdx.com/p/barriers-to-ai-adoption-engineering

  2. Don’t Stand Still: Evolve Your Architecture – Maciej MJ Jędrzejewski
    Temat poruszałem luźno na LinkedIn przy okazji polecania książki Evolutionary Architecture. Teraz szerzej wraca z nim MJ.
    Opisuje jak ważne jest myślenie o ewolucji architektury podczas rozwoju swojego systemu. Wraz z upływem czasu zmieniają się docelowe atrybuty jakościowe. Jeśli nasza architektura za tym nie nadąża, to mamy duży rozdźwięk pomiędzy tym co chcemy, a tym co ona dostarcza.
    https://newsletter.fractionalarchitect.io/p/17-dont-stand-still-evolve-your-architecture>

  3. Optimizing Your “20% Time for Technical Debt” – Mirek Stanek
    Część firm strategicznie przeznacza 20% czasu na pracę z długiem technologicznym i utrzymaniem produktu. Ale zdecydowana większość nie osiąga z tego zakładanych zysków. Dlaczego?
    Mirek świetnie przedstawia błędne założenia dookoła pracy z długiem. Musimy lepiej sprzedawać nasze inicjatywy, skupiać się na konkretnych obszarach, równolegle unikać powiększania długu. Tylko wtedy nasze inicjatywy rzeczywiście przyniosą wartość organizacji.
    https://www.practicalengineering.management/p/optimizing-your-20-time-for-tech-debt

  4. Multi-tenant apps with single-tenant SQLite databases - Szymon Mentel
    Trochę technicznego mięsa. Na WarsawJS Szymon wystąpił z prezentacją o przeprowadzeniu podziału multi-tenant istniejącego systemu.
    Wartościowa prezentacja o tym, jak wprowadzić izolację klientów krok po kroku. Masa przykładów, diagramów, oceny zalet i wad. Świetne jako wprowadzenie dla nowych osób wyjaśniające, czego wymaga taki podział.
    https://www.youtube.com/watch?v=x-hgJj14Xcg

  5. Google appears to randomly cancel old products – why?
    W świecie Google pojawiła się kolejna drama. Firma zdecydowała się zakończyć pracę usługi URL Shortener – goo.gl. Co zabawne, przekierowała klientów na inną usługę Firebase Dynamic Links, która również jest wygaszana 😅
    Jednak to co jest istotne to opis użytkownika xlr8harder i dyskusja poniżej. Przedstawiony został obraz Google jako firmy, gdzie system wynagradzania jest tak ustawiony, że nie opłaca się utrzymywać długofalowo serwisów. Co powoduje, że firma masowo porzuca to co stworzyła.
    Jest to ważna lekcja dla wszystkich osób, które określają wskaźniki oceny dla pracowników / produktów. Jeśli źle wybierzecie wskaźniki, to będziecie mieli bardzo nietypowe, odsunięte w czasie konsekwencje.
    https://x.com/xlr8harder/status/1814195097887502403


Czym jest rozszerzalność?

Standardowo, zanim przejdziemy do rozwiązań, skupmy się chwilkę na zrozumieniu problemu.

Problem z ogólnym pojęciem

Rozszerzalność produktu - temat, który często pojawia się w rozmowach między biznesem a zespołami technicznymi. Słyszymy:

Nasz produkt musi być rozszerzalny.

Brzmi sensownie, prawda? W końcu kto nie chciałby mieć elastycznego rozwiązania, które można łatwo dostosować do zmieniających się potrzeb? Problem w tym, że samo stwierdzenie “rozszerzalny” nie mówi nic 😅

Co dokładnie oznacza “rozszerzalny” w kontekście danego produktu?

  • Dla biznesu może to oznaczać możliwość dodawania nowych funkcji bez większego wysiłku.
  • Dla zespołu technicznego może to być łatwe dodawanie kolejnych komponentów.
  • A może chodzi o łatwość integracji z zewnętrznymi systemami?

Bez zdefiniowania tego pojęcia, każda grupa może interpretować je na swój sposób. Zespół techniczny może skupić się na aspektach, które uważa za kluczowe dla rozszerzalności, podczas gdy biznes ma na myśli coś zupełnie innego. W rezultacie końcowy produkt może nie być rozszerzalny dla żadnej ze stron.

Dodatkowo rozszerzalność (podobnie jak inne atrybuty jakościowe) jest trudniejsza do wychwycenia niż pojedyncza funkcja. W ferworze dostarczania kolejnych “ficzerów” produktu, nierzadko przestajemy się skupiać na rozszerzalności, ponieważ jej po prostu nie rozumiemy. Co sprawia, że po roku budzimy się z systemem, który nie jest nawet w 1% rozszerzalny.

Aby sobie z tym poradzić zobaczmy najpierw czym są atrybuty jakościowe i jak z nimi pracować.

Atrybuty jakościowe

Ok, skoro już wiemy, że z rozszerzalnością jest problem, to może warto cofnąć się o krok. Czym właściwie są atrybuty jakościowe?

Atrybuty jakościowe to nie “CO”, a “JAK” naszego produktu. Mówiąc inaczej:

  • Funkcje mówią nam, CO produkt robi.
  • Atrybuty jakościowe określają, JAK produkt to robi.

Atrybutów jakościowych możemy zdefiniować bardzo wiele, tutaj kilka z mojego ebooka „Drivery architektoniczne w twoim zespole”:

IMG1.png

Z atrybutami jakościowymi jest jeden istotny problem - nie da się o nich rozmawiać tak, jak o funkcjach. Nie możemy zwyczajnie powiedzieć “dodajmy rozszerzalność” tak, jak mówimy “dodajmy nowy przycisk”.

To sprawia, że musimy podejść od innej strony do definicji atrybutów. Musimy sięgnąć po czasowniki! Spójrzmy na bazowy przykład:

Produkt ROZSZERZA SIĘ o nową funkcję w czasie krótszym niż tydzień pracy jednego developera.

Widzisz różnicę? Nie mówimy, że produkt “jest rozszerzalny”. Mówimy jak szybko i łatwo możemy go rozszerzać. A to już coś, co można zmierzyć i ocenić! 📏

Jednocześnie pewnie zauważyłeś już lukę, którą można podsumować:

Nie ma czegoś takiego jak “uniwersalne” rozszerzanie się.

Każdy produkt jest rozszerzalny…, ale tylko w określonych kierunkach. Dlatego tak ważne jest, by dokładnie określić, w jakich obszarach nasz produkt ma być elastyczny.

W kolejnych etapach przyjrzymy się, jak to wygląda w praktyce. Bo teoria teorią, ale nic tak nie przemawia do wyobraźni jak konkretne przykłady, prawda? 😉

Rzeczowniki i ich liczność

Wyobraźmy sobie, że budujemy system monitoringu. Biznes przedstawia nam następujące założenie:

W naszym systemie będziemy mieli X stacji monitoringu od Y partnerów, które dostarczają Z parametrów pogodowych.

Brzmi prosto, prawda? Jednak umyka nam istotny fakt. Zamiast od razu przystępować do implementacji, warto zatrzymać się na moment i zadać kilka kluczowych pytań:

  1. Jak szybko będzie rosła liczba stacji monitoringu (X)?
  2. Jak często będziemy dodawać nowych partnerów (Y)?
  3. Czy będziemy dodawać nowe parametry (Z)?

IMG2.png

Najważniejsze jednak: ile czasu powinno nam zająć dostosowanie systemu do tych zmian? Kogo będziemy do tego potrzebować?

Rozważmy dwa scenariusze:

  • Jeśli liczba stacji rośnie o 1000 rocznie, nasz system musi się łatwo rozszerzać w tym kierunku. W przeciwnym razie większość czasu spędzimy na ręcznym dodawaniu nowych stacji. Stracimy absurdalną ilość czasu pracowników operacyjnych.
  • Ale jeśli nowych partnerów mamy tylko 1-2 rocznie? W tym wypadku możemy nie potrzebować w pełni zautomatyzowanego systemu onboardingu. Wystarczy, że nasi programiści będą w stanie stosunkowo łatwo rozszerzyć produkt o nową integrację.

Widzisz różnicę? Dla jednego rzeczownika potrzebujemy pełnej automatyzacji, w innym wystarczy, że system będzie “częściowo rozszerzalny” - da się go rozszerzyć, ale może to wymagać pewnego nakładu pracy programisty.

Kluczem jest zrozumienie, gdzie nasza rozszerzalność ma największe znaczenie. Rzeczowniki i ich ilość jest dobrym startem w myśleniu o rozszerzaniu produktu.

Systemy zewnętrzne

„Rozszerzmy” nieco poprzedni przykład. 😃

Rozszerzalność w kontekście systemów zewnętrznych to kluczowy aspekt, który musimy brać pd uwagę przy planowaniu rozwoju produktu. Jak pisał Brandon Byars u Fowlera: You can’t buy integration. Przyjrzyjmy się temu na konkretnym przykładzie.

Wyobraź sobie, że tworzysz produkt dla firm, w ramach którego ich pracownicy mogą logować się poprzez swoje konta firmowe. Początkowo pracujemy głównie z firmami korzystającymi z ekosystemu Microsoft. Naturalne wydaje się więc zintegrowanie z Azure AD (czy też, jak to teraz nazywają, Microsoft Entra ID). To szybkie i skuteczne rozwiązanie dla naszych pierwszych klientów.

Warto zatrzymać się jednak na moment i zadać sobie pytanie o rozszerzalność:

Czy wszystkie firmy, które potencjalnie mogą być naszymi klientami, korzystają ze stacka Microsoftu?

To pytanie prowadzi do kolejnych rozważań:

  • Co z firmami korzystającymi z Google Workspace?
  • A co z tymi, które mają własne, wewnętrzne systemy uwierzytelniania?

IMG3.png

Na początku naszej drogi produktowej, prawdopodobnie postawimy na szybkość dostarczenia rozwiązania. Zintegrujemy się z jednym, najbardziej popularnym wśród naszych klientów systemem. To zrozumiałe - chcemy szybko wejść na rynek i zacząć zbierać feedback.

Jednak w dłuższej perspektywie, rozszerzanie o kolejne systemy zewnętrzne staje się kluczowe. Ignorowanie tego aspektu prowadzi do sytuacji, w której tracimy potencjalnych klientów tylko dlatego, że nie jesteśmy w stanie zintegrować się z wymaganym systemem zewnętrznym.

Dlatego też większość dojrzałych narzędzi B2B oferuje kilka opcji uwierzytelniania. Przykładowo Miro - popularne narzędzie do współpracy online - oferuje integrację z wieloma systemami SSO, co pozwala im dotrzeć do szerszego grona klientów.

Podobnie jest w przypadku platform e-commerce. Jeśli spojrzymy na Allegro, zobaczymy, że oferuje ono różne systemy dostaw i płatności. Firma nie ogranicza się do jednego dostawcy czy jednego operatora płatności. Dlaczego? Bo rozumie, że różni klienci mają różne preferencje i potrzeby.

Co to oznacza dla nas jako twórców produktu?

  1. Na początku możemy skupić się na jednej, najbardziej popularnej integracji, aby szybko wejść na rynek.
  2. Jednak już na etapie projektowania powinniśmy myśleć o tym, czy i jakie w przyszłości możemy potrzebować systemy zewnętrzne.
  3. Jeśli w najbliższych planach znajdują się integracje z kolejnymi systemami to warto zanalizować koszty stworzenia abstrakcji. Pozwoli to odpowiednio wcześnie podjąć decyzję o rozszerzalności produktu.

Pamiętajmy, że rozszerzalność w tym kontekście to nie tylko kwestia techniczna. To strategiczna decyzja biznesowa, która może znacząco wpłynąć na naszą zdolność do pozyskiwania nowych klientów i wchodzenia na nowe rynki.

Proces główny i procesy podrzędne

Teraz przejdźmy do nieco bardziej złożonego scenariusza.

Wyobraźmy sobie, że budujemy system sprzedaży biletów lotniczych. Podstawowy proces to oczywiście zakup biletu. Ale co, jeśli chcemy oferować dodatkowe usługi? Transfer na lotnisko, ubezpieczenie podróżne, dodatkowy bagaż… Lista będzie długa i może się jeszcze powiększać.

Wtedy pojawia się kluczowe pytanie o rozszerzalność:

Czy dodanie nowego produktu dodatkowego wymaga zmian w głównym procesie sprzedaży?

Jeśli odpowiedź brzmi “tak”, to wskazuje problem. Wyobraź sobie, że za każdym razem, gdy chcesz my dodać nową opcję, musisz zacząć grzebać w sercu naszego systemu. To jak otwieranie silnika samochodu, żeby dodać nowy przycisk na desce rozdzielczej! 🔧🚗

Co zatem z tym zrobić? Celem powinno być takie zaprojektowanie procesu nadrzędnego (sprzedaż biletu), by elementy podrzędne (dodatkowe usługi) mogły być dodawane i modyfikowane bez wpływu na główny proces.

IMG4.png

Jak to może wyglądać w praktyce? Opcji jest sporo.

  1. Główny proces może zawierać ogólny “krok” na dodatki, nie wiedząc dokładnie, jakie one będą.
  2. Każdy dodatek może być implementowany jako osobny moduł, z własną logiką i interfejsem.
  3. System może dynamicznie ładować dostępne dodatki, bez konieczności modyfikacji głównego kodu.

Dzięki takiemu podejściu:

  • Możemy rozszerzać nowe produkty dodatkowe bez dotykania głównego procesu sprzedaży.
  • Zespoły odpowiedzialne za różne dodatki mogą pracować niezależnie.
  • Testowanie i wdrażanie nowych opcji stają się prostsze i bezpieczniejsze.

To właśnie jest przykład wartościowej rozszerzalności. Nasz produkt jest gotowy na przyszłe zmiany produktowe, nawet jeśli nie wiemy dokładnie, jakie to będą zmiany.

Rozwój niezależny obszarów

Podstawy mamy już za sobą, wejdźmy więc na jeszcze wyższy poziom abstrakcji. Mówimy już nie tylko o pojedynczych procesach, ale o całych obszarach funkcjonalnych naszego systemu.

Wyobraź sobie, że tworzymy produkt dla sieci laboratoriów medycznych. Główne obszary to:

  1. Sklep online - tu klienci zamawiają badania.
  2. Laboratorium - tu wykonuje się badania.

Na pierwszy rzut oka mogłoby się wydawać, że najłatwiejszym rozwiązaniem jest bezpośrednie połączenie tych dwóch obszarów. Klient składa zamówienie, to zamówienie trafia do laboratorium, laborant wykonuje badanie. Wydaje się proste…

Ale czy na pewno rozszerzalne?

Zastanówmy się:

  • Co, jeśli chcemy dodać nowe źródło zamówień, np. sklep partnera?
  • Co, jeśli laboratorium chce wykonywać badania nie tylko na podstawie zamówień online? Np. w ramach barteru wykonamy badanie za darmo.
  • Co, jeśli w przyszłości będziemy chcieli współpracować z innymi sieciami laboratoriów?

Jeśli nasze obszary są ściśle ze sobą splecione, każda taka zmiana będzie wymagała modyfikacji w obu obszarach naraz.

Jak więc zaprojektować produkt tak, by był bardziej rozszerzalny?

IMG5.png

Kluczem jest wprowadzenie abstrakcji, która oddzieli te dwa obszary. Zamiast operować na konkretnych “zamówieniach”, możemy wprowadzić pojęcie “zlecenia badania”.

  • Sklep generuje zamówienia.
  • Mechanizm centralny przekształca zamówienia w zlecenia badań.
  • Laboratorium pracuje na zleceniach, nie wiedząc (i nie potrzebując wiedzieć) skąd one pochodzą.

Dzięki takiemu podejściu:

  1. Możemy łatwo dodawać nowe źródła zamówień (sklep internetowy, aplikacja mobilna, partnerzy zewnętrzni) - wszystkie będą generować zlecenia w tym samym formacie.
  2. Laboratorium może przyjmować zlecenia z różnych źródeł, nie tylko z naszego sklepu.
  3. Możemy łatwo rozszerzyć system o współpracę z zewnętrznymi laboratoriami, kierując do nich zlecenia w ich formacie.

Tak właśnie wygląda esencja rozszerzalności na poziomie całego produktu. Nie wiemy dokładnie, jak nasz biznes będzie się rozwijał w przyszłości, ale projektujemy system tak, by był gotowy na różne scenariusze.

Pamiętajmy jednak, że takie podejście wymaga większego nakładu pracy na początku. Trzeba dobrze przemyśleć model współpracy pomiędzy obszarami. Ale ta inwestycja zwraca się z nawiązką, gdy przychodzi czas na rozbudowę produktu.

Podsumowanie

Rozszerzalność to podstępna bestia. Ale można ją okiełznać. Trzeba tylko zadawać lepsze pytania. Mam nadzieję, że tymi przykładami pokazałem Ci jak dobrze rozpocząć z nią pracę.

A u Ciebie, jak jeszcze rozumie się rozszerzalność? Daj znać w odpowiedzi :)


📧 Prześlij dalej

Dzięki, że doczytałeś(aś) do końca. 😊

Wszystkie poprzednie wydania newslettera są dostępne tutaj.

Jeśli spodobał Ci się mój newsletter, prześlij go proszę osobom, którym też mógłby się spodobać. Z góry dziękuję.

A jeśli nie jesteś jeszcze w newsletterze, to zachęcam do zapisania się.

Polecam się na przyszłość!
Radek Maziarka

Radek Maziarka
"Inżynierskie podejście do produktów cyfrowych."

P.S. Co myślisz o tym newsletterze? Odpisz :)