Soru Strateji Örüntüsünün Gerçek Dünya Örneği


Hakkında okuyorum OCP müdürü ve bunu başarmak için strateji kalıbını nasıl kullanacağız.

Bunu bir kaç insana açıklamaya çalışacağım, ama düşünebildiğim tek örnek, "sipariş" statüsüne göre farklı doğrulama sınıfları kullanmaktır.

İnternetten birkaç makale okudum, ancak bunlar genellikle stratejiyi kullanmak için raporlar / faturalar / doğrulama vb.

Bir strateji paterninin yaygın olduğunu düşündüğünüz gerçek dünya örnekleri var mı?


76
2017-12-16 01:29


Menşei




Cevaplar:


Peki buna ne dersin:

Bir dosyayı şifrelemek zorundasınız.

Küçük dosyalar için, tüm dosyanın okunduğu ve bellekte saklandığı "bellekte" stratejisini kullanabilirsiniz (dosyalar için <1 gb diyelim).

Büyük dosyalar için, dosyanın bölümlerinin bellekte okunduğu ve kısmi şifreli sonuçların tmp dosyalarında saklandığı başka bir strateji kullanabilirsiniz.

Bunlar aynı görev için iki farklı strateji olabilir.

Müşteri kodu aynı görünecektir:

 File file = getFile();
 Cipher c = CipherFactory.getCipher( file.size() );
 c.performAction();



// implementations:
interface  Cipher  {
     public void performAction();
}

class InMemoryCipherStrategy implements Cipher { 
         public void performAction() {
             // load in byte[] ....
         }
}

class SwaptToDiskCipher implements Cipher { 
         public void performAction() {
             // swapt partial results to file.
         }

}

     Cipher c = CipherFactory.getCipher( file.size() );

Şifre için doğru strateji örneğini döndürürdüm.

Umarım bu yardımcı olur.

(Cipher'in doğru kelime olup olmadığını bile bilmiyorum: P)


86
2017-12-16 01:40



Örneğiniz daha fazla bir Fabrika Kalıbı değil mi? Ayrıca C # olarak çalışmayacağını düşünüyorum. "GetCipher ()" yönteminiz statik bir yöntemdir, ancak C # 'de bir arabirimde statik bir yöntem tanımlayamazsınız (Java'da bunu düşünmüyorum ama bunun için emin değilim). - FrenchData
Beraberler. Fabrika stratejiyi yaratır, fakat kendi stratejisi (temelde) aynı işlemi gerçekleştirmek için algoritmayı kullanır. Strateji çalışma zamanında da değiştirilebilir. Doğru olan fabrika yöntemi hakkında, onu değiştirdim. - OscarRyz
Osacars noktasına eklemek için, fabrika olmadan bu fabrika olmadan oluşturulabilir Cipher C =null; if (file.size() <= 2048) { C = new InMemoryCipherStrategy(); } else { c= SwaptToDiskCipher (); } - Abhijit Mazumder
@FrenchData ile katılıyorum. Harika bir örnek olmakla birlikte CipherFactory Strateji modeline aşina olmayanları karıştırır. - Tim Bezhashvyly
Fabrika modeli yaratılış hakkında, Strateji Davranışla ilgili. Biraz farklı bir hak var mı? - nhoxbypass


Yine, eski bir yazı ama yine de aramalara çıkıyor, böylece iki tane daha örnek ekleyeceğim (Kod C #). Proje yöneticileri, “Uygulamayı 'X' yapmak istiyoruz ama 'X' henüz net değil ve yakın gelecekte değişebilir. " Bu strateji modelini açıklayan video, StarCraft örnek olarak kullanır.

Bu kategoriye girenler:

  • Sıralama: Bu sayıları sıralamak istiyoruz, ancak BrickSort, BubbleSort veya başka bir sıralama kullanıp kullanmayacağımızı bilmiyoruz.

  • Doğrulama: "Bazı kurallara" göre öğeleri kontrol etmeliyiz, ancak bu kuralın ne olacağı henüz belli değil ve yeni olanları düşünebiliriz.

  • Oyunlar: Oyuncunun hareket ettiğinde yürümesini ya da koşmasını istiyoruz, ama belki de gelecekte, yüzmeyi, uçmayı, ışınlamayı, yer altına yuvarlanmayı vb.

  • Bilginin depolanması: Uygulamanın Veritabanına bilgi depolamasını istiyoruz, ancak daha sonra bir dosyayı kaydetme veya bir web çağrısı yapabilmemiz gerekebilir.

  • Çıktı: X'i düz bir dize olarak çıkarmalıyız, ancak daha sonra bir CSV, XML, JSON vb.


Örnekler

Kullanıcıların bir veritabanındaki insanlara ürün atayabileceği bir projem var. Bir ürünün bir kişiye bu ataması, bazı iş kurallarına bağlı olan "Onaylandı" veya "Reddedildi" durumundadır. Örneğin: Bir kullanıcı belirli bir yaştaki bir kullanıcıya ürün atarsa, durumun reddedilmesi gerekir; Öğedeki iki alan arasındaki fark 50'den büyükse, durumu reddedilir, vb.

Şimdi, geliştirme aşamasında bu iş kuralları henüz tamamen açık değildir ve yeni kurallar her an ortaya çıkabilir. Stragety modelinin gücü, bir IRule listesi verilen bir RuleAgent yaptığım.

public interface IRule {
    bool IsApproved(Assignment assignment); 
 }

Bir kişiye bir ürün ataması sırasında, bir RuleAgent yaratıyorum, bir kural listesi (tüm IRule'yi uygular) verin ve bir atamayı doğrulamasını isteyin. Tüm kuralları ile koşacak. Hangi, hepsi aynı arayüzü, çünkü hepsi var IsApproved Herhangi biri yanlışsa döndürürse yöntem ve yanlış döndür.

Mesela yönetici aniden ortaya çıkıyor ve diyor ki, tüm ödevleri stajyerlere ya da fazla mesai yapan insanlara yapılan tüm ödevleri reddetmeliyiz ... Bunun gibi yeni sınıflar oluşturuyorsunuz:

public OvertimeRule : IRule
{
    public bool IsApproved(Assignment assignment) //Interface method
    {
        if (assignment.Person.Timesheet >= 40)
        {
            return false;
        }
        return true;
    }
}

public InternRule : IRule
{
    public bool IsApproved(Assignment assignment) //Interface method
    {
        if (assignment.Person.Title == "Intern")
        {
            return false;
        }
        return true;
    }
}

İfadeleri veya kodları eklemeye veya kaldırmaya devam etmek zorunda olmadığınızı görüyorsunuz, sadece IRUle arayüzünü uygulayan yeni bir kural sınıfı hazırlayın ve gerektiğinde bunları değiştirin.


Bir başka harika örnek: Scott Allen'ın video dizisi http://www.asp.net/mvc/pluralsight Uygulamanın Birim-test bölümünde strateji modelini nerede kullanır?

Popülerliğe göre öğeleri görüntüleyen bir sayfa içeren bir web sitesi oluşturur. Ancak "Popüler" birçok şey olabilir (çoğu görüntüleme sayısı, çoğu abone, oluşturma tarihi, en fazla etkinlik, en az yorum miktarı vb.) Ve yönetimin henüz nasıl sipariş verileceğini tam olarak bilmemesi ve farklı bir şekilde denemeyi isteyebilmesi daha sonraki bir tarihte siparişler. Bir sipariş yöntemiyle bir arabirim (IOrderAlgorithm veya bir şey) yaparsınız ve bir Orderer nesnesinin siparişi IOrderAlgorithm arabiriminin somut bir uygulamasına vermesine izin verirsiniz. Bir "CommentOrderer", "ActivityOrderer", vb. Yapabilirsin ... Ve yeni gereksinimler ortaya çıktığında bunları değiştir.


43
2018-01-16 14:57





Oldukça basit birkaç örneği düşünebilirim:

  • Bir listeyi sıralama. Strateji, listedeki iki öğeden hangisinin "İlk" olduğuna karar vermek için kullanılan karşılaştırmadır.
  • Sıralama algoritmasının kendisinin (QuickSort, HeapSort, vb.) Çalışma zamanında seçilebileceği bir uygulamanız olabilir.
  • Ekler, Düzenler ve Filtreler Log4Net ve log4j
  • Düzen Yöneticileri UI araç takımlarında
  • Veri sıkıştırma. Tek yöntemi şunun gibi görünen bir ICompressor arabiriminiz olabilir:

    byte [] sıkıştır (byte [] girişi);

    Beton sıkıştırma sınıflarınız RunLengthCompression, DeflateCompression vs. gibi şeyler olabilir.


11
2018-01-08 21:07





Strateji örüntüsünün yaygın bir kullanımı, özel sıralama stratejileri tanımlamaktır (yüksek sıralı fonksiyonlar olmayan dillerde), ör. Java'daki bir dizinin listesini, anonim bir iç sınıftan geçirerek (strateji arayüzünün bir uygulaması):

List<String> names = Arrays.asList("Anne", "Joe", "Harry");
Collections.sort(names, new Comparator<String>() {
  public int compare(String o1, String o2) {
    return o1.length() - o2.length();
  }
});
Assert.assertEquals(Arrays.asList("Joe", "Anne", "Harry"), names);

Benzer şekilde, nesne veri tabanları ile yerel sorgular için stratejiler kullanılabilir, örn. db4o'da:

List<Document> set = db.query(new Predicate<Document>() {
  public boolean match(Document candidate) {
    return candidate.getSource().contains(source);
  }
});

9
2018-01-11 16:12





Her gün kullanıcı tabanını kurumsal dizinimize göre senkronize eden bir uygulama var. Kullanıcı, Üniversitedeki statülerine göre uygun veya uygun değildir. Her gün provizyon programı yürürlüğe girer ve başvuruda bulunacak olanların başvuruda sağlandığından ve de-provizyon almayanlardan (gerçekten degradasyon algoritmasına göre, fakat bu noktanın yanında) emin olunmasını sağlar. Cumartesi günü, her kullanıcının bazı özelliklerini senkronize etmenin yanı sıra uygun uygunluğa sahip olduklarından emin olmak için daha kapsamlı bir güncelleme yapıyorum. Ayın sonunda o ay için kullanım bazında bir miktar fatura iadesi işlemi yapıyorum.

Bu senkronizasyonu yapmak için bir kompozisyon oluşturabilirim. Ana program temel olarak haftanın gününe bağlı olarak bir ana stratejiyi seçer (yalnızca senkronizasyon değişiklikleri / tümünü senkronize et) ve akademik takvime göre dönem süresi. Faturalandırma döngüsü biterse, faturalandırma stratejisiyle de oluşturur. Daha sonra seçilen stratejiyi standart bir arayüz üzerinden çalıştırır.

Bunun ne kadar yaygın olduğunu bilmiyorum ama strateji modeli için mükemmel bir uyum olduğunu hissettim.


8
2017-12-16 02:36



Bu çok güzel bir örnek. Ayrıca, açık bir şekilde komut ve strateji deseni arasındaki farkı açık bir şekilde anlatıyor - amaç. "Temel program temelde seçer Haftanın gününe bağlı olarak bir ana strateji " - Utsav T


Anahtar notlar:

  1. strateji davranış tasarım desenidir. Algoritma ailesi arasında geçiş yapmak için kullanılır.

  2. Bu model bir soyut strateji içeriyor arayüzey ve çoğu beton strateji uygulamaları (algoritmalarBu arayüzün

  3. Uygulama strateji kullanıyor arayüzey bir tek. Bazı yapılandırma parametrelerine bağlı olarak, somut strateji etiketlenecek arayüzey.

UML Şeması wikipedia

enter image description here

Bir gerçek kelime örneği: Bazı aylarda indirimler sunan havayolları (Temmuz-Aralık). Bir tane alabilirsin Ücret ay numarasına bağlı olarak fiyatlandırma seçeneklerine karar veren modül.

Basit bir örneğe bakın. Bu örnek, alışveriş sepetlerine özel günlerde / indirimli saatlerde kolayca indirim sağlayan çevrimiçi perakendecilik uygulamalarına genişletilebilir.

import java.util.*;

/* Interface for Strategy */
interface OfferStrategy {
    public String getName();
    public double getDiscountPercentage();
}
/* Concrete implementation of base Strategy */
class NoDiscountStrategy implements OfferStrategy{
    public String getName(){
        return this.getClass().getName();
    }
    public double getDiscountPercentage(){
        return 0;
    }
}
/* Concrete implementation of base Strategy */
class QuarterDiscountStrategy implements OfferStrategy{
    public String getName(){
        return this.getClass().getName();
    }
    public double getDiscountPercentage(){
        return 0.25;
    }
}
/* Context is optional. But if it is present, it acts as single point of contact
   for client. 

   Multiple uses of Context
   1. It can populate data to execute an operation of strategy
   2. It can take independent decision on Strategy creation. 
   3. In absence of Context, client should be aware of concrete strategies. Context acts a wrapper and hides internals
   4. Code re-factoring will become easy
*/
class StrategyContext {
    double price; // price for some item or air ticket etc.
    Map<String,OfferStrategy> strategyContext = new HashMap<String,OfferStrategy>();
    StrategyContext(double price){
        this.price= price;
        strategyContext.put(NoDiscountStrategy.class.getName(),new NoDiscountStrategy());
        strategyContext.put(QuarterDiscountStrategy.class.getName(),new QuarterDiscountStrategy());        
    }
    public void applyStrategy(OfferStrategy strategy){
        /* 
        Currently applyStrategy has simple implementation. You can use Context for populating some more information,
        which is required to call a particular operation            
        */
        System.out.println("Price before offer :"+price);
        double finalPrice = price - (price*strategy.getDiscountPercentage());
        System.out.println("Price after offer:"+finalPrice);
    }
    public OfferStrategy getStrategy(int monthNo){
        /*
            In absence of this Context method, client has to import relevant concrete Strategies everywhere.
            Context acts as single point of contact for the Client to get relevant Strategy
        */
        if ( monthNo < 6 )  {
            return strategyContext.get(NoDiscountStrategy.class.getName());
        }else{
            return strategyContext.get(QuarterDiscountStrategy.class.getName());
        }

    }
}
public class StrategyDemo{    
    public static void main(String args[]){
        StrategyContext context = new StrategyContext(100);
        System.out.println("Enter month number between 1 and 12");
        int month = Integer.parseInt(args[0]);
        System.out.println("Month ="+month);
        OfferStrategy strategy = context.getStrategy(month);
        context.applyStrategy(strategy);
    }

}

çıktı:

Enter month number between 1 and 12
Month =1
Price before offer :100.0
Price after offer:100.0

Enter month number between 1 and 12
Month =7
Price before offer :100.0
Price after offer:75.0

Faydalı makaleler:

strateji dzone tarafından desen

strateji sourcemaking tarafından desen


8
2018-02-03 14:52





Bunun eski bir soru olduğunu biliyorum, ama son zamanlarda uyguladığım ilginç bir örneğim var.

Bu, bir belge dağıtım sisteminde kullanılan strateji modelinin çok pratik bir örneğidir.

Çok sayıda belge ve bazı meta veriler içeren bir arşiv alan bir PDF dağıtım sistemi vardı. Meta verilere dayanarak, belgenin nereye yerleştirileceğine karar verdi; Verilere bağlı olarak, belgeyi A, Bveya C depolama sistemleri veya üçünün bir karışımı.

Farklı müşteriler bu sistemi kullandılar ve hata durumunda farklı geri alma / hata işleme gereklilikleri vardı: Biri teslimat sisteminin ilk hatada durmasını, halihazırda depolarında teslim edilen tüm belgeleri bırakmasını istedi, ancak işlemi durdurdu ve başka bir şey sunmadı. ; başka bir tanesi geri almak istedi B depolanırken hata olması durumunda C, ancak zaten teslim edilmiş olanları bırakın A. Üçüncü veya dördüncüsünün de farklı ihtiyaçları olduğunu hayal etmek kolay.

Sorunu çözmek için, teslimat mantığını içeren temel bir teslimat sınıfını ve tüm depolardan geri alma yöntemlerini oluşturdum. Bu yöntemler, aslında hata durumunda doğrudan teslimat sistemi tarafından aranmaz. Bunun yerine, sınıf bir "Geri Alma / Hata İşleme Stratejisi" sınıfını (sistemi kullanan müşteriye dayalı olarak) almak için Bağımlılık Enjeksiyonu kullanır. Bu hatalar, söz konusu strateji için uygunsa geri alma yöntemlerini çağırır.

Teslimat sınıfının kendisi, strateji sınıfına ne olduğunu bildirir (hangi belgelerin depoya verildiğini ve hangi hataların gerçekleştiğini gösterir) ve bir hata oluştuğunda, devam edip etmeme konusunda strateji ister. Strateji "durdur" yazıyorsa, sınıf, stratejinin "cleanUp" yöntemini çağırır. Bu yöntem, daha önce bildirilen bilgileri, teslim sınıfından hangi rollback yöntemlerini çağırması gerektiğine karar vermek için kullanır veya basitçe hiçbir şey yapmaz.

rollbackStrategy.reportSuccessA(...);
rollbackStrategy.reportFailureB(...);

if (rollbackStrategy.mustAbort()) {
    rollbackStrategy.rollback(); // rollback whatever is needed based on reports
    return false;
}

Yani şimdi iki farklı stratejim var: biri QuitterStrategy (ilk hatadan vazgeçer ve hiçbir şeyi temizler) diğeri ise MaximizeDeliveryToAStrategy (Bu işlemin durdurulmaması ve depoya teslim edilen malzemelerin hiçbir zaman geri alınmaması için mümkün olduğu kadar çalışır. A, ancak geri bildirimler B eğer teslimat için C ) Başarısız olur.

Anlayışımdan, bu strateji modelinin bir örneğidir. Eğer (evet, sen okuyorsun) yanlış olduğumu düşünüyorsanız, lütfen aşağıya yorum yapın ve bana bildirin. Strateji örüntüsünün "saf" bir kullanımının ne olacağını ve uygulamamın hangi yönlerinin tanımı ihlal ettiğini merak ediyorum. Biraz komik görünüyor çünkü strateji arayüzü biraz şişman. Şimdiye kadar gördüğüm tüm örnekler sadece bir metodu kullanıyor, ama yine de bunun bir algoritmayı kapsandığını düşünüyorum (eğer bir iş mantığı bir algoritma olarak düşünülebiliyorsa).

Strateji ayrıca dağıtım yürütme sırasında olaylar hakkında bildirildiğinden, aynı zamanda bir Gözlemciama bu başka bir hikaye.

Küçük bir araştırma yapmadan, bu "kompozit bir model" gibi görünüyor (MVC gibi, belirli bir şekilde altında birçok tasarım desenleri kullanan bir desen) danışman. Teslimatın devam edip etmemesi gerektiğine dair bir danışman, ama istendiği zaman geri alma yapabildiğinden aktif bir hata işleyicisi.

Her neyse, bu, strateji paterninin kullanımının çok basit / aptalca olduğu hissini yaratabilecek oldukça karmaşık bir örnektir. Diğer modellerle birlikte kullanıldığında gerçekten karmaşık ve hatta daha uygulanabilir.


7
2017-10-05 05:57





Strateji modeli, doğrulama ve sıralama algoritmaları için özel olarak en çok kullanılan modeldir.

Basit bir pratik örnekle açıklamama izin ver

enum Speed {
  SLOW, MEDIUM, FAST;
}

class Sorter {
 public void sort(int[] input, Speed speed) {
    SortStrategy strategy = null;
    switch (speed) {
    case SLOW:
        strategy = new SlowBubbleSortStrategy();
        break;
    case MEDIUM:
        strategy = new MediumInsertationSortStrategy();
        break;

    case FAST:
        strategy = new FastQuickSortStrategy();
        break;
    default:
        strategy = new MediumInsertationSortStrategy();
    }
    strategy.sort(input);
 }

}

interface SortStrategy {

    public void sort(int[] input);
}

class SlowBubbleSortStrategy implements SortStrategy {

   public void sort(int[] input) {
    for (int i = 0; i < input.length; i++) {
        for (int j = i + 1; j < input.length; j++) {
            if (input[i] > input[j]) {
                int tmp = input[i];
                input[i] = input[j];
                input[j] = tmp;
            }
        }
    }
    System.out.println("Slow sorting is done and the result is :");
    for (int i : input) {
        System.out.print(i + ",");
    }
  }

 }

class MediumInsertationSortStrategy implements SortStrategy {

public void sort(int[] input) {
    for (int i = 0; i < input.length - 1; i++) {
        int k = i + 1;
        int nxtVal = input[k];
        while (input[k - 1] > nxtVal) {
            input[k] = input[k - 1];
            k--;
            if (k == 0)
                break;
        }
        input[k] = nxtVal;
    }
    System.out.println("Medium sorting is done and the result is :");
    for (int i : input) {
        System.out.print(i + ",");
    }

 }

}

class FastQuickSortStrategy implements SortStrategy {

public void sort(int[] input) {
    sort(input, 0, input.length-1);
    System.out.println("Fast sorting is done and the result is :");
    for (int i : input) {
        System.out.print(i + ",");
    }
}

private void sort(int[] input, int startIndx, int endIndx) {
    int endIndexOrig = endIndx;
    int startIndexOrig = startIndx;
    if( startIndx >= endIndx)
        return;
    int pavitVal = input[endIndx];
    while (startIndx <= endIndx) {
        while (input[startIndx] < pavitVal)
            startIndx++;
        while (input[endIndx] > pavitVal)
            endIndx--;
        if( startIndx <= endIndx){
            int tmp = input[startIndx];
            input[startIndx] = input[endIndx];
            input[endIndx] = tmp;
            startIndx++;
            endIndx--;
        }
    }
    sort(input, startIndexOrig, endIndx);
    sort(input, startIndx, endIndexOrig);
 }

}  

Bunun için test kodu

public class StrategyPattern {
  public static void main(String[] args) {
    Sorter sorter = new Sorter();
    int[] input = new int[] {7,1,23,22,22,11,0,21,1,2,334,45,6,11,2};
    System.out.print("Input is : ");
    for (int i : input) {
        System.out.print(i + ",");
    }
    System.out.println();
    sorter.sort(input, Speed.SLOW);
 }

}

Aynı örnek http://coder2design.com/strategy-pattern/


5
2017-07-08 11:38



Strateji kalıbının farklı kullanımları: Doğrulamalar: Kodunuzda pek çok doğrulama yapılması gerektiğinde. Farklı Algoritmalar: Özellikle farklı sıralama algoritmaları kullanılabildiğinde, örneğin kabarcık sıralaması veya hızlı sıralama. Bilgilerin Saklanması: Farklı yerlerde, örneğin veritabanı veya dosya sisteminde bilgi olabileceğimiz zaman. Ayrıştırma: ayrıştırma yaparken farklı girdiler için farklı stratejiler kullanabiliriz. Filtreleme Stratejileri. Yerleşim Stratejileri. - Jatinder Pal


Strateji kalıbına iyi bir örnek, farklı karakterlere sahip olabileceğimiz bir oyunda olacaktır ve her karakterin saldırı için birden fazla silahı olabilir, ancak bir seferde yalnızca bir silahı kullanabilir. Bu yüzden, içerik olarak karakterimiz var, örneğin, Kral, Komutan, Şövalye, Asker  ve saldırının () kullanılan silahlara bağlı olan yöntem / algoritma olabileceği bir strateji olarak silah. Yani eğer beton silah sınıfları Kılıç, Balta, Tatar yayı, BowAndArrow vs. ise hepsi saldırı () yöntemini uygulayacaklardır. Eminim daha fazla açıklama gerekli değildir.


3
2018-01-15 16:08



Kabul edilen cevabın bu örnek hakkında konuşması gerektiğini düşündüm :) - Jeancarlo Fontalvo