Zapoznając się z daną technologią czy robiąc mikroprojekt, w większości przypadków wystarczy jeden plik, który będzie zawierać cały potrzebny kod. Nie po to jednak są katalogi i pliki, aby nie korzystać z ich dobrodziejstw. Rozdzielanie projektu na mniejsze komponenty nie jest jednak czynnością, którą można zrobić z marszu. Musi być naprawdę dobrze przemyślane, ponieważ wadliwa architektura może doprowadzić do miejsca, w którym występują rzeczy, takie jak:

  • Silne wiązanie (ang. strong coupling) - sytuacja, w której wiele modułów jest powiązanych ze sobą i zmiana w jednym miejscu projektu pociąga za sobą (często nieokreślone) zmiany w innych miejscach.
  • Ślepa uliczka - problem z dalszą rozbudową programu, zła struktura może uniemożliwić wprowadzanie dalszych modułów.
  • Nadmiarowość- najtrudniejsze do wykrycia ponieważ "za dużo" jest pojęciem względnym. Chodzi tutaj o sytuację, gdy dodanie kolejnego modułu wiąże się z dodaniem wielu innych, nadmiarowych konstrukcji, które występują tylko po to, aby rozbudowa była możliwa, a której można uniknąć przy innej architekturze programu.

Wiele projektów trafia do kosza i muszą zostać zostać przepisane od nowa albo przebudowane tak, aby osiągnąć odpowiednią formę. Jedyną złą rzeczą jaka z tego wynika jest frustracja, która następuje po uświadomieniu sobie, że "to nie był dobry pomysł, trzeba to napisać na nowo". Po kilku startach tego samego projektu można się naprawdę zirytować, jednak moim zdaniem są to bardzo dobre lekcje, jeżeli wyciągniemy odpowiednie wnioski.

Prezentuję krótki opis podejść, które pozwolą na zmniejszenie ryzyka dotarcia z projektem w nieodpowiednie miejsce.

Wzorce projektowe

Jest cała gama wzorców, które istnieją po to, aby tworzyć zwartą konstrukcję programów, jak np. MVC. Schematy te są interesujące nie tylko dlatego, że układają przepływ informacji w programie i organizują go za pomocą odpowiednich struktur. Podążając za wzorcem jesteśmy w stanie zbudować także odpowiednią strukturę plików, która będzie odpowiadać za poszczególne jego elementy. Np. Wzorzec Model View Controller (Model, Widok, Kontroler) rozdziela aplikację na trzy główne rodzaje komponentów, gdzie za dane (ich pozyskiwanie i przetwarzanie) odpowiadają "modele", za prezentację danych i interakcję z użytkownikiem odpowiadają "widoki", a przepływem informacji od użytkownika do odpowiednich komórek danych sterują "kontrolery". Tak więc dość naturalnym wydaje się utworzenie odpowiedniej struktury katalogów, która będzie wyglądać następująco:

models/
views/
controllers/

Frameworki

Jeżeli decydujemy się na framework, on sam wymusi na nas odpowiednią organizację projektu i jego układ. W tym przypadku większy problem sprawia zrozumienie intencji twórców frameworka i dostosowanie naszego wyobrażenia aplikacji do (zazwyczaj) sztywnych ram szkieletu. Niektóre frameworki są bardziej pobłażliwe i elastyczne- może to być zarówno wada i zaleta, jeżeli wiemy co robimy. Jeżeli nie wiemy co robimy, możemy skończyć w ślepym zaułku tak samo, jak przy braku frameworka.

Autorska struktura projektu

Warto podpytać starszych stażem programistów jak sobie radzą z nowymi projektami, zanim zaczniemy tworzyć własne. Nie ma jednak nic złego w eksperymentowaniu i tworzeniu całkowicie nowych, nie mających nic wspólnego z jakimkolwiek standardem struktur projektowych. W tym przypadku kartka papieru i ołówek jest najlepszym przyjacielem programisty. W tym momencie możemy poczuć się niczym architekt Matrixa i tworzyć niestworzone. Siedząc w kawiarni czy w ławce na lekcji/wykładzie można poczuć się naprawdę wyjątkowo. Przy tworzeniu nowej struktury warto mieć na uwadze:

  • Przepływ informacji- w jaki sposób komponenty nadrzędne rozgłaszają (propagują, wysyłają, wymieniają) dane z komponentami podrzędnymi. Szczególne zwrócenie uwagi na ten aspekt jest kluczowe. Najlepiej, gdy przepływ danych (ang. flow) jest w miarę jednokierunkowy, a komponenty wymieniają się danymi jedynie z najbliższymi sąsiadami w strukturze programu.
  • Potrzebne komponenty- lista kluczowych obiektów, na których będzie opierać się program. W zależności od projektu mogą to być np. komponenty związane z komunikacją sieciową, interface użytkownika czy wewnętrzne mechanizmy przetwarzania danych. Najprościej rzecz ujmując: czym będą kluczowe elementy programu.
  • Wyjście/Wejście- mechanizmy mówiące w jaki sposób program będzie pobierać dane i je prezentować. To zazwyczaj są "końcówki" architektury, na kartce papieru raczej są umieszczone gdzieś na krańcach strony.

Praktyka, praktyka i jeszcze raz praktyka

Niejeden program przyszło mi przepisywać i wypracowanie odpowiednich struktur pod konkretne technologie zawsze rozpoczyna się od wielogodzinnych dyskusji. Będę kompletnie szczery, w bardzo niewielu przypadkach jestem naprawdę zadowolony- zawsze widzę coś, co można zrobić lepiej. Podejrzewam, choć może to być nieco próżne, że każdy tak ma :)

Dobry kontent!

Piotr Poźniak

Piotr Poźniak

Programuję od ponad 15 lat. Prowadzę software house. Angażuję i zachęcam wszystkich do programowania w ramach inicjatywy Programowanie jest łatwe.

Bądź pierwszy, podziel się swoją opinią!