Paradygmat obiektowy i Przypadki Użycia

Przypadki uży­cia w nota­cji UML1 to jed­na z naj­star­szych metod doku­men­to­wa­nia wyma­gań i nadal budzi wie­le kon­tro­wer­sji w kwe­stii ich popraw­ne­go użycia.

Obiektowy paradygmat i pojęcie systemu

Słownik j.polskiego mówi:

para­dyg­mat ?przy­ję­ty spo­sób widze­nia rze­czy­wi­sto­ści w danej dzie­dzi­nie, dok­try­nie itp.?

obiekt ?rzecz abs­trak­cyj­na, np. cecha lub poję­cie?, ?przed­miot, któ­ry moż­na zoba­czyć lub dotknąć?

sys­tem ?układ ele­men­tów mają­cy okre­ślo­ną struk­tu­rę i sta­no­wią­cy logicz­nie upo­rząd­ko­wa­ną całość?, ?zespół wie­lu urzą­dzeń, dróg, prze­wo­dów itp., funk­cjo­nu­ją­cych jako całość?

Ludwig von Bertalanffy w swo­jej Ogólnej Teorii Systemów?2? określa 

sys­tem: sta­no­wią­cy okre­ślo­ną całość byt, zło­żo­ny z mają­cych inte­rak­cje elementów. 

Pojęciami powią­za­ny­mi są tu pod­sys­tem i super sys­tem. Są to poję­cia względ­ne, ich zna­cze­nie odno­si się do sys­te­mu ana­li­zo­wa­ne­go. Innymi sło­wy: dany sys­tem skła­da się z pod­sys­te­mów oraz jest czę­ścią sys­te­mu nad­rzęd­ne­go czy­li super sys­te­mu. Paradygmat obiek­to­wy, w swej isto­cie, nawią­zu­je do teo­rii sys­te­mów: sys­tem (ana­li­zo­wa­ny lub pro­jek­to­wa­ny) skła­da się z współ­pra­cu­ją­cych obiektów.

Cechą pod­sta­wo­wą obiek­to­we­go para­dyg­ma­tu jest her­me­ty­za­cja, któ­ra ozna­cza, że obiekt nie udo­stęp­nia swo­je­mu oto­cze­niu (nie udo­stęp­nia) swo­jej struk­tu­ry (budo­wy), ma z oto­cze­niem wyłącz­nie okre­ślo­ne inte­rak­cje, zwa­ne ope­ra­cja­mi. Innymi sło­wy obiekt reagu­je w okre­ślo­ny spo­sób na okre­ślo­ne bodź­ce igno­ru­jąc wszel­kie pozo­sta­łe, a zbiór tych ope­ra­cji nazy­wa­my inter­fej­sem obiek­tu. Jedynym spo­so­bem pozy­ska­nie infor­ma­cji o obiek­cie jest zapy­ta­nie go o to”. Cechą ele­men­tów sys­te­mu, czy­li obiek­tów, jest to, że poszcze­gól­ne z nich są mię­dzy sobą bar­dzo luź­no powią­za­ne ale wewnątrz sie­bie są one bar­dzo spój­ne. Jedno z wie­lu opra­co­wań na ten temat mówi:

Cohesion and Coupling deal with the quali­ty of an OO design. Generally, good OO design sho­uld be loose­ly coupled and high­ly cohe­si­ve. Lot of the design prin­ci­ples, design pat­terns which have been cre­ated are based on the idea of ?Loose coupling and high cohe­sion?.3

Konsekwencją her­me­ty­za­cji jest poli­mor­fizm. Znamy jedy­nie nazwę bodź­ca, meto­da powsta­nia reak­cji obiek­tu ma bodziec jest ukry­ta, co zna­czy, że nazwa bodź­ca okre­śla sku­tek z nie to jak powstał. 

Podsumowując, obiek­to­wy para­dyg­mat mówi nam, że przed­miot ana­li­zy lub pro­jek­to­wa­nia, przed­sta­wia­my jako sys­tem, czy­li okre­ślo­ną struk­tu­rę skła­da­ją­cą się z okre­ślo­nych ele­men­tów, ele­men­ty te współ­pra­cu­ją (mają inte­rak­cje) w okre­ślo­ny spo­sób.

Paradygmat obiek­to­wy: Jedynym związ­kiem mię­dzy obiek­ta­mi sys­te­mu jest wza­jem­na współ­pra­ca czy­li inte­rak­cja. Hermetyzacja ozna­cza, że obiek­ty ukry­wa­ją swo­ją budo­wę i nie współ­dzie­lą nicze­go. Polimorfizm ozna­cza, że istot­na jest nazwa pole­ce­nia, a nie meto­da jego wyko­na­nia, bo te mogą być różne. 

Co piszą w sieci i książkach

W sie­ci i w lite­ra­tu­rze moż­na spo­tkać róż­ne wyja­śnie­nia i opi­sy tego co popu­lar­nie nazy­wa się (moim zda­niem nie­słusz­nie) podej­ściem obiek­to­wym”. W zależ­no­ści od tego czy celem jest opi­sa­nie bada­ne­go przed­mio­tu czy jego zapro­jek­to­wa­nie, mówi­my o ana­li­zie zorien­to­wa­nej obiek­to­wo lub pro­jek­to­wa­niu zorien­to­wa­nym obiektowo.

W sie­ci spo­tka­my bar­dzo czę­sto opi­sy takie jak ten:

Object-Oriented Analysis
A method of ana­ly­sis which descri­bes the pro­blem doma­in in terms of clas­ses and objects.
OOA feeds OOD which then can be imple­men­ted with OOP.?4?

Jest to dość powszech­nie spo­ty­ka­na i nie­praw­dzi­wa teza, mówią­ca że ana­li­za obiek­to­wa (obiek­to­we meto­dy ana­li­zy) pole­ga na opi­sa­niu pro­ble­mu z uży­ciem klas i obiek­tów. Nie jest tak­że praw­dą, że z zasa­dy” atry­bu­ty to dane (rozu­mia­ne tak jak pola w bazach danych, UML – dia­gram klas – abso­lut­nie nie słu­ży do mode­lo­wa­nia danych!). Analiza obiek­to­wa może pro­wa­dzić do obiek­to­we­go pro­jek­to­wa­nia a potem do obiek­to­wej implementacji.

Większość tek­stów na temat metod obiek­to­wych wycho­dzi z rąk pro­gra­mi­stów. Ci opi­su­ją ją z per­spek­ty­wy imple­men­ta­cji z uży­ciem tak zwa­nych obiek­to­wo zorien­to­wa­nych języ­ków pro­gra­mo­wa­nia. Tak zwa­na obiek­to­wa orien­ta­cja języ­ka pro­gra­mo­wa­na spro­wa­dza się do tego, że ele­men­ty pro­gra­mu są orga­ni­zo­wa­ne w kla­sy, a te zawie­ra­ją atry­bu­ty i ope­ra­cje. Atrybuty to ele­men­ty zapa­mię­ty­wa­ne a ope­ra­cje to wywo­ły­wa­ne funk­cje (meto­dy, pro­ce­du­ry). Innymi sło­wy jest to kolej­na struk­tu­ral­na meto­da pisa­nia oprogramowania.

To czy pro­jekt jest fak­tycz­nie obiek­to­wy” zale­ży od jego archi­tek­tu­ry a nie od fak­tu, że uży­to obiek­to­wo zorien­to­wa­ne­go języ­ka pro­gra­mo­wa­nia (nawet w assem­ble­rze moż­na pro­gra­mo­wać obiektowo).

Inny przy­kład:

Programowanie obiek­to­we (ang. object-orien­ted pro­gram­ming, OOP) ? para­dyg­mat pro­gra­mo­wa­nia, w któ­rym pro­gra­my defi­niu­je się za pomo­cą obiek­tów ? ele­men­tów łączą­cych stan (czy­li dane, nazy­wa­ne naj­czę­ściej pola­mi) i zacho­wa­nie (czy­li pro­ce­du­ry, tu: meto­dy). Obiektowy pro­gram kom­pu­te­ro­wy wyra­żo­ny jest jako zbiór takich obiek­tów, komu­ni­ku­ją­cych się pomię­dzy sobą w celu wyko­ny­wa­nia zadań.

Podejście to róż­ni się od tra­dy­cyj­ne­go pro­gra­mo­wa­nia pro­ce­du­ral­ne­go, gdzie dane i pro­ce­du­ry nie są ze sobą bez­po­śred­nio zwią­za­ne. Programowanie obiek­to­we ma uła­twić pisa­nie, kon­ser­wa­cję i wie­lo­krot­ne uży­cie pro­gra­mów lub ich fragmentów.

Największym atu­tem pro­gra­mo­wa­nia, pro­jek­to­wa­nia oraz ana­li­zy obiek­to­wej jest zgod­ność takie­go podej­ścia z rze­czy­wi­sto­ścią ? mózg ludz­ki jest w natu­ral­ny spo­sób naj­le­piej przy­sto­so­wa­ny do takie­go podej­ścia przy prze­twa­rza­niu infor­ma­cji.5

Ad. pierw­szy aka­pit. Przede wszyst­kim pisa­ny przez pro­gra­mi­stę pro­gram zawie­ra dekla­ra­cje klas, te zawie­ra­ją atry­bu­ty i ope­ra­cje. Na pod­sta­wie tych klas (dekla­ra­cji) powsta­ną w pamię­ci kom­pu­te­ra obiek­ty, ale dopie­ro wte­dy gdy pro­gram ten będzie się wyko­ny­wał w pamię­ci komputera.

Ad. dru­gi aka­pit. Praktycznie podział pro­gra­mu na dekla­ra­cje klas to inna for­ma struk­tu­ry­za­cji kodu pro­gra­mu. Pisanie, kon­ser­wa­cja i wie­lo­krot­ne uży­cie nie jest pro­stą kon­se­kwen­cją fak­tu uży­cia obiek­to­we­go języ­ka pro­gra­mo­wa­nia. Podział pro­gra­mu na kla­sy, i to jak ten podział zosta­nie prze­pro­wa­dzo­ny, to wyłącz­nie inwen­cja archi­tek­ta lub pro­gra­mi­sty, nie ma takie­go obo­wiąz­ku (prze­czy­taj o Boskim obiek­cie).

Ad. trze­ci aka­pit. Najpierw przy­po­mnij­my, że pra­ce nad opro­gra­mo­wa­niem prze­bie­ga­ją w nastę­pu­ją­cej kolej­no­ści: Analiza obiek­to­wa, Projektowanie obiek­to­we, Programowanie obiek­to­we. Tak więc pro­gra­mo­wa­nie to ostat­ni etap i jedy­nie imple­men­ta­cja pro­jek­tu. Pomysł na archi­tek­tu­rę kodu pro­gra­mu to pro­jek­to­wa­nie. Jeżeli mówić o tym do cze­go jest przy­zwy­cza­jo­ny ludz­ki mózg, to do obiek­to­we­go postrze­ga­na oto­cze­nia, ale na dość wyso­kim pozio­mie abs­trak­cji (widzi­my ludzi lub samo­cho­dy, ale mało kto postrze­ga je jako sys­tem współ­dzia­ła­ją­cych obiektów”).

Człowiek postrze­ga swo­je oto­cze­nie jako okre­ślo­ne obiek­ty, ale rzad­ko zna i rozu­mie ich wewnętrz­ną struk­tu­rę i mecha­nizm dzia­ła­nia. I tu docho­dzi­my do poję­cia Przypadek Użycia w nota­cji UML

Przypadki użycia – czym są?

Z uwa­gi na to, że przy­tła­cza­ją­ca więk­szość (dekla­ro­wa­nych) zasto­so­wań poję­cia przy­pa­dek uży­cia ma swo­je źró­dło w nota­cji UML, sku­pie się na tej nota­cji. Od 2015 roku mamy UML 2.5, ostat­nia aktu­ali­za­cja do 2.5.1. mia­ła miej­sce w grud­niu 2017. Czytamy tam:

18.1.1 Summary
UseCases are a means to cap­tu­re the requ­ire­ments of sys­tems, i.e., what sys­tems are sup­po­sed to do. The key con­cepts spe­ci­fied in this clau­se are Actors, UseCases, and sub­jects. Each UseCase?s sub­ject repre­sents a sys­tem under con­si­de­ra­tion to which the UseCase applies. Users and any other sys­tems that may inte­ract with a sub­ject are repre­sen­ted as Actors.1

Ogólnie: Przypadki Użycia są spo­so­bem na opi­sa­nie wyma­gań wobec sys­te­mu, rozu­mia­nych jako to, co sys­tem ma robić. Kluczowe poję­cia z tym zwią­za­ne to Aktor, Przypadek Użycia, przed­miot opi­su. Każdy Przypadek Użycia repre­zen­tu­je sys­tem z per­spek­ty­wy celu jego uży­cia. Każdy czło­wiek lub inny zewnętrz­ny sys­tem mają­cy z nim inte­rak­cje, nazy­wa­my Aktorem tego systemu.

Tak więc Przypadek Użycia to reak­cja sys­te­mu na bodź­ce, któ­rych źró­dłem jest aktor systemu. 

18.1.3.1 Use Cases and Actors
A UseCase may apply to any num­ber of sub­jects. When a UseCase applies to a sub­ject, it spe­ci­fies a set of beha­viors per­for­med by that sub­ject, which yields an obse­rva­ble result that is of value for Actors or other sta­ke­hol­ders of the sub­ject.1

Generalizując Przypadek Użycia sys­te­mu repre­zen­tu­je (spe­cy­fi­ku­je) zacho­wa­nie sys­te­mu (zestaw, łań­cuch jego zacho­wań) w odpo­wie­dzi na okre­ślo­ny bodziec, efek­tem tego zacho­wa­nia jest okre­ślo­ny rezul­tat przed­sta­wia­ją­cy war­tość dla Aktora. 

Tak więc Przypadek Użycia to abs­trak­cja repre­zen­tu­ją­ca efekt inte­re­su­ją­cy z punk­tu widze­nia akto­ra, ten efekt to reak­cja sys­te­mu ini­cjo­wa­na dzia­ła­niem aktora. 

W spe­cy­fi­ka­cji UML opi­sa­no dwie spe­cy­ficz­ne konstrukcje:

Rozszerzenie (18.1.3.2. Extend) 

Extend is inten­ded to be used when the­re is some addi­tio­nal beha­vior that sho­uld be added, possi­bly con­di­tio­nal­ly, to the beha­vior defi­ned in one or more UseCases.1

Używane w celu poka­za­nia, że okre­ślo­ny Przypadek Użycia, może cecho­wać się pew­ny­mi dodat­ko­wy­mi, warun­ko­wy­mi zacho­wa­nia­mi (może ono doty­czyć wię­cej niż jed­ne­go przy­pad­ku użycia).

Włączenie (18.1.3.3 Includes)

The Include rela­tion­ship is inten­ded to be used when the­re are com­mon parts of the beha­vior of two or more UseCases. This com­mon part is then extrac­ted to a sepa­ra­te UseCase, to be inc­lu­ded by all the base UseCases having this part in com­mon.1

Używane jest w celu wyłą­cze­nia (poka­za­nia) na zewnątrz, pew­nej okre­ślo­nej wspól­nej czę­ści, dwóch lub więk­szej licz­by Przypadków użycia.

Dwa klu­czo­we wnioski:

  1. zarów­no inc­lu­de jak i extent są to kon­struk­cje ujaw­nia­ją­ce wnę­trze archi­tek­tu­ry kodu, a więc łamią­ce zasa­dę hermetyzacji,
  2. inc­lu­de to wyłą­czo­na część wspól­na co naj­mniej dwóch przy­pad­ków uży­cia, więc: 
    1. nie ma sen­su łącze­nie akto­ra do przy­pad­ku wyłą­czo­ne­go, bo do nie­sa­mo­dziel­ny frag­ment scenariusza,
    2. nie ma sen­su kon­struk­cja z jed­nym przy­pad­kiem uży­cia i jed­nym lub wie­lo­ma przy­pad­ka­mi połą­czo­ny­mi związ­kiem inc­lu­de.

Jeżeli dekla­ru­je­my, że pro­jekt jest zgod­ny z para­dyg­ma­tem obiek­to­wym, kon­struk­cje te nie mają zasto­so­wa­nia. Są zabro­nio­ne, bo łamią pod­sta­wo­wą zasa­dę para­dyg­ma­tu obiek­to­we­go jaką jest hermetyzacja. 

Obie te kon­struk­cje (inc­lu­de i extend) mają rodo­wód z metod struk­tu­ral­nych, a są to lata 80-te, gdzie sto­so­wa­nie poję­cia pod­pro­gra­mu było stan­dar­do­wą kon­struk­cją re-uży­cia kodu. Litera U w akro­ni­mie UML ozna­cza uni­fied” czy­li ujed­no­li­co­ny, UML jest więc ujed­no­li­co­nym i uni­wer­sal­nym narzę­dziem, co sami auto­rzy UML wska­zu­ją, tłu­ma­cząc dla­cze­go te kon­struk­cje zosta­ły utrzy­ma­ne w spe­cy­fi­ka­cji UML.:

This is becau­se UseCases may be spe­ci­fied in vario­us for­mats such as natu­ral lan­gu­age, tables, tre­es, etc.

Nie mniej jed­nak nadal poja­wia­ją się, łamią­ce fun­da­men­ty obiek­to­we­go para­dyg­ma­tu, kurio­zal­ne pomy­sły na mode­lo­wa­nie archi­tek­tu­ry sys­te­mu z uży­ciem Przypadków Użycia, takie jak te opi­sa­ne tu:

Decomposing Use Cases Towards Logical Architecture Design6

Innym przy­kła­dem sto­so­wa­nia przy­pad­ków uży­cia w spo­sób nie­zgod­ny z UML, jest bar­dzo popu­lar­na książ­ka Alistair’a Cockburna zaty­tu­ło­wa­na Stosowanie Przypadków Użycia7.

UML has had lit­tle impact on the­se ide­as – and vice ver­sa. Gunnar Overgaard, a for­mer col­le­ague of Jacobson?s, wro­te most of the UML use case mate­rial, and kept Jacobson?s heri­ta­ge. However, the UML stan­dards gro­up has a strong dra­wing-tools influ­en­ce, with the effect that the textu­al natu­re of use cases was lost in the stan­dard. Gunnar Overgaard and Ivar Jacobson discus­sed my ide­as, and assu­red me that most of what I have to say abo­ut a use case fits within one of the UML ellip­ses, and hen­ce neither affects nor is affec­ted by what the UML stan­dard has to say. That means you can use the ide­as in this book quite com­pa­ti­bly with the UML 1.3 use case stan­dard. On the other hand, if you only read the UML stan­dard, which does not discuss the con­tent or wri­ting of a use case, you will not under­stand what a use case is or how to use it, and you will be led in the dan­ge­ro­us direc­tion of thin­king that use cases are a gra­phi­cal, as oppo­sed to textu­al, con­struc­tion. Since the goal of this book is to show you how to wri­te effec­ti­ve use cases, and the stan­dard has lit­tle to say in that regard, I have iso­la­ted my remarks abo­ut UML to Appendix A.7

Cockburn wyty­ka nota­cji UML ogra­ni­cze­nia metod gra­ficz­nych opar­tych na ryso­wa­niu elips, jed­nak pomi­ja fakt, że przy­pad­ki uży­cia to cele akto­rów (i wyma­ga­nia czy­li umo­wa z zama­wia­ją­cym) a nie final­na wer­sja sys­te­mu oraz fakt, że UML zawie­ra mię­dzy inny­mi dia­gram sekwen­cji, któ­re­go celem sto­so­wa­nia jest wła­śnie deta­licz­ne doku­men­to­wa­nie sce­na­riu­szy przy­pad­ków uży­cia. w swo­im Dodatku A roz­pi­su­je się na temat tego, jak związ­ka­mi inc­lu­de, extend, dzie­dzi­cze­niem roz­pi­sy­wać deta­le tek­sto­wych (i tabe­la­rycz­nych) spe­cy­fi­ka­cji przy­pad­ków uży­cia, ale nie tyl­ko w moich oczach, pogłę­bia pro­blem łama­nia zasad para­dyg­ma­tu obiektowego.

Na zakoń­cze­nie, war­to zwró­cić uwa­gę na pra­ce takie jak ta: User Story to Use Case sce­na­rio8, gdzie korzy­sta­jąc z tego, że tak zwa­ne user sto­ry w wer­sji sfor­ma­li­zo­wa­nej to zapi­sy w rodzaju:

  • jako ? oso­ba, przy­pi­sa­na rola,
  • chcę ? cecha, funk­cjo­nal­ność, czynność,
  • ponie­waż ? uza­sad­nie­nie, rezul­tat, korzyść.

moż­li­we jest gene­ro­wa­ne (wypro­wa­dza­nie) przy­pad­ków uży­cia z user sto­ry wg. schematu:

  • aktor ? oso­ba,
  • przy­pa­dek uży­cia ? funkcjonalność,
  • rezul­tat sce­na­riu­sza przy­pad­ku uży­cia ? rezul­tat

Podejście to ma jed­nak poważ­ną wadę, jest nią zigno­ro­wa­nie fak­tu, że aktor to kla­sa użyt­kow­ni­ków a nie użyt­kow­nik. Innymi sło­wy np. sys­tem CRM prze­zna­czo­ny jest do pra­cy w dzia­le sprze­da­ży, akto­rem jest każ­dy pra­cow­nik tego dzia­łu (sys­tem CRM ma w swej pod­sta­wo­wej dzie­dzi­nie, jaką jest obsłu­ga kon­tak­tów z klien­ta­mi, jed­ne­go akto­ra: pra­cow­ni­ka dzia­łu sprze­da­ży, upraw­nie­nia kon­kret­nych osób to kon­se­kwen­cja ich sta­no­wisk i reguł biz­ne­so­wych). Dlatego powyż­sza meto­da i tak wyma­ga póź­niej­sze­go skla­sy­fi­ko­wa­nia osób w aktorów.

Konstrukcje w posta­ci dia­gra­mów, na któ­rych mamy mul­tum Przypadków Użycia, połą­czo­nych związ­kiem inc­lu­de z jed­nym przy­pad­kiem nazwa­nym Logowanie?9?, zali­czam do jed­nych z naj­bar­dziej kurio­zal­nych. Czytając taki dia­gram zgod­nie z UML, nale­ży uznać, że wszyst­kie sce­na­riu­sze zawie­ra­ją w sobie owo logo­wa­nie, inny­mi sło­wy, każ­da wyko­ny­wa­na czyn­ność z apli­ka­cją skła­da się mie­dzy innym z logo­wa­nia. Warto wie­dzieć, że w UML nie było i nie ma cze­goś o nazwie: biz­ne­so­we czy sys­te­mo­we przy­pad­ki Przypadki Użycia. 

A na zakoń­cze­nie cie­ka­we zesta­wie­nie błędów:

Use case model­ling is the most power­ful requ­ire­ments model­ling tech­ni­que to model solu­tion requ­ire­ments if applied cor­rec­tly. I have come across many BA teams (inc­lu­ding my own) that made lot of com­mon mista­kes in use case model­ling. By avo­iding the top 10 mista­kes iden­ti­fied in this paper, BA teams can not only save lot of efforts in use case model­ling but also signi­fi­can­tly enhan­ce the value deli­ve­red and impro­ve the satis­fac­tion of sta­ke­hol­ders. Source: Top 10 mista­kes in Use Case Modelling

(artykuł uzupełniony 2019-09-21)

Żródła

  1. 1.
    Unified Modeling Language. ABOUT THE UNIFIED MODELING LANGUAGE SPECIFICATION VERSION 2.5.1. https://​www​.omg​.org/​s​p​e​c​/​U​M​L​/​A​b​o​u​t​-​U​ML/. Published December 16, 2017. Accessed January 5, 2019.
  2. 2.
  3. 3.
  4. 4.
  5. 5.
  6. 6.
    Santos N. Modeling in Agile Software Development: Decomposing Use Cases Towards Logical Architecture Design. SpringerLink. 10.1007/978 – 3‑030 – 03673-7_31” target=„_blank” rel=„noopener noreferrer”>https://link.springer.com/chapter/10.1007/978 – 3‑030 – 03673-7_31. Published November 3, 2018. Accessed January 5, 2019.
  7. 7.
    WRITING EFFECTIVE USE CASES, Alistair Cockburn, Addison-Wesley, c. 2001.
  8. 8.
  9. 9.
    Szwed P. io:zadanie_3. [Piotr Szwed]. http://home.agh.edu.pl/~pszwed/wiki/doku.php?id=io:zadanie_3. Published November 4, 2012. Accessed January 6, 2019.

Inne artykuły na podobny temat

Dodaj komentarz

Twój adres email nie zostanie opublikowany

Komentuj i zadawaj pytania autorowi.

Identyfikator *
E-mail *
Witryna internetowa

Witryna wykorzystuje Akismet, aby ograniczyć spam. Dowiedz się więcej jak przetwarzane są dane komentarzy.