Wzory projektowe GoF - z których faktycznie korzystasz? [Zamknięte]

16

Staram się edukować moich kolegów w zakresie wzorców projektowych. Niektóre z oryginalnych wzorców Gang of Four są trochę ezoteryczne, więc zastanawiam się, czy istnieje podgrupa „niezbędnych” wzorców, którą wszyscy programiści powinni znać. Przeglądając listę, myślę, że prawdopodobnie użyłem -

  • Fabryka abstrakcyjna
  • Metoda fabryczna
  • Singel
  • Most
  • Fasada
  • Komenda

Z których faktycznie korzystasz i do czego je wykorzystujesz?

Link dla tych, którzy chcą listy wzorów

Craig Schwarze
źródło
7
IMHO, pytanie jest zbyt niejasne, by prowadzić użytecznej dyskusji. Czy chcesz jedną odpowiedź na wzór lub jedną odpowiedź na kombinację wzorów?
Macke
Przydałoby się kilka powodów, dla których używasz tych wzorców, w przeciwnym razie wymieniasz pojęcia ... Wyobraź sobie pytanie: „Jakich słów kluczowych używasz?” i zbieranie list „ for, if, while...etc” - trudno zmierzyć, jak bezcelowe byłoby to.
ocodo
1
Nie zgadzam się ze Slomojo - myślę, że dobrze byłoby wiedzieć, które słowa kluczowe były powszechnie używane, a które nie były w języku. To samo dotyczy na przykład klas podstawowych.
Craig Schwarze
1
Zmodyfikowałem go nieco bardziej - mam nadzieję, że teraz przyniesie to lepszą dyskusję.
Craig Schwarze
1
Jakie rodzaje owoców faktycznie jesz? Jestem ciekawy, co masz nadzieję uzyskać z tego pytania. Jeśli widzisz wzór, którego użyły 3 lub 4 osoby, ale go nie znasz, czy to sprawi, że będziesz go używać?
Marcie

Odpowiedzi:

4

Oto lista tych, z których korzystałem lub widziałem w praktyce:

Singleton - obiekt aplikacji w ASP.Net będący tego najlepszym przykładem.

Adapter - Łączenie z bazami danych zwykle może obejmować klasę Adaptera przynajmniej w moim obszarze .Net.

Fabryka - ogólne informacje na temat generowania obiektów, chociaż widziałem to więcej w niektórych starszych klasycznych ASP w tamtych czasach.

Strategia - miałem aplikację, która dla każdego typu urządzenia miała podobną strukturę dla klasy, że rozważałbym implementację tego wzorca.

Fasada - pod pewnymi względami jest to podobne do wzorca adaptera, ponieważ jest czymś, co łączy ze sobą zwykle kilka systemów.

JB King
źródło
1
Wszystkie ważne zastosowania. Dla każdego, kto to czyta - pamiętaj, że te wzorce z pewnością nie są do nich ograniczone.
Boris Yankov,
5

Autorzy opracowali wzory z zaobserwowanych projektów, które znaleźli w rzeczywistych zastosowaniach. Nikt prawdopodobnie nie użyje ich wszystkich, ale wszystkie są wykorzystywane.

smithco
źródło
Do czego użyłeś smithco i po co?
Craig Schwarze
@CraigS Użyłem wielu z nich. Autorzy wzorców projektowych mają zestaw dobrych przykładów do każdego opisywanego wzoru. Najlepsze, co mogę dać, to poświęcić czas na dokładne przeczytanie książki.
smithco,
3

Dekorator .

EDYCJA : W prawie każdym projekcie, który wychodzi poza „trywialny” etap, kończy się interfejsem IAction (szczegóły mogą się różnić):

// Programming Language does not matter
interface IAction {
     bool operateOn(Foo* target);
     string getDisplayName(); // useful for debugging and logging
};

Następną godzinę spędzam na pisaniu wielu małych, prawie trywialnych zajęć, które wdrażają IAction. W połączeniu są bardzo mocne i elastyczne.

Np. LogActionAn (napisz, aby zalogować i wykonać IAction), NullAction(nic nie rób i zwróć true), ActionList(wykonaj listę IAction i zwróć ANDing booli). W niektórych przypadkach AndAction(zwróć AND dwóch akcji, może być zwarty lub nie) OrAction, NotActionma również sens.

Chociaż technicznie z powyższych przykładów tylko LogAction jest dekoratorem (drugi nie działa dokładnie na 1 IAction), nadal uważam to za uogólnienie wzoru Dekoratora, kiedy tworzę ActionList LogAction z IAction.

Sjoerd
źródło
Do czego tego używasz?
Craig Schwarze
1
@CraigS Przykład dodany na żądanie.
Sjoerd,
Wygląda bardziej jak połączenie Dekoratora i Kompozytu, co jest w porządku, i doskonały dowód na to, że trudność we wzorach nie wynika z ich samodzielnego używania, ale z mieszania ich razem :)
Matthieu M.
Tak, to klasyk. Jest złożony z poleceniem. W rzeczywistości istnieje nazwa tego wzoru: nazywa się on „Specification” ( en.wikipedia.org/wiki/Specification_pattern ).
Martin Wickman,
2

Zakładam, że masz zamiar ograniczyć pytanie do użycia wzorców we własnym kodzie / projektach (bez bibliotek klas i frameworków stron trzecich).

Podobnie jak inni, najczęściej używałem również wzorów Factory . Następnie

  • Singleton : obecnie nie tyle, ale czasem jest to konieczne, zazwyczaj w przypadku globalnych danych konfiguracyjnych
  • Strategia i metoda szablonu : dość często, np. Do reprezentowania różnego rodzaju obliczeń w naszej aplikacji
  • Konstruktor : do zestawiania wyników transakcji z systemem mainframe w obiekty wyjściowe (w niektórych przypadkach zawiera wiele analizowania tekstu i tworzenia hierarchii dużych obiektów)
  • Polecenie : wdrożyłem go tylko raz wiele lat temu, ale obecnie w naszym projekcie Java od czasu do czasu używam Callables, które moim zdaniem są w zasadzie Poleceniami
Péter Török
źródło
2

Użyłem wielu innych, o których już wspomniano (Singleton, Factory, Builder, Command, Strategy itp.)

Jednym, o którym jeszcze nie wspominałem, jest Flyweight, którego często używam. Poniżej podałem przykładową implementację:

/**
 * Flyweight class representing OCR digits.
 * 
 * @author matt
 *
 */
public class Digit {
    /** Static flyweight map containing Digits which have been encountered. **/
    private static Map digits = new HashMap();

    /** The block of text representing Digit. **/
    private String blockRep = null;

    /** A map representing acceptable blocks of characters and the string representation of their
     * numerical equivalents.
     */
    public static final Map VALID_DIGITS;

    /** Enum of valid digits. **/
    public static enum DigitRep {
        ZERO    (   " _ \n" +
                    "| |\n" +
                    "|_|"       ),

        ONE (       "   \n" +
                    "  |\n" +
                    "  |"       ),

        TWO (       " _ \n" +
                    " _|\n" +
                    "|_ "       ),

        THREE   (   " _ \n" +
                    " _|\n" +
                    " _|"       ),

        FOUR    (   "   \n" +
                    "|_|\n" +
                    "  |"       ),

        FIVE    (   " _ \n" +
                    "|_ \n" +
                    " _|"       ),

        SIX     (   " _ \n" +
                    "|_ \n" +
                    "|_|"       ),

        SEVEN   (   " _ \n" +
                    "  |\n" +
                    "  |"       ),

        EIGHT   (   " _ \n" +
                    "|_|\n" +
                    "|_|"       ),

        NINE    (   " _ \n" +
                    "|_|\n" +
                    " _|"       );

        private String blockRep;

        DigitRep(String blockRep) {
            this.blockRep = blockRep;
        }

        @Override
        public String toString() {
            return blockRep;
        }
    }

    static {
        /* Initialize the map of acceptable character blocks. */
        Map tmpMap = new HashMap();
        tmpMap.put( DigitRep.ZERO.toString(),   "0");
        tmpMap.put( DigitRep.ONE.toString(),    "1");
        tmpMap.put( DigitRep.TWO.toString(),    "2");
        tmpMap.put( DigitRep.THREE.toString(),  "3");
        tmpMap.put( DigitRep.FOUR.toString(),   "4");
        tmpMap.put( DigitRep.FIVE.toString(),   "5");
        tmpMap.put( DigitRep.SIX.toString(),    "6");
        tmpMap.put( DigitRep.SEVEN.toString(),  "7");
        tmpMap.put( DigitRep.EIGHT.toString(),  "8");
        tmpMap.put( DigitRep.NINE.toString(),   "9");       
        VALID_DIGITS = Collections.unmodifiableMap(tmpMap);
    }

    /**
     * Private constructor to enforce flyweight/factory pattern.
     * 
     * @param blockRep
     */
    private Digit(String blockRep) {
        this.blockRep = blockRep;
    }

    /**
     * Flyweight factory method to create a Digit object from the "block"
     * representation of the digit.
     * @param blockRep The "block" representation of a digit.  Should look
     * something like:
     * " _ \n"
     * "|_|\n"
     * "|_|"
     * @return A flyweight Digit object representing the digit.
     */
    public static synchronized Digit getDigit(String blockRep) {
        Digit digit = digits.get(blockRep);
        if(digit == null) {
            digit = new Digit(blockRep);
            digits.put(blockRep, digit);
        }

        return digit;
    }

    /**
     * Determines whether or not the digit is valid.
     * @return true if the digit is valid, else false.
     */
    public boolean isValid() {
        return VALID_DIGITS.containsKey(blockRep);
    }

    /**
     * Accessor method to get the block representation of this digit.
     * 
     * @return
     */
    public String getBlockRep() {
        return blockRep;
    }

    @Override
    public String toString() {
        return VALID_DIGITS.containsKey(blockRep) ? VALID_DIGITS.get(blockRep) : "?";
    }
}
Matt Caldwell
źródło
1
+1 jeden z mniej znanych, ale wciąż niezwykle przydatnych wzorów.
MattDavey,
2

Większość oryginalnych wzorów Gang of Four jest nadal używana, ale są też inne popularne obecnie, których nie ma w książce.

Znajdź referencje dla Design Patters w języku, którego używasz. Zwykle są bardziej konkretne i wykorzystują określone funkcje językowe do implementacji wzorców w bardziej zwięzły i elegancki sposób.

Trzy świetne zasoby dotyczące Wzorów Projektowych:

Książka „Head First Design Patterns” - językiem z wyboru jest Java, ale dotyczy wszystkich języków. Wzorce projektowe dofactory - świetne i darmowe objaśnienia wzorców projektowych .net z kodem. PluralSight - Biblioteka wzorców projektowych - ta jest płatna, ale jest zbyt dobra, aby nie uwzględniać jej na liście.

Borys Jankow
źródło
1

Cóż, jeśli korzystasz ze zwykłych bibliotek, takich jak ACE, ostatecznie używasz więcej, niż myślisz. Używam Observer / Observable intensywnie :-)

Maniak
źródło
1

Użyłem Konstruktora co najmniej raz (ten sam proces konwertera mógł zbudować dane wyjściowe HTML lub Excel).

Często używam metody szablonów (do zadań związanych z JDBC lub abstrakcyjnych kontrolerów Swing).

Kiedyś musiałem opracować wiele nowych funkcji w aplikacji opartej na formularzu, co było bałaganem. Mogłem się rozwijać dopiero po przebudowaniu istniejących rzeczy na rozwiązanie oparte na wzorcach państwowych. (Cóż, większość).

Często używam również poleceń (Swing Actions), a także obserwatorów.

Kiedyś użyłem rozwiązania przypominającego Mememento do wykrywania zmian w formularzach Swing. Formularz serializowałby swój stan, co porównałem (równa się ()) z wcześniejszymi stanami.

Karl
źródło
1

Wierzę, że mam ich najwięcej w całej mojej karierze. jedyny, którego jestem pewien, że nie użyłem, to wzorzec adaptera, który został zaimplementowany z wielokrotnym dziedziczeniem w książce, ponieważ nie jestem wielkim fanem wielokrotnego dziedziczenia.

Raphael
źródło
1

Lubię dekoratora. Jedyne, co dodałem do wymienionych, to Proxy.

Chuck Stephanski
źródło