Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Projekt systemu w php
Forum PHP.pl > Forum > PHP
Nightstalker
Cześć,
zabieram się właśnie za dokumentacje systemu napisanego w php (wspomaganego przez zend framework)... No i mam z tym mały problem, bo nigdy wcześniej nie robiłem tego zgodnie z teorią serwowaną na uczelniach, a tego właśnie wymaga mój projekt :-) W pracy zawsze zaczynam od analizy, której efektem są przypadki użycia. Przypadki są konsultowane z klientem i na tej podstawie wyodrębnione są główne "obiekty systemu" i dalej schemat bazy. W tym miejscu powinienem jednak zrobić diagram klas, ale niech mi ktoś powie - jak przedstawić na takim diagramie standardowe biblioteki zenda? Przykładowo, mój obiekt "faktura", ma możliwość zapisu i wydruku, ale sam z siebie tego nie robi, tylko odwołuje się do managera, który z kolei przy użyciu dao czyni zapis. To samo z drukowaniem - odpowiedni manager korzysta z innej klasy do wydruku. Obiekt faktury jednak sam w sobie nie ma metody w stylu "drukuj", a tego chyba wymaga projekt systemu w metodyce obiektowej... Bardzo proszę, niech ktoś biegły w tym temacie mi to wytłumaczy... Googluje już od dwóch tygodni i nie spotkałem się z wyjaśnieniem wyczerpującym temat. Mądre książki też np. opisują diagramy sekwencji - orientuje się o co w nich chodzi i potrafię je tworzyć dla głównych obiektów systemu, ale problem pojawia się gdy mam zamiar przedstawić jakiś zendowy proces 9np. sprawdzanie formularza)... Może za bardzo skupiam się na szczegółach? Może powinienem zrobić po prostu diagram klas dla głównych obiektów, wyodrębnić ich atrybuty oraz metody, na tej podstawie zrobić erd i schemat bazy, a szczegóły implementacji przedstawić jakoś inaczej? Jeszcze raz proszę kogoś biegłego o pomoc! Pogubiłem się w tym wszystkim :-)
bastard13
Diagramy klas nie powinny zawierać absolutnie żadnej informacji nt. wykorzystywanych w projekcie frameworków, orm itp., nawet język programowania nie powinien być na tym etapie uwzględniony. Tego typu sprawy można ewentualnie dodać do wymagań niefunkcjonalnych aplikacji.
Co do samego modelu, to twój przykładowy obiekt faktura może mniej więcej wyglądać tak:
Faktura
-dataWystawienia:date
-wystawiajacy:Company
-kupujacy:Customer
+drukuj():string
+wystaw(wystawiajacy:Company, kupujacy:Customer)

Do tego dochodzą ci odpowiednie asocjacje z Company i Customer.
Ogólnie zazwyczaj faza projektowa ma miejsce przed wykonaniem projektu:) I na podstawie zebranych wymagań projektujesz to, co ma zostać zrobione. Sposób rozwiązania tego, w jaki sposób faktura ma być drukowana, to już kwestia implementacji.
Crozin
Na przyszłość dodawaj proszę jakieś akapity - strasznie ciężko się czyta taki blok tekstu. wink.gif

Na takim diagramie powinieneś przedstawić jedynie interfejs aplikacji, czyli de facto nie wiele tutaj powinno z Zenda pozostać.
Cytat
Przykładowo, mój obiekt "faktura", ma możliwość zapisu i wydruku, ale sam z siebie tego nie robi, tylko odwołuje się do managera, który z kolei przy użyciu dao czyni zapis
Oczywiście, bardzo dobrze że to osobne obiekty odpowiedzialne za druk czy zapis, jednakże to nie obiekt Faktura się do nich odwołuje. To one powinny najpierw otrzymać jakiś obiekt po czym to na nich wywołujesz operację zapisu czy druku. Tak mogłoby wyglądać ostateczne użycie:
  1. Invoice invoice = new Invoice();
  2. invoice.set...(...);
  3. invoice.set...(...);
  4. invoice.set...(...);
  5.  
  6. InvoicePrinter printer = ...; // tworzy / pobiera skądś obiekt drukarki faktur
  7. printer.setInvoice(invoice);
  8. printer.print();
  9. // lub jeżeli zajdzie taka potrzeba inny interfejs:
  10. // printer.print(invoice);
  11.  
  12. InvoiceManager manager = ...;
  13. manager.persist(invoice);
  14.  
  15. invoice.set...(...);
  16.  
  17. manager.update(invoice);


Jak mogłyby te obiekty wyglądać?
  1. public interface Manager<T> {
  2. public void persist(T object);
  3. public void update(T object);
  4. public void remove(T object);
  5. }
  6.  
  7. public class InvoiceManager implements Manager<Invoice> {
  8. @Override
  9. public void persist(Invoice object) {
  10. ...
  11. }
  12.  
  13. @Override
  14. public void update(Invoice object) {
  15. ...
  16. }
  17.  
  18. @Override
  19. public void remove(Invoice object) {
  20. ...
  21. }
  22. }
  23.  
  24. public interface Printer {
  25. public void print();
  26. }
  27.  
  28. public class InvoicePrinter implements Printer {
  29. @Override
  30. public void print() {
  31. ...
  32. }
  33. }
  34.  
  35. public class Invoice {
  36. ...
  37. }
Przeniesienie tego na diagram nie powinno być trudne.

Pozwoliłem sobie na przykład w Javie bo lepiej w niej widać co jest czym i do czego się odnosi
Nightstalker
Crozin, napisaliśmy post w tym samym momencie, więc robie edycje :-) Najpierw odpowiedź i pytanie do bastard13:

Czyli jestem na dobrym tropie :-) Jeśli dobrze zrozumiałem to robiąc diagram klas mam skupić się na faktycznych czynnościach jakie wykonują kluczowe obiekty, a to w jaki sposób coś robią i za pośrednictwem czego mogę ukryć lub pominąć, tak?
System był projektowany w miarę poprawnie - najpierw była analiza i określenie wymagań, później ogólne przypadki użycia i diagramy stanów ilustrujące bardziej złożone procesy.
Na ich podstawie powstał projekt bazy danych, który dla zwiększenia wydajności został później poddany denormalizacji (czyli w rezultacie mam dwa: ERD i schemat fizyczny docelowej bazy).
Do tego doszły makiety GUI i z tego miejsca zabrałem się za implementacje.
Kiedy jednak przyszło do składania dokumentacji zorientowałem się, że realizuje projekt wg lekko "wybrakowanej" metodyki obiektowej, bo brak w nim diagramów klas (o diagramch sekwencji już nie wspominając)...
Zapomniałem wspomnieć, że jest to praca na zaliczenie kursu projektowania systemów, na który raczej rzadko uczęszczałem (i teraz to się mści...) :-) Mogę liczyć jeszcze na jakieś porady?

A teraz Crozin:

Sorry za te tekst - późno w nocy było jak pisałem, a enter daleko...

Bardzo dużo mi rozjaśniłeś. Wygląda na to, że jednak powinienem uwzględnić pewne klasy, którymi posługuje się np. przy zapisie lub odczycie z bazy danych.
Dobrym przykładem będzie zarządzanie kolekcją faktur, bo mam tam kilka klas managerów, maperów, "składaczy" i oczywiście obiekt "faktura" :-) Wieczorem poskładam diagram i zaprezentuje Wam tutaj - mam nadzieję, że mogę liczyć na Waszą ocenę ;-)



Oj chyba jednak nie tędy droga - wydaje mi się że za bardzo wchodzę w kwestię architektury systemu i szczegóły implementacji... No ale zobaczymy... Poniżej uproszczony diagram klas. W skrócie działa to tak:
1. aplikacja tworzy i używa managera finansów
2. manager finansów tworzy i używa managera listy faktur oraz managera pojedynczej faktury
3. managery listy i pojedynczej faktury dziedziczą po uniwersalnych managerach i tylko ustawiają im odpowiednie dao
4. managery korzystają z dao do utrwalania i odczytywania danych
5. dao listy i dao obiektu dziedziczą po uniwersalnych dao i tylko ustawiają im parametry wskazujące na mapper i model
6. na samym końcu mamy model, który jest wynikiem działania mappera, który z kolei jest używany przez dao



(http://imageshack.us/f/836/classdx.jpg/ - daje link bezpośredni, bo nie wiem czy hotlink zaskoczy)

To jest na prawdę fajna architektura i sprawdza się "w boju", ale nie wiem czy dobrze przedstawiam ją na projekcie.

PS. To co napisał bastard13 wydaje mi się jednak być w sprzeczności ze słowami Crozin (albo odwrotnie), bo jeśli mam ukrywać szczegóły implementacji to powinienem pozbyć się z diagramu tych wszystkich managerów. Co o tym myślicie?
bastard13
Cytat
Jeśli dobrze zrozumiałem to robiąc diagram klas mam skupić się na faktycznych czynnościach jakie wykonują kluczowe obiekty, a to w jaki sposób coś robią i za pośrednictwem czego mogę ukryć lub pominąć, tak?

'W jaki sposób' - to już kwestia implementacji i nie jest to istotne na etapie projektowania. No chyba, że wymagania pozafunkcyjne mówią co innego:)
'Za pośrednictwem czego' - to powinno być w modelu, ponieważ powinien on w jasny sposób przedstawiać asocjacje i zależności. U mnie to najczęściej wygląda tak, że mam diagram, na którym przedstawiam powiązania i zależności między klasami (na nim są tylko nazwy klas), a dokładniejszy ich opis jest na kolejnych diagramach. Dzięki czemu przedstawiając ten pierwszy jestem w stanie przedstawić ogólną ideę. Jeżeli nie ma żadnych uwag, to mogę przejść do bardziej szczegółowego opisu, czyli przedstawienia klas wraz z atrybutami i metodami. Oczywiście takie rozbijanie ma sens, jeżeli przedstawiany diagram składa się z wielu klas. W innym przypadku można sobie podarować takie rozdrabnianie:)

Cytat
[...] najpierw była analiza [...] określenie wymagań [...] przypadki użycia [...] i diagramy stanów [...] projekt bazy danych [...]

Kolejność jest mniej więcej taka
1) Określenie wymagań funkcjonalnych i niefunkcjonalnych. Te drugie, najczęściej, w dalszych etapach, będą zwiększały swoją obiętośćsmile.gif Poczytaj o FURPS+.
2) Rozmowy z klientem i użytkownikami systemu. Na tej podstawie powstają scenariusze.
3) Tworzenie przypadków użycia na podstawie zebranych scenariuszy.
4) W między czasie powstaje słownik ze wszystkimi nazwami itp. Chodzi o to, żeby i dla klienta i dla programisty wszystko było jednoznaczne.
5) Na tym etapie możliwe, że będziesz potrzebował ponownie wrócić do wcześniejszych punktów. Ogólnie trwa to do momentu, gdy wszystkie przypadki użycia są zadowalające.
6) W tym momencie dopiero zaczyna się analiza:) Najpierw identyfikujemy obiekty encji, brzegowe i sterujące. Pomocne tutaj mogą być heurystyki Abbotta (także na innych etapach projektowania:), niestety nie znam żadnego dobrego linku:(
7) Na podstawie zidentyfikowanych obiektów powstają diagramy sekwencji.
8) Dla obiektów o długim czasie życia warto jeszcze stworzyć diagramy stanów.
9) Na podstawie zebranych informacji tworzymy diagramy klas:)

Punkty 7-9 nie muszą być realizowane w takiej kolejności. To już zależy od indywidualnego podejścia.
Projekt bazy danych moim zdaniem powinien powstać dopiero w momencie, gdy są gotowe już wszystkie diagramy klas, ponieważ dopiero na podstawie prawidłowo zidentyfikowanych obiektów encji jesteś w stanie stworzyć dobrą bazę danych.
Co do makiety GUI, to może być przedstawiona klientowi, gdzieś między 3-5 punktem, gdy już wiadomo mniej więcej, co dany system ma robić.


@up after your last edit:)
Cytat
To co napisał bastard13 wydaje mi się jednak być w sprzeczności ze słowami Crozin (albo odwrotnie), bo jeśli mam ukrywać szczegóły implementacji to powinienem pozbyć się z diagramu tych wszystkich managerów

To nie jest sprzeczne. Przez implementację miałem na myśli ciało metod. Crozin przedstawił ci projekt za pomocą kodu.
Ogólnie diagram powinien zawierać wszystkie klasy, które planujesz wykorzystać. Jednak nie musisz pisać, że Controller dziedziczy po Zend_Controller i wypisywać wszystkich metod, które tam się znajdują, bo to już nie należy do dziedziny aplikacji, którą projektujesz.

Kilka uwag:
1) Atrybuty klas powinny być prywatne (Invoice).
2) Rozumiem, że InvoiceMapper służy do zapisu i pobierania danych. Takie metody powinny znajdować się w klasie Invoice.
3) Nie ma potrzeb powtarzania metod i atrybutów i w klasach bazowych i dziedziczących. To oczywiste, że jeżeli AbstractSingleObjectDAO posiada metodę getById(), to klasy potomne również ją posiadają. Coś takiego ma sens tylko wtedy, jeżeli klasa abstrakcyjne deklaruje metodę abstrakcyjną, a dopiero w klasie potomnej jest ona implementowana.
4) Wydaje mi się, że klasy InvoiceManager i InvoiceDAO mogły być połączone w jedną klasę. Tak samo InvoiceListManager i InvoiceListDAO.
5) List powinien być kolekcją Single, a u ciebie jest totalny brak powiązania między nimi, nie licząc oczywiście klasy InvoiceMapper.
6) I nazwy klas abstrakcyjnych powinny być pisane pochyłą czcionkątongue.gif
Nightstalker
OK, dzięki za pomoc, ale mam taki mętlik w głowie, że poczytałem trochę mądrych książek i zaczynam projekt od początku...

Plan jest taki:

1. Wstęp - będzie napisany na końcu wink.gif
2. Przegląd:
----2.1. Analiza biznesowa - wybrałem metodę BABOK, bo była najbliższa temu co faktycznie robiłem:
--------2.1.1. Analiza przedsiębiorstwa - co robi firma, z czym ma problemy i gdzie jest miejsce dla nowego systemu, tutaj będzie też branżowy słownik danych - dobre miejsce?
--------2.1.2. Pozyskiwanie wymagań - analiza dokumentu, który klient zaprezentował jako spis wymagań funkcjonalnych i niefunkcjonalnych, jego transformacja na formalną postać tekstową oraz aktualizacje tych wymagań na podstawie cyklu spotkań z klientem i dodatkowych materiałów jakie przedstawił,
--------2.1.3. Planowanie i zarządzanie wymaganiami - tu mam zamiar napisać tylko w jakiej formie będą dalej dokumentowane wymagania funkcjonalne (przypadki użycia) i kto odpowiada za ewentualne zmiany oraz w jaki sposób będą numerowane kolejne wersje dokumentów (czysta formalność),
--------2.1.4. Dokumentowanie wymagań - chciałbym tu wstawić przypadki użycia utworzone na podstawie wymagań funkcjonalnych - co o tym myślicie? Dobre miejsce?
--------2.1.5. Komunikowanie wymagań - tutaj chcę napisać tylko, że klient zaakceptował przypadki użycia powstałe na bazie wymagań i jak bardzo był zadowolony, bo tak faktycznie było i warto w pracy o tym wspomnieć,
--------2.1.6. Ocena rozwiązania - tutaj będzie podsumowanie stwierdzające, że analiza wyczerpała temat w stopniu wystarczającym do rozpoczęcia projektowania systemu zgodnie z wymaganiami opracowanymi wspólnie z klientem - to chyba trzyma się kupy i co najważniejsze, trzyma się książki wink.gif
----2.2. Obiektowy model dziedziny - na podstawie analizy biznesowej mogę przedstawić już obiekty, które powinny istnieć w systemie aby zrealizować przypadki użycia (wraz z atrybutami, ale bez metod - zamiast metod podam opis słowny)
----2.3. Narzędzia i technologie - opis narzędzi (w tym PHP, JS, HTML, Zend Framework) i wyjaśnienie dlaczego właśnie te narzędzia, a nie inne
3. Projekt:
----3.1. Określenie celów - chcę tutaj wyznaczyć kilka celów opracowanych na podstawie przedstawionych wcześniej wymagań - dobry pomysł?
----3.2. Przegląd istniejących rozwiązań - solidne uzasadnienie potrzeby stworzenia nowego systemu
----3.3. Opis aktorów i przypadki użycia razem ze scenariuszami (także alternatywnymi),
----3.4. Model danych - diagram relacji encji (no i teraz pytanie - czy powinienem? to przecież metodyka strukturalna, ale jakiś podkład dla schematu bazy danych muszę mieć)
----3.5. Schemat bazy danych - nic dodać nic ująć...
----3.6. Projekt GUI - makiety,
----3.7. Architektura systemu - diagram klas służących do zarządzania obiektami z modelu dziedziny,
----3.8. Opis implementacji - jakieś ciekawostki na temat budowy systemu, zastosowanych algorytmów, itp...
----3.9. Testy jednostkowe, wydajnościowe i funkcjonalne potwierdzające, że projekt spełnia postawione na początku wymagania
4. Podsumowanie:
----4.1. Konfrontacja rezultatu z celami,
----4.2. Sugestie na temat dalszej rozbudowy systemu

Co o tym myślicie?

PS. Tak poza tym to zdecydowałem, że jak tylko skończę studia to idę na kolejne - tym razem z naciskiem na analizę i projektowanie systemów :-)
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.