GoF Tasarım Desenleri - aslında hangilerini kullanıyorsunuz? [kapalı]


16

Meslektaşlarımı tasarım kalıpları konusunda eğitmeye çalışıyorum. Orijinal Dörtlü Gang desenleri biraz ezoterik, bu yüzden tüm programcıların bilmesi gereken bir "temel" desen alt grubu olup olmadığını merak ediyorum. Listeye baktığımda, muhtemelen kullandığımı düşünüyorum -

  • Soyut Fabrika
  • Fabrika Yöntemi
  • Singleton
  • Köprü
  • Cephe
  • komuta

Aslında pratikte hangilerini kullanıyorsunuz ve bunları ne için kullanıyorsunuz?

Bir kalıp listesi isteyenler için bağlantı


7
IMHO, soru faydalı tartışmalar vermek için çok belirsiz. Patern başına bir cevap mı yoksa patern kombinasyonu başına bir cevap mı istiyorsunuz?
Macke

Bu kalıpları kullanmanızın bazı nedenleri yararlı olabilir, aksi takdirde yalnızca kavramları listeliyorsunuz ... Şu soruyu sorduğunuzu düşünün: "Hangi anahtar kelimeleri kullanıyorsunuz?" ve " for, if, while...vb." listelerinin toplanması - bunun ne kadar anlamsız olacağını ölçmek zor.
ocodo

1
Slomojo'ya katılmıyorum - hangi anahtar kelimelerin yaygın olarak kullanıldığını ve hangilerinin bir dilde olmadığını bilmek oldukça kullanışlı olacağını düşünüyorum. Örneğin, temel sınıflar için de aynı şey geçerlidir.
Craig Schwarze

1
Biraz daha değiştirdi - umarım bu şimdi daha iyi bir tartışma yaratacaktır.
Craig Schwarze

1
Aslında ne tür meyveler yersiniz? Bu sorudan ne çıkarmayı umduğunu merak ediyorum. 3 veya 4 kişinin kullandığı bir desen görüyorsanız ama kullanmadıysanız, bu onu kullanmanıza neden olacak mı?
Marcie

Yanıtlar:


4

Pratikte kullandığım veya gördüğümlerin bir listesi:

Singleton - ASP.Net'teki uygulama nesnesi bunun en iyi örneğidir.

Bağdaştırıcı - Veritabanlarına bağlanmak genellikle en azından .Net şeyler alanımda bir Bağdaştırıcı sınıfı içerebilir.

Fabrika - Nesneleri üretmek için genel olarak bunu daha eski bazı klasik ASP'de gördüm.

Strateji - Her cihaz türü için, sınıf için benzer bir yapıya sahip olduğum bir uygulama vardı, bu modelin bir uygulamasını düşünürdüm.

Cephe - Bazı yönlerden bu genellikle birkaç sistemi birbirine bağlayan bir şey olması açısından Adaptör modeline benzer.


1
Tüm geçerli kullanımlar. Bunu okuyan herkes için - bu kalıpların kesinlikle bunlarla sınırlı olmadığını unutmayın.
Boris Yankov

5

Yazarlar, gerçek uygulamalarda buldukları gözlenen tasarımlardan desenleri derlediler. Hiç kimse muhtemelen hepsini kullanmaz, ancak hepsi kullanılır.


Hangisini smithco kullandınız ve ne için kullandınız?
Craig Schwarze

@CraigS Birçoğunu kullandım. Tasarım Desenlerinin yazarları, tanımladıkları her desenle bir dizi iyi örneğe sahiptir. Verebileceğim en iyi öneri kitabı iyice okumak için zaman harcamak.
smithco

3

Dekoratör .

DÜZENLEME : 'Önemsiz' aşamayı aşan hemen hemen her projede, bir IAction arayüzü bulunur (ayrıntılar farklı olabilir):

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

Ertesi saat IAction'ı uygulayan çok sayıda küçük, neredeyse önemsiz sınıflar yazmaya harcıyorum. Birleştirildiklerinde çok güçlü ve esnektirler.

Örn. LogAction(IAction'ı günlüğe kaydetmek ve gerçekleştirmek için yazın), NullAction(hiçbir şey yapmayın ve doğru dönmeyin), ( ActionListIActions listesini yapın ve bools'un ANDing'ini döndürün). Bazı durumlarda bir AndAction(iki eylemden VE-ing dönmek kısa devre veya olmasın olabilir), OrAction, NotActionmantıklı da.

Teknik olarak yukarıdaki örneklerden sadece LogAction bir Dekoratör olsa da (diğeri tam olarak 1 IAction'da çalışmaz), yine de IActions'ın LogActions'ının bir ActionList'ini yaptığımda bu dekoratör deseninin genelleştirilmesini düşünüyorum.


Ne için kullanıyorsun?
Craig Schwarze

1
@CraigS İstek üzerine örnek eklendi.
Sjoerd

Bu :) daha ince dekoratör ve aslında Composite bir karışımı, ve desenlerde zorluk bağımsız bunları kullanarak gelmiyor o mükemmel gösteri gibi görünüyor, ama bir araya onları karıştırma
Matthieu M.

Evet, bu bir klasik. Komut ile eşleştirilmiş Kompozittir. Aslında bu patten için bir isim var: buna "Spesifikasyon" ( en.wikipedia.org/wiki/Specification_pattern ) denir .
Martin Wickman

2

Soruyu kendi kodunda / projelerinde kalıp kullanımını kısıtlamak istediğinizi varsayalım (sınıf kütüphaneleri ve 3. taraf çerçeveleri yok).

Diğerleri gibi ben de en çok Fabrika kalıplarını kullandım . Sonra

  • Singleton : Günümüzde çok fazla değil, ancak yine de, genellikle küresel yapılandırma verileri için gereklidir.
  • Strateji ve Şablon Yöntemi : sık sık, örneğin uygulamamızda farklı hesaplama türlerini temsil etmek için
  • Oluşturucu : bir ana bilgisayar sistemiyle yapılan işlemlerin sonuçlarını çıktı nesnelerine toplamak için (bazı durumlarda çok sayıda metin ayrıştırma ve büyük nesne hiyerarşileri oluşturma)
  • Komut : Bunu yıllar önce bir kez uyguladım, ancak bugünlerde Java projemizde Callables'ı her zaman kullanıyorum, temelde Komutlar olduğuna inanıyorum

2

Daha önce bahsedilenlerin birçoğunu kullandım (Singleton, Factory, Builder, Command, Strategy, vb.)

Daha önce bahsetmediğim biri, çok sık kullanma eğiliminde olduğum Flyweight. Aşağıda örnek bir uygulama sağladım:

/**
 * 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) : "?";
    }
}

1
Daha az bilinen ama yine de inanılmaz derecede faydalı kalıplardan birini + 1'leyin.
MattDavey

2

Orijinal Dörtlü Gang desenleri bugün hala kullanılmaktadır, ancak kitapta olmayan şimdi popüler olanlar da vardır.

Kullandığınız dilde Design Patters için bir referans bulun. Daha somut olma eğilimindedirler ve kalıpları daha özlü ve zarif bir şekilde uygulamak için belirli dil özelliklerini kullanırlar.

Tasarım Desenleri için üç harika kaynak:

"Head First Design Patterns" Kitabı - tercih edilen dil Java'dır, ancak tüm dillerle ilgilidir. dofactory Tasarım Desenleri - büyük ve ücretsiz .net tasarım desenleri ile kod açıklamaları. PluralSight - Tasarım Desenleri Kütüphanesi - bu ücretli, ancak listeye dahil edilemeyecek kadar iyi.


1

ACE gibi ortak kütüphaneler kullanırsanız, kullandığınızdan daha fazlasını kullanırsınız. Observer / Observable'ı yoğun olarak kullanıyorum :-)


1

Bir Builder'ı en az bir kez kullandım (aynı dönüştürücü işlemi HTML veya Excel çıktısı oluşturabilir).

Sıklıkla Şablon Yöntemini kullanıyorum (JDBC ile ilgili görevler veya soyut Swing denetleyicileri için).

Bir keresinde form tabanlı bir uygulamaya birçok yeni özellik geliştirmek zorunda kaldım, ki bu bir karışıklıktı. Ancak mevcut şeyleri Devlet-desen temelli bir çözüme yeniden uyarladıktan sonra ilerleyebildim. (Pekala, çoğu).

Komutları da sık sık kullanıyorum (Salıncak Eylemleri) ve Gözlemciler.

Bir kez Swing formlarındaki değişiklikleri tespit etmek için Mememento benzeri bir çözüm kullandım. Form, önceki durumlarla karşılaştırdığımı (eşittir ()) durumunu serileştirir.


1

Onların kariyerim boyunca çoğuna sahip olduğuma inanıyorum. kullanmadığımdan emin olduğum tek şey, çoklu kalıtımın büyük bir hayranı olmadığım için kitapta çoklu kalıtımla uygulanan Adaptör Deseni.


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.