Większość literatury na temat zwinności wydaje się być stronnicza w stosunku do aplikacji biznesowych typu CRUD, w których użytkownik jest prawie świadomy tego, co dzieje się za kulisami. (W porządku, ponieważ większość pisanego kodu prawdopodobnie należy do tej klasy).
W przypadku tego typu aplikacji związek między historiami użytkowników (wymaganiami) a zadaniami programistycznymi jest w większości prosty: wystarczy podzielić historię użytkownika na kilka zadań.
Istnieje jednak inny rodzaj aplikacji, w którym większość kodu ma do czynienia ze złożonym przetwarzaniem, które nie jest bezpośrednio widoczne dla użytkownika. Przykładami mogą być:
- Kompilatory
- Systemy analizy obrazu samochodów samojezdnych
- Systemy symulacji przepływu płynów
Tutaj relacja zadań i historii użytkowników może być bardzo trudna. Czy istnieją techniki rozwiązania tego problemu, czy jest to coś, co musimy zaakceptować i jak najlepiej wykorzystać?
źródło
Odpowiedzi:
Okazało się, że jest on dłuższy niż planowałem (zaczął jako komentarz), ale mam nadzieję, że dodana długość / szczegóły są pomocne i uważasz je za uzasadnione.
Zwinne nie jest specyficzne dla aplikacji CRUD
Myślę, że dzieje się tak, ponieważ łatwiej jest tworzyć łatwe do naśladowania przykłady tego typu, a nie dlatego, że metodologia jest ukierunkowana na tego rodzaju systemy. Jeśli stworzysz niezbyt łatwy do naśladowania przykład, ryzykujesz, że czytelnik utknie, próbując zrozumieć przykład, kiedy Twoim celem było nauczenie czytelnika o zwinnych koncepcjach.
Historie użytkowników! = Wymagania
Historia użytkownika nie jest tym samym, co wymaganie. To prawda, że może się nakładać w zależności od tego, jak „wysoki poziom” jest wymagany, ale ogólnie nie taki sam. Mam wrażenie, że wpadłeś w tę samą pułapkę, w którą wpadło wielu moich byłych menedżerów: myślenie o historiach użytkowników jako synonimach „wymagań”, podobnie jak w przypadku użytkowników SVN próbujących przejść na Git, ale zachowaj myślenie w kategoriach SVN. (Następnie mają problemy z powodu złych założeń początkowych).
IMHO, kluczowa różnica między wymaganiami a historiami użytkowników polega na tym, że wymagania określają szczegółowo, w jaki sposób powinny zachowywać się niektóre elementy systemu; są to specyfikacje, które obejmują dane wejściowe, wyjściowe, założenia / warunki wstępne, zgłoszone możliwe wyjątki itp. Koncentrują się na tym, co robi system .
OTOH, historie użytkowników koncentrują się na oczekiwanym wyniku dla użytkownika końcowego bez próby stworzenia szczegółowej specyfikacji behawioralnej dla komponentów systemu. Koncentrują się na oczekiwanym doświadczeniu użytkownika .
To, co kiedyś robiłem i to była praktyka, którą mój zespół przyjął, polegało na podziale historii użytkowników na zadania. Twoje zadania mogą być tak szczegółowe lub niejasne, jak chciałeś / potrzebujesz, ale miały one być wskaźnikami postępu w rzeczywistej pracy wykonanej w celu doprowadzenia historii do końca.
Przykład
Z grubsza przypominam sobie USA, nad którymi pracowałem lata temu, w których użytkownicy musieli samodzielnie przypisywać przypadki testowe, aby wszyscy w zespole wiedzieli, nad którymi pracują, aby uniknąć powielania wysiłków; interfejs użytkownika był (n wewnętrzną) aplikacją internetową. Użytkownik widział tylko przycisk, ale historia została podzielona na kilka zadań, które obejmowały pewne szczegóły techniczne dotyczące implementacji itp.
Widoczność użytkownika
Czy można w jakiś sposób uczynić go widocznym dla użytkownika?
Rozważ GPS. Kiedy spóźnisz się na swoją kolej, nie zobaczysz faktycznego procesu ponownego obliczania trasy, ale użytkownik otrzymuje przydatne informacje zwrotne (np. „Ponowne obliczanie ...”).
Kompilatory mogą wyświetlać ostrzeżenia lub błędy lub zawierać nowe ustawienia / opcje w GUI, aby użytkownicy mogli zobaczyć, że dodano coś nowego. Myślałem, że użytkownikami kompilatorów byliby programiści, prawda? Czy nie widzą dodanego wsparcia dla nowego standardu?
Chociaż obsługa nowego standardu prawdopodobnie byłaby na poziomie funkcji i musiałaby zostać podzielona na historie użytkowników, upewnij się, że przynajmniej w niektórych przypadkach nie próbujesz używać historii, gdy powinieneś używać funkcji ?
Analiza obrazu w samochodzie może być sformułowana w sposób, który pozwala użytkownikowi wiedzieć, że szanse na wypadek samochodu zostały zmniejszone. Na przykład:
Jako pasażer w samochodzie samobieżnym potrzebuję prawdopodobieństwa, że pojazd spowoduje wypadek, uderzając w nierozpoznany obiekt tak blisko zera, jak to możliwe, aby móc podróżować bezpieczniej.
To USA przechwytuje, na wysokim poziomie, rzeczy, które normalnie trzeba by określić, używając kombinacji wymagań funkcjonalnych i niefunkcjonalnych - w tym bezpieczeństwa, ochrony itp.
Wymaganie może jednak dotyczyć bardziej systemu; na przykład:
Funkcja
abc
w komponencieA
musi mieć zmniejszoną wartość progową tolerancji w algorytmie porównywania obrazów, aby lepiej wykrywać obiekty poruszające się powoli.Dla mnie byłoby to z łatwością zadanie w ramach wspomnianej powyżej historii użytkownika, zatytułowanej: Zmniejszenie tolerancji działania,
A.abc
a następnie uwzględnienie w niej innych istotnych szczegółów.W przypadku systemu symulacji płynów możesz nawet mieć pasek postępu, który zawiera informacje zwrotne na temat zadań wykonywanych w tle przez system, jeśli ma to sens. (Zawsze istnieje sposób na poinformowanie użytkownika o czymś, chociaż możesz chcieć uniknąć spamowania).
Nie wiem wystarczająco dużo o konkretnych domenach, o których wspomniałeś, aby wymyślić lepsze i / lub bardziej realistyczne przykłady, ale jeśli jest coś na wynos, możesz użyć różnych sposobów przekazywania opinii użytkownikom na temat czegoś mniej widocznego, co system może działać, tzn. mogą istnieć sposoby na uczynienie niewidzialnych rzeczy nieco bardziej widocznymi. (Nawet jeśli sprowadza się do napisania zestawu uwag do wydania, które dokumentują, o ile szybsza jest wydajność systemu dzięki twoim wysiłkom itp.)
Związek między historiami a zadaniami
Nasze podejście polegało na skoncentrowaniu historii użytkowników na tym, co było żądaniem, dlaczego zostało złożone i jakie rzeczy muszą być prawdziwe, aby uznać USA za „zrobione”. To, jak zawsze pozostawiono poza USA i pozostawiono programistom.
Deweloperzy podzielą problem opisany w USA na zestaw zadań, nad którymi będą pracować.
Mówię to jako ktoś, kto w przeważającej części zajmował się programowaniem po stronie serwera, co jest prawdopodobnie tak „niewidoczne”, jak to tylko możliwe dla użytkownika końcowego.
W zależności od tego, co musiałem zrobić, czasami korzystałem z AJAX, aby wyświetlać prostą animację / gif „ładowanie ...”, aby użytkownik wiedział, że musi poczekać chwilę na ukończenie czegoś innego, nie otrzymując złego wrażenia. Czasami było to tak proste. Zadanie do tego byłoby właściwe.
Inny paradygmat, praktyka i doświadczenie
Poza zaakceptowaniem zmiany paradygmatu, ćwiczeniem i gromadzeniem doświadczenia, prawdopodobnie niewiele więcej do powiedzenia. Często widziałem ludzi, którzy próbowali przejrzeć skróty. Odradzałbym to, szczególnie jeśli zaczynasz. W miarę zdobywania doświadczenia możesz pozwolić sobie na pewną elastyczność, ale unikaj osłabiania siebie.
Biorąc pod uwagę poprzednie sformułowania, nadal myślisz o opowiadaniach, jakby były one „przemianowanymi wymaganiami”, co moim zdaniem jest fałszywym założeniem. Myślę, że jest to objaw głębszego problemu dotyczącego podstawowych różnic między podejściami zwinnymi i nieagresywnymi.
Po drugie, uważam, że powinieneś zaakceptować fakt, że zwinność jest zmianą paradygmatu w porównaniu z wodospadem, co oznacza, że chociaż proces ma podobne cele, podchodzą do niego na różne sposoby. (Pomyśl SVN kontra Git, jeśli to pomoże).
Spróbuj poprawić swoje obecne zrozumienie różnic koncepcyjnych między wymaganiami a historiami użytkowników i zaakceptuj, że to nie to samo.
Uczenie się na twoich sprintach - retrospektywy
To, czego nie mogę wystarczająco podkreślić, to retrospekcja między Scrum Master a deweloperami na końcu każdego sprintu. To miejsce, w którym dyskutują o rzeczach, które „poszły dobrze” lub „nie poszły dobrze” w uczciwy / przejrzysty sposób, i jakie możliwe zmiany zostaną wprowadzone w następnym sprincie w celu rozwiązania kwestii „nie poszło dobrze” .
To pozwoliło nam się dostosować, a nawet uczyć się na podstawie doświadczeń innych. Zanim się zorientowaliśmy, znacznie się poprawiliśmy, mierząc ogólną spójność prędkości naszego zespołu.
źródło
W takich przypadkach z pewnością można zastosować zasady zwinne. W jaki sposób?
Nie musisz jeść całego słonia jednym kęsem. Zwinny prosi tylko o pokazanie, że wyczyściłeś talerz przed kolejną porcją słonia.
źródło
Uważam, że ludzie, którzy stosują się wyłącznie do historii użytkowników, albo po prostu wezmą udział w bardzo głupich ćwiczeniach wymyślania dalekosiężnych sposobów, w jakie zmiany techniczne zaplecza wpływają na użytkownika (oczywiście bez wiedzy użytkownika, ponieważ są po prostu naiwniakami użytkownik i mówisz o skomplikowanych zmianach w linii potoku analizy danych lub coś w tym rodzaju), albo całkowicie stracą na tym „jak możemy zorganizować tę pracę!?!”
Myślę, że oczywistym rozwiązaniem jest bycie bardziej pragmatycznym. Jeśli praca ma charakter techniczny i nie ma szczególnie zauważalnego wpływu na użytkownika, nie trać snu, próbując wyjaśnić, jak to działa. Po prostu wybierz oczywisty i prosty sposób, w jaki może przynieść korzyści użytkownikom, a następnie zorientuj historię wokół szczegółów niezbędnych deweloperom do wykonywania swoich zadań. Uważam to za niezwykle frustrujące, gdy organizacja producentów upiera się przy braku informacji technicznych w historii, gdy jest to absolutnie konieczne. To po prostu niezbyt całościowy pogląd na to, czym tak naprawdę jest ten artefakt (historia). Jak myślą, że istnieje tylko dla nich, w większości przypadków jest to ważne również dla inżynierów.
W przypadku większości tych zadań technicznych istnieje niewielka niepewność w odniesieniu do wpływu na użytkownika, niezależnie od tego, czy poprawia to wydajność, aby przyszłe dostawy były szybsze, poprawiając wydajność, wpływ na niezawodność. Nie są tak naprawdę tym, o czym ludzie myślą, gdy myślą „historie użytkowników”, ale jeśli firma chce zrozumieć, dlaczego zaciągnąłbyś dług techniczny lub coś w tym celu, wyjaśnienia te są zwykle najprostsze do przekazania.
tl; dr nie pozwól, aby scrumnazi utrudniły ci życie po prostu dlatego, że są zbyt duże, by się przystosować. Bycie adaptacyjnym to w końcu podstawowa koncepcja zwinności. Ścisłe przestrzeganie Scruma lub Agile zwykle leci w twarz lub pragmatyzm i praktyczność (co tak naprawdę działa najlepiej).
źródło
Myślę, że problemem jest nadanie historyjkom użytkowników znaczenia, którego nie mają. Scrum używa terminu PBI lub Backlog Produktu, który moim zdaniem jest nieskończenie lepszy. PBIS będzie często wykonaj format historię użytkownika, na przykład, może masz PBI jak „Abonenci powinni móc przeglądać swoje dane abonamentu”, ale również może równie dobrze mieć PBI jak „Utwórz procedurę przechowywaną, aby uzyskać dane abonenta „.
Historie użytkowników są narzędziem . Pomagają ci tworzyć opisy funkcji i wymagania oparte na postawieniu się w sytuacji użytkownika. Ale tak jak klucz jest bezużyteczny, gdy trzeba zawiesić zdjęcie, zdarza się, że historia użytkownika może nie być potrzebna.
To powiedziawszy, wiele drużyn gra po prostu szybko i swobodnie z częścią „użytkownika”. Mogą mieć „historie użytkowników”, takie jak „Jako programista, muszę mieć możliwość wywołania procedury składowanej w celu uzyskania szczegółów subskrybenta”, zasadniczo „historii programisty”. Jest to równie ważna opcja, ale osobiście twierdzę, że tak długo, jak potrafisz opisać, co należy zrobić, i wymyślić zestaw kryteriów akceptacji, nie ma znaczenia, czy masz za nią prawdziwą historię użytkownika.
źródło
Tego rodzaju aplikacje są dokładnie tymi, w których występuje różna wiedza specjalistyczna i będą się dalej rozwijać. Członkowie zespołu będą mieli zróżnicowane wykształcenie, różne projekty hobbystyczne i różne doświadczenia zawodowe w przeszłości, różne umiejętności. Ponadto, jeśli ktoś opracuje określony fragment kodu, można oczekiwać, że programista będzie tym, który zna kod najlepiej. Dlatego sensowne może być przekazanie tego samego dewelopera dalszym zadaniom programistycznym obejmującym ten sam fragment kodu.
W najpopularniejszym zwinnym procesie Scrum planuje się pokera, w którym do każdego zadania przypisany jest poziom trudności. Poziom trudności nie zależy od osoby, która wykonuje to zadanie zgodnie z procesem. Następnie podczas sprintu ludzie są uważani za jednorodnych, dzięki czemu każda osoba będzie mogła wybrać każde zadanie i je zrealizować. To założenie obowiązuje w prostych projektach typu CRUD. Ale w bardzo złożonych i trudnych projektach na pewno nie.
Nie użyłbym zwinnego procesu do tego rodzaju projektów. Najlepszym wyborem jest unikanie formalnych procesów i po prostu dobre zarządzanie projektami. Decydując, kto wdraża daną funkcję, należy wziąć pod uwagę, kto ma najlepsze umiejętności potrzebne do tej funkcji i najlepszą znajomość istniejącego kodu. Nie jest do tego potrzebny żaden proces. Prawdopodobnie będziesz chciał napisać dobre dokumenty projektowe dla wszystkich funkcji i aktualizować je. Pamiętaj, że nie promuję tutaj modelu przypominającego wodospad: nie wszystkie dokumenty projektowe zostaną napisane na początku projektu; zamiast tego napiszesz nowe dokumenty projektowe, ponieważ potrzebne są nowe funkcje.
źródło