Diagram aktywności UML odpowiedzią na “a gdzie ja mam to dopisać?”

By 22 August 2014 October 15th, 2016 ITlogy

Pytanie z tytułu zna chy­ba każdy, dopiero zaczy­na­ją­cy swo­ją naukę pro­gramowa­nia, człowiek. Napisało się już trochę kodu, chce się dodać do niego kole­jne “funkcjon­al­noś­ci”, ma się już nawet kod i abso­lut­nie brak pomysłów, gdzie powin­no się go umieś­cić. Kuba może potwierdz­ić, że  ostat­nio najczęś­ciej zadawanym przeze mnie pytaniem było: ale gdzie to napisać? Po przeczy­ta­niu tuto­ri­alu ora­cle (jako, że jestem trochę dalej niż lekc­je na blogu nie mogę korzys­tać z tych pisanych przez Kubę), zapoz­na­niu się z zadaniem i napisa­niu /wyszukaniu na stack­over­flow rozwiąza­nia miałam zazwyczaj dość sporą niepewność gdzie to wszys­tko umieś­cić. Cza­sa­mi poma­gała odpowiedź na pyta­nia: Co to ma robić? Z czym?, ale gdy licz­ba linii kodu rosła, te dwa pyta­nia coraz częś­ciej nie wystar­cza­ły. Na odsiecz przyszły dia­gramy UMLowe, o których poczy­tasz poniżej.

UML czyli Unified Modeling Language

Służy do opisy­wa­nia — mod­e­lowa­nia frag­men­tu ist­niejącej rzeczy­wis­toś­ci (np. dzi­ału w fir­mie, jakiegoś pro­ce­su czy wycin­ka sys­te­mu), albo pro­jek­towa­nia i anal­izy czegoś, co dopiero ma pow­stać — np. sys­temów infor­maty­cznych. Nieodłącznym jego ele­mentem są dia­gramy i to właśnie o jed­nym z nich będzie ten wpis. Jeśli jesteś bardziej zain­tere­sowana samym UMLem to odsyłam cho­ci­aż­by do Wikipedii.

Activity Diagram

Czyli po pol­sku dia­gram czyn­noś­ci lub akty­wnoś­ci służy do przed­staw­ienia krok po kroku jakie czyn­noś­ci są wykony­wane. Nie opisu­je szczegółów jak te czyn­noś­ci są wykony­wane a jedynie pokazu­je w jakiej kole­jnoś­ci i kiedy. Dzię­ki swo­jej budowie pokazu­je, jakie są akc­je, a także jak są one połąc­zone (co w przełoże­niu na pytanie z tytułu pozwala nam dokład­nie ułożyć nasze frag­men­ty kodu w odpowied­niej kole­jnoś­ci). W dal­szej częś­ci będziemy korzys­tać z pod­sta­wowych ele­men­tów diagramu:

  • zaokrą­glonych pros­tokątów reprezen­tu­ją­cych akcje
  • pros­tokątów reprezen­tu­ją­cych obiekty
  • rom­bów reprezen­tu­ją­cych decyzje
  • belek reprezen­tu­ją­cych rozwi­dle­nia i łączenia dzi­ałań jednoczesnych
  • czarne kółko reprezen­tu­jące początek (zainicjowanie)
  • czarne kółko w białym kole reprezen­tu­jące koniec (stan końcowy)

Oczy­wiś­cie, może się okazać, że w Twoim przy­pad­ku potrze­bu­jesz innego ele­men­tu dia­gra­mu, opisy innych ele­men­tów zna­jdziesz w sekcji mate­ri­ały dodatkowe. Przykład­owy dia­gram akty­wnoś­ci zna­j­du­je się poniżej (jakże znany ze stron www naszych wykładowców).

Przykładowy diagram aktywności

Przykład­owy dia­gram aktywności

W tym miejs­cu jeszcze parę słów, które Kuba kazał mi napisać i pod­kreślić: UML (jak i dowolne inne metody­ki) są po to, żeby pomóc nam w pro­jek­cie. W sytu­acji kiedy chce­my dodać dodatkową infor­ma­cję, notację itp, doda­jmy ją, nieza­leżnie od tego czy jest zgod­na ze stan­dar­d­em czy nie. UML to wspól­ny język dla wielu osób, co ma ogromne znacze­nie w pro­jek­tach przy których pracu­ją set­ki osób. W mniejszych pro­jek­tach najwazniejsze żeby wszyscy członkowie zespołu rozu­mieli dia­gram i infor­ma­c­je w nim zawarte. Jeśli trud­no wyraz­ić Ci intenc­je w stan­dar­d­owym UML, a wszyscy zain­tere­sowani rozu­mieją wprowad­zone przez Ciebie zmi­any i odstępst­wa, nie krępuj się. UML ma pomóc Tobie i w razie potrze­by dopa­sowac sie do Ciebie, a nie Ty do UMLa.

Activity diagram w praktyce

Ponieważ najłatwiej omaw­iać coś na przykładzie, prze­jdźmy do mod­e­lowa­nia naszego wycin­ka rzeczy­wis­toś­ci :) Zostaw­iliśmy ostat­nio naszego kota pod opieką zna­jomego i troszkę mu się przy­brało między przed­ni­mi a tyl­nimy łap­ka­mi. Naszym zadaniem będzie stworze­nie aplikacji, która będzie chronić lodówkę przed Tes­lą. Aplikac­ja ma zapy­tać użytkown­i­ka o imię, i jeśli podane imię to Tes­la, ma wyświ­etlić poucze­nie o diecie, w prze­ci­wnym wypad­ku wyświ­etlić hasło do lodów­ki (przyjmi­jmy, że to takie odrobinę zmody­fikowane “hel­lo world”, z którym na pewno już się spotkałaś). Pier­wszym krok­iem w stworze­niu activ­i­ty dia­gra­mu jest wyp­isanie wszys­t­kich czyn­noś­ci, które musimy wykon­ać w naszym programie:

  • wczy­tanie imienia użytkownika
  • sprawdze­nie, czy to nie Tesla
  • wyświ­etle­nie “jesteś na diecie”
  • wyświ­etle­nie hasła do lodówki

Następ­nie sprawdza­my, w których czyn­noś­ci­ach pojaw­ia­ją się jakieś obiekty/dane na wejś­ciu lub wyjś­ciu. Poprzez dane rozu­miemy dowol­ną infor­ma­cję — np. aby wczy­tać imię użytkown­i­ka nie potrze­bu­je­my żad­nej infor­ma­cji (nie mamy nic na ‘wejś­ciu’), ale akc­ja ta daje nam ciąg znaków — imię — na wyjś­ciu. Z kolei sprawdze­nie, czy to nie Tes­la, wyma­ga na wejś­ciu ciągu znaków — imienia — a na wyjś­ciu daje nam infor­ma­cję prawda/fałsz (flagę), czy to fak­ty­cznie Tes­la. Podsumowując:

  • Wczy­tanie imienia nie ma nic na wejś­ciu, nato­mi­ast na wyjś­ciu ma obiekt String imię.
  • Sprawdze­nie czy to Tes­la, ma na wejś­ciu String imię, a na wyjś­ciu boolean (tak/nie).
    • W przy­pad­ku tak, wyświ­et­lamy “jesteś na diecie”,
    • w przy­pad­ku nie hasło do lodówki
Gotowy diagram aktywności dla programu chroniącego lodówkę

Gotowy dia­gram akty­wnoś­ci dla pro­gra­mu chroniącego lodówkę

Takie rozpisanie naszej aplikacji ułatwia ułoże­nie poszczegól­nych ele­men­tów, bo dostrzegamy zależnoś­ci pomiędzy nimi. Na pod­staw­ie tego opisu kon­stru­u­je­my nasz dia­gram akty­wnoś­ci. Ważne jest to, by wszys­tkie obiek­ty czy dane były w odpowied­nich miejs­cach. Przeanal­izu­jmy go krok po kroku, doda­jąc poszczególne ele­men­ty kodu: Wczy­taj imię to akty­wność, która pyta użytkown­i­ka o imię. Nie zaw­iera żad­nych danych wejś­ciowych, ale na wyjś­ciu ma daną w postaci String imię. (meto­da getUser­In­put() to nasza funkc­ja, która po pros­tu zwraca lin­ijkę wpisaną przez użytkownika).

System.out.println("Cześć jak masz na imię?"); 
userInput = getUserInput();

Tej danej potrze­bu­je­my do sprawdzenia czy to Tes­la. W bloku decyzyjnym String imię to dana wejś­ciowa, a daną wyjś­ciową jest boolean (fla­ga tak/nie).

if (userInput.equalsIgnoreCase("Tesla"))
{
     //tutaj powinien być fragment kodu jeśli użytkownik to Tesla
} else {
    //tutaj powinien być fragment kodu jeśli użytkownik nie jest Teslą.
}

W zależnoś­ci od wyniku tes­tu, nasz pro­gram wyświ­etli hasło do lodów­ki albo poucze­nie o diecie.

System.out.println("SuperTajneHasloDoLodowki"); //akcja do wykonania jeśli to nie Tesla
System.out.println("Jesteś na diecie"); // akcja do wykonania, jeśli to Tesla

W rezulta­cie nasz frag­ment kodu wyglą­da następująco:

System.out.println("Cześć jak masz na imię?");
userInput = getUserInput();
if (userInput.equalsIgnorcase("Tesla") {
    System.out.println("Jesteś na diecie");
} else {
    System.out.println("SuperTajneHasloDoLodowki");
}

Oczy­wiś­cie nie jest to dzi­ała­ją­cy kod, poniżej pełny kod całej klasy (aplikacji):

import java.util.Scanner;
public class Lodowka {
    static Scanner sc = new Scanner(System.in);
    public static void main(String[] args) {
        String userInput = "";
        System.out.println("Cześć jak masz na imię?");
        userInput = getUserInput();
        if (userInput.equalsIgnorCase("Tesla")) {
            System.out.println("Jesteś na diecie");
        } else {
            System.out.println("SuperTajneHasloDoLodowki");
        }
    }
    
    public static String getUserInput() {
        return sc.nextLine().trim();
    }
}

Metodę tą moż­na również stosować dla ist­niejącego kodu, gdy chce­my dodać do niego nowy ele­ment. Bard­zo fajną metodą nau­ki jest pisanie odpowied­nich frag­men­tów kodu na post-itach /w Wordzie /notatniku i następ­nie przek­le­janie ich w odpowied­niej kole­jnoś­ci na kartce papieru. Dzię­ki temu, po ułoże­niu naszych karteczek w odpowied­niej kole­jnoś­ci wystar­czy właś­ci­wie przepisać kod bezpośred­nio do naszego programu.

Przygotowanie diagramu aktywności za pomocą post-itów

Przy­go­towanie dia­gra­mu akty­wnoś­ci za pomocą post-itów

 

Budowanie diagramu dla problemu krok po kroku

Prześledźmy zatem, jak zbu­dować taki dia­gram krok po kroku, na nieco bardziej skom­p­likowanym przykładzie. Najpierw określmy sobie prob­lem. Niech będzie nim kon­wert­er walut — wczy­tu­je­my od użytkown­i­ka kurs walu­ty, ilość walu­ty a następ­nie wyświ­et­lamy użytkown­ikowi oblic­zoną wartość.

Krok 1 — wypisanie elementów które mamy (elementy wymagane)

W naszym przy­pad­ku jest to:

  • wczy­taj kurs (brak danych na wejś­ciu, na wyjś­ciu: kurs)
  • wczy­taj ilość (in: -, out: ilość)
  • oraz oblicz (in: ilość, kurs, out: wartość).

Należy jed­nak pamię­tać, że infor­ma­c­je pobier­ane od użytkown­i­ka są zawsze na początku zapisy­wane jako String. Będziemy wiec musieli zamienić je na for­mat liczbowy ( o którym było mowa w lekcji #01), co powodu­je, że mamy jeszcze:

  • zamień kurs na f. liczbowy (in: String kurs, out: f.liczbowy kurs)
  • zamień ilość na f. liczbowy (in: String ilość, out: f.liczbowy ilość)

Krok 2 — wypisanie elementów które będziemy potrzebowali lub dla których znamy kod (elementy opcjonalne)

Aby wczy­tać kurs i ilość korzys­tamy z metody getUser­In­put() (która była omówiona w lekcji #02). Aby dokon­ać kon­wer­sji String na f.liczbowy (zas­tanów się, jaki for­mat powinien mieć kurs, a jaki ilość) korzys­tamy w odpowied­niej metody, tu może pomóc Stack­over­flow (dla iloś­ci: String2Integer albo dla kur­su: String2Float) Odpowied­nie frag­men­ty kodu zapisu­je­my sobie gdzieś “pod ręką”.

Krok 3 — konstruowanie diagramu

Są dwa główne pode­jś­cia do kon­struowa­nia takiego dia­gra­mu — od początku i od koń­ca. W pier­wszym pode­jś­ciu zaczy­namy od początku, czyli od sytu­acji w której nie mamy żad­nych danych i wykonu­je­my wszys­tkie czyn­noś­ci które może­my, pow­tarza­jąc ten krok za każdym razem gdy otrzy­mamy nową infor­ma­cję aż otrzy­mamy infor­ma­cję, którą oczeku­je­my. Jest to pode­jś­cie ‘zachłanne’ — tzn. robimy wszys­tko co może­my, dopó­ki nie trafimy na to, co potrze­bu­je­my. Drugie pode­jś­cie odwraca ten pro­ces — zaczy­namy od infor­ma­cji którą potrze­bu­je­my, wykonu­jąc czyn­noś­ci, które są potrzeb­ne do jej otrzy­ma­nia. Pow­tarza­my to dopó­ty, dopó­ki nie będziemy potrze­bowali żad­nej dodatkowej infor­ma­cji. Wynik w obu przy­pad­kach powinien być zbliżony lub iden­ty­czny (w prost­szych przy­pad­kach). Żaden z tych sposobów nie jest lep­szy od drugiego, są po pros­tu inne. W zależnoś­ci od prob­le­mu i naszej wiedzy, jeden z nich może okazać się bardziej efek­ty­wny, ale warto znać i przećwiczyć oba.

Krok 3.1 — budowa diagramu ‘od początku’

Zaczy­namy od akcji, które nie potrze­bu­ją żad­nych danych na wejś­ciu. W naszym przy­pad­ku są to wczy­tanie kur­su i wczy­tanie iloś­ci. Nie ma żad­nej różni­cy, co zro­bimy najpierw, dlat­ego na dia­gramie przed­staw­iamy je równocześnie.

Krok 3.1.1 akcje wczytaj na diagramie aktywności

Krok 3.1.1 akc­je wczy­taj na dia­gramie aktywności

Widz­imy, że po prze­jś­ciu tych akcji mamy do dys­pozy­cji dane typu String. Jak wyni­ka z naszej wcześniejszej anal­izy, może­my ich użyć do kon­wer­sji na odpowied­ni for­mat liczbowy. I to właśnie będą nasze kole­jne akcje.

kantor bu 2

Krok 3.1.2 Dodanie akty­wnoś­ci zami­any na for­mat liczbowy

W ten sposób mamy już wszys­tkie niezbędne dane w odpowied­nim for­ma­cie, by dokon­ać obliczeń. Wstaw­iamy więc akcję oblicz.

Krok 3.1.3 Dodanie akcji oblicz

Krok 3.1.3 Dodanie akcji oblicz

W ten sposób wyko­rzys­tal­iśmy wszys­tkie “cegieł­ki”, a wyjś­ciowa dana jest tym, czego potrze­bowal­iśmy. Oznacza to, że nasz wykres doszedł do punk­tu koń­cowego. Gotowy wykres wyglą­da tak, jak poniżej:

Krok 3.1.4 Gotowy wykres aktywności dla zadania z kantorem

Krok 3.1.4 Gotowy wykres akty­wnoś­ci dla zada­nia z kantorem

 

Krok 3.2 — budowa diagramu ‘od końca’

Zaczy­na­jąc od koń­ca, patrzymy, co ma być wynikiem naszego pro­gra­mu i szukamy odpowied­niej akcji, która nam go zapewni. Widz­imy, że aby otrzy­mać Float wartość musimy dokon­ać akcji oblicz. Potrze­bu­je ona dwóch danych na wejś­ciu, o czym wiemy z treś­ci zada­nia, w odpowied­nich for­mat­ach liczbowych.

Krok 3.2.1 Dodanie akcji oblicz

Krok 3.2.1 Dodanie akcji oblicz

Potrze­bu­je­my ter­az źródeł naszych danych. Widz­imy, że może­my je uzyskać tylko poprzez wyko­nanie kon­wer­sji String –> f. liczbowy. To nasz dru­gi krok.

Krok 3.2.2 Konwersja na format liczbowy

Krok 3.2.2 Kon­wer­s­ja na for­mat liczbowy

Widz­imy, że aby dokon­ać kon­wer­sji potrze­bu­je­my danych w for­ma­cie String, które pochodzą od użytkown­i­ka. To są nasze kole­jne akcje.

3.2.3 Dodanie akcji wczytaj

3.2.3 Dodanie akcji wczytaj

Znów dos­zliśmy do punk­tu, w którym wszys­tkie ele­men­ty zostały wyko­rzys­tane, a akc­je zna­j­du­jące się na górze naszego dia­gra­mu nie posi­ada­ją żad­nych danych wejś­ciowych. To znak, że może­my zakończyć (a właś­ci­wie rozpocząć) nasz diagram.

Krok 3.2.4 Gotowy diagram

Krok 3.2.4 Gotowy diagram

 

Krok 4 — przepisujemy kod

Mamy już gotowy dia­gram i wg niego układamy nasze frag­men­ty kodu. Oczy­wiś­cie należy pamię­tać o stan­dar­d­owej kon­strukcji pro­gra­mu w Javie (o tym zna­jdziesz infor­ma­c­je w lekcji #02). Akc­je, które są zapisane jako równoległe na dia­gramie w kodzie będą oczy­wiś­cie następować po sobie, jed­nak nie ma znaczenia, która z nich będzie wpisana jako pierwsza.

Zadanie

Najlepiej uczyć się w prak­tyce, dlat­ego pole­cam stworzyć dia­gram akty­wnoś­ci do prostego pro­gra­mu. Stwórz pro­gram do wita­nia się z użytkown­ikiem. Użytkown­ik poda­je swo­je imię i nazwisko, a pro­gram go wita. Jeśli imię użytkown­i­ka kończy się na a to słowa­mi: Cześć, wyda­je mi się, że jesteś kobi­etą, jeśli na inną literę to: Cześć, wyda­je mi się, że jesteś mężczyzną.

Podpowiedź

pokaż pod­powiedź »
Potrzeb­na meto­da to: endsWith.
 

Mam nadzieję, że dzię­ki temu wpisowi, tak jak ja, znacznie ograniczysz stres spowodowany niezbyt dużą wprawą w pisa­niu w Javie (czy jakimkol­wiek innym języku, bo prze­cież to narzędzie abso­lut­nie uni­w­er­salne) i łatwiej Ci będzie ułożyć swój pro­gram. A może masz inne pomysły co może pomóc w takich momen­tach zas­to­ju nad kodem? Z chę­cią poczytam(y) o nich w komentarzach.

PS. A jeśli wpis się podobał, to zapraszam do śledzenia fan­page’a, by być zawsze na bieżą­co z naszy­mi postami.