Jakie wzorce projektowe stosujecie najczęściej ?

0

Pytanie bardzo proste :) których warto wyuczyć się na blachę bo często się pojawiają a o których istnieniu i zastosowaniu wystarczy po prostu wiedzieć :) co wy na to ? Pytanie w kontekście C++ lub C#. Mi akurat tak się trafiło że w żadnym z projektów w których byłem nie był stosowany ŻADEN wzorzec projektowy O_O , na jednej rozmowie w sprawie pracy powiedziano mi nawet wprost "tutaj wzorców projektowych nie stosujemy w ogóle".

Wiec pytanie jakie są wasze doświadczenia w tym temacie?

0

jak chcesz się męczyć i wymyślać koło na nowo to nie stosuj. niektóre wzorce są na tyle oczywiste, że możesz je stosować nieświadomie np.:
http://en.wikipedia.org/wiki/Composite_pattern

0

Singleton jedynie mi się zdarza :P
EDIT:
No jak tu wymieniacie, to jeszcze u mnie dochodzi fabryka, fasada, adapter i pewnie jeszcze coś by się znalazło ;]

3

Nigdy nie myśle w kategoriach "jaki by tu wzorzec wpierdzielić". Jeżeli stosuje jakieś wzorce to raczej nieświadomie - zdarzyło się zastosować singleton, fabrykę, dekorator, adapter.

1

Fabryka oraz Singleton to podstawa, którą na pewno stosujesz.
Wzorzec to tylko sugestia jak rozwiązać pewien standardowy problem. Nikt nie karze ci trzymać się ściśle wzorca. Dla mnie określenie wzorca w komentarzu jest doskonałym ułatwieniem w analizowaniu cudzego kodu.
Zresztą często się zdarza, że ludzie stosują wzorce nieświadomie.

0

Zgadzam się , koła na nowo nie ma sensu wymyślać i często stosuje się wzorce różnego rodzaju nieświadomie ale dla przykładu jakie wzorce zdarzyło się wykorzystywać tobie ?

0

Akurat Singleton nie jest zbyt dobrym wzorcem. Beznadziejnie się to testuje, do tego dochodzi problem z thread-safety. Spopularyzowany przez PHP, gdzie ludzie się nie martwią ani jednym, ani drugim (bo tym akurat nie muszą).

8

wzorzec "to działa" (ang. "it works")

0

Wzorzec z którego wszyscy korzystają (nawet jeśli o tym nie wiedzą) czyli Strategia, pewnie czasem też Adapter i Fasada, oprócz tego przydatny może być Observer, MVC/MVP

0
przemek_l napisał(a):

na jednej rozmowie w sprawie pracy powiedziano mi nawet wprost "tutaj wzorców projektowych nie stosujemy w ogóle".

Ale to jakiś odgórny zakaz i dyscyplinarka w razie czego? ;)

Na pewno obserwator i iterator - te są wbudowane w składnię języka. Singleton się przydaje, ale tu nie ma się czym podniecać. Najczęściej chyba przydają mi się strategia i metoda szablonowa. Nigdy nie wykorzystałem fabryki ani metody wytwórczej, dla mnie to przerost formy nad treścią. Adapter czy fasadę stosuje się według potrzeb, więc też bez żadnej finezji.
Do tego oczywiście MVC, MVP, repository i unit of work.

6

@Shalom:
[o Strategii]

Ja myśle że jest, bo stosuje się ją automatycznie korzystając z dynamicznego polimorfizmu ;]

To stwierdzenie jest tak naciągane, że uznałbym je po prostu za nieprawdziwe ;).

Granice pomiędzy wzorcami projektowymi bywają niekiedy... rozmyte. Jednak żebyśmy mogli mówić o Strategii, muszą być spełnione warunki, które przeważnie nie są spełnione, gdy korzystamy z polimorfizmu, tj. np. traktujemy obiekt tak, jakby był pewnego abstrakcyjnego typu, podczas gdy naprawdę musi być (oczywiście) pewnego konkretnego podtypu.

We wzorcu Strategia mamy do czynienia z trzema artefaktami:

  1. Osłoniętym algorytmem, zwanym Strategią (to część wzorca Strategia -- charakterystyczna, ale nie jedyna; IMO nawet nie najbardziej charakterystyczna). Przeważnie mamy klasę abstrakcyjną, która rozwiązuje pewien problem i podklasy konkretne, które rozwiązują ten sam problem, ale każda za pomocą innego algorytmu.
  2. Obiektem bezpośrednio używającym algorytmu. Obiekt nazywamy czasem Kontekstem.
    [--- Tu się kończy implementacja samego wzorca Strategia ---]
  3. Klientami, którzy korzystają z naszego wzorca. Mają odniesienie do Kontekstu. Tworzą konkretne Strategie i przekazują je Kontekstowi.

Co najlepiej pozwala rozpoznać ten wzorzec, wg mnie?

Nie Strategie, tylko Kontekst. Kontekst posiada referencję do Strategii. Referencja jest typu abstrakcyjnego. Z tym rzeczywiście mamy do czynienia w zwykłym polimorfizmie -- przecież to zwykła kompozycja. Obiekt posiada referencję do innego obiektu.

Ale we wzorcu Strategia jest jeszcze jeden bajer: to klienci przekazują Kontekstowi referencję do konkretnej Strategii. Czyli wybierają, jak Kontekst rozwiąże pewien problem -- za pomocą jakiej Strategii (tj. jakiego algorytmu).

Wzorzec Strategia ma jeszcze kilka innych charakterystyk. Zadaniem Strategii jest kapsułkowanie algorytmu. Przeważnie posiada ona dokładnie jedną metodę publiczną, która wykonuje algorytm na danych zapewnionych przez Kontekst.

Same Strategie nie różnią się niczym od innego wzorca: Obiektu reprezentującego metodę. Bo Strategie to Obiekty reprezentujące metodę.

Bajer wzorca Strategia polega jednak na tym, że klienci mogą wymieniać algorytmy używane przez Kontekst.

Czym to się różni np. od wzorca Stan? W nim też mamy coś w rodzaju Kontekstu (to obiekt posiadający różne stany) i obiekty przypominające Strategie. Tylko te obiekty mają przeważnie więcej niż jedną metodę i są przez "Kontekst" samodzielnie wymieniane zgodnie z przejściami pomiędzy stanami.

Wzorca Strategia używa się w niektórych językach bardzo często. Można powiedzieć, że w JavaScripcie mamy z nim do czynienia na każdym kroku. Wzorzec jest bardzo dobrze wspierany przez konstrukcje języka. W JavaScripcie, funkcje są obiektami i można je tworzyć i np. przypisywać do zmiennych ad hoc, w dowolnym miejscu. Poszczególne Strategie to po prostu funkcje. Np. w takim kodzie:

var tablica = [1, 2, 3, 4]; // to samo co = new Array() + przypisywanie elementów
var kwadraty = tablica.map(function(element) {
  return element * element;
});
alert(kwadraty); // 1, 4, 9, 16

Tutaj tablicę można uznać za Kontekst, funkcję anonimową przekazywaną do .map() za Strategię, a cały ten wycinek kodu to kod kliencki. Mapujemy elementy tablicy (liczby) wg określonej Strategii (zwracającej kwadraty liczb).

BTW, @Shalom: w komentarzu pisałeś o szablonach jako statycznym polimorfizmie w C++. Akurat w książce Bandy Czterech wspominają o tym, że w ten sposób także można zrealizować Strategię. I też się liczy :).


Ja wzorców używam raczej często. Pracuję nad aplikacjami sterowanymi zdarzeniami, więc wzorzec Obserwator jest w użyciu non stop.

Singleton... w dużej aplikacji jakiś tam się trafi (np. pomaga zarządzać wersjami językowymi), ale nie nadużywam go, bo nie różni się on wiele od zmiennych globalnych i użycie Singletona to dla mnie zawsze lampka ostrzegawcza. Ludzie często jednak wyjeżdżają z Singletonem podczas rozmowy o wzorcach, nawet na rozmowach kwalifikacyjnych. Wydaje mi się, że to bardziej spowodowane jest tym, że wzorzec ten ma wpadającą w ucho nazwę ;D i jest prosty do zapamiętania.

Relatywnie często korzystam z leniwej inicjalizacji, która też jest swoistym wzorcem. Najczęściej piszę w JavaScripcie, który ma dziedziczenie prototypowe, więc automatycznie korzystam też ze wzorca Prototyp.

Metoda wytwórcza -- jak najbardziej. W JavaScripcie nie chodzi w niej jednak o to, żeby zwracała typ abstrakcyjny, a tworzyła konkretne obiekty, bo JS ma i tak bardzo dynamiczną typizację i nikogo nie obchodzi konkretny typ obiektu. Chodzi więc raczej o kapsułkowanie skomplikowanego tworzenia obiektu w jednej funkcji.

Budowniczy... użyłem na pewno w dwóch ostatnich aplikacjach, nad jakimi pracowałem. W tej ostatniej ze trzy, dość wypasione razy. Dwa służyły do zbudowania walidatorów obsługi formularzy. Trzeci... budował drzewo zależności pomiędzy plikami. To były funkcyjne, monadowe API.

Metoda szablonowa -- często. Staram się zawsze trzymać zasady Otwarty-Zamknięty. Piszę małe, niezależne funkcje, z czego jedna wywołuje drugą i chcę umożliwić łatwą wymianę dowolnej z nich.

Adapter zdarza się, gdy chcę dostosować jakieś stare/niewygodne/zmienne API. Kiedyś kumple-programiści z ówczesnego projektu dumali nad tym, jakim cudem chce mi się pisać testy automatyczne i stosować te wszystkie wzorce, podczas gdy pracujemy w dużym projekcie zahaczającym o bloatware i rozkład oprogramowania. Jeden stwierdził, że ja się po prostu okopałem warstwami abstrakcji od całego tego crapu i operowałem we... własnym crapie.

Fasada dość często, gdy chcę zapewnić bardzo proste API dla prostych przypadków. Niedawno trochę się zdziwiłem, gdy podliczyłem, że jedna Fasada, zapewniająca bodajże jedną czy dwie metody (choć ze sporymi możliwościami konfiguracji), korzysta wewnętrznie z już chyba kilkudziesięciu plików z kodem źródłowym, co dla JavaScriptu (bo w tym akurat pisałem) jest już czymś dość skomplikowanym.

Pewnie jeszcze trochę by się tego wszystkiego znalazło. O ile mi wiadomo, wzorców używam świadomie. Staram się też nadawać poszczególnym obiektom odpowiednie nazwy tak, by od razu było widać, że dany wzorzec jest w użyciu. Czyli np. XxxBuilder dla Budowniczych, a dla Metod wytwórczych createXxx().

edit:
Dekoratora w sumie też ostatnio użyłem. Do rodziny okienek typu "popup". Jeden moduł obsługiwał praktycznie całą aplikację webową (poza panelem administracyjnym). Dodatkowe zachowania -- np. keszowanie, walidacja, wysyłanie formularza ajaxem -- dodawało się do okienek dekoratorami.

Z popularnym Model-Widok-Kontroler oprócz przygód dobrych, miałem też dość nieprzyjemną -- w celach testowych trochę go nadużyłem, pisząc tak całą aplikację, która być może nie powinna być tak napisana. To jest mega-wzorzec, zaważył więc na całej architekturze aplikacji. Nie było tragicznie, ale nie było też za dobrze.

Iterator oczywiście jest używany na co dzień. W takiej Javie, z Iterable i wsparciem języka, wszystko jest jasne, ale wydaje mi się, że nawet w JavaScripcie, mimo wszystko, można nazwać popularne kontenery iteratorami wewnętrznymi:

// natywna tablica
var tab = ["a", "b", "c"];
tab.forEach(function(element) {
  alert(element);
  // jest iteracja? jest
});

// kolekcja jQuery
var $kolekcja = $(".moje-elementy");
$kolekcja.each(function(indeks, element) {
  $(element).hide(); // też się iterujemy
});

Na pewno jest to przykład iteracji wewnętrznej, choć zakres odpowiedzialności samych kontenerów jest oczywiście większy niż tylko iteracja. Można jednak powiedzieć, że kontenery te są iteratorami wewnętrznymi po samych sobie ;).

0

Fabryka, adapter, singleton, obserwator

0

Ja stosowałem singleton i fasada.

0

Obserwator, dekorator, model, singleton (jednak ostatnio czasem rezygnuję ze względu na wielowątkowość), fasada i ogólnie większość czego potrzeba przy MVC.

0

Wszystko, w różnym nasileniu, większość wzorców pojawia się naturalnie w pewnych sytuacjach. Naczęściej stosowanym jest chyba strategia, przynajmniej z tych, które nie wynikają z konstrukcji języka i jego bibliotek. Natomiast najczęściej nadużywanym wzorcem był zdecydowanie template method, zdarzyło mi się stosować TM zamiast strategii, komplikując prosty projekt i utrudniając jego testowanie.

Singleton to często raczej antywzorzec, DI sprawniej rozwiązuje wiele problemów, zapewniając przy tym przewidywalny czas życia i redukując zależności. Niezłą alternatywą jest borg pattern (monostate), nie jest jednak pozbawiony wszystkich wad singletonu.

Chętnie popracowałbym z projektem używającym cake pattern, jeszcze nie miałem okazji.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.