Contoh Pola Strategi Dunia Nyata

95

Saya telah membaca tentang prinsipal OCP dan bagaimana menggunakan pola strategi untuk mencapai hal ini.

Saya akan mencoba dan menjelaskan hal ini kepada beberapa orang, tetapi satu-satunya contoh yang dapat saya pikirkan adalah menggunakan kelas validasi yang berbeda berdasarkan pada status "pesanan".

Saya telah membaca beberapa artikel online, tetapi ini biasanya tidak menggambarkan alasan yang nyata untuk menggunakan strategi, seperti menghasilkan laporan / tagihan / validasi dll ...

Apakah ada contoh dunia nyata yang menurut Anda pola strategi biasa?

Ravindra babu
sumber

Jawaban:

100

Bagaimana dengan ini:

Anda harus mengenkripsi file.

Untuk file kecil, Anda dapat menggunakan strategi "dalam memori", di mana file lengkap dibaca dan disimpan di memori (katakanlah untuk file <1 gb)

Untuk file besar, Anda dapat menggunakan strategi lain, di mana bagian file dibaca dalam memori dan hasil terenkripsi sebagian disimpan dalam file tmp.

Ini mungkin dua strategi berbeda untuk tugas yang sama.

Kode klien akan terlihat sama:

 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.
         }

}

Itu

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

Akan mengembalikan contoh strategi yang benar untuk sandi tersebut.

Saya harap ini membantu.

(Saya bahkan tidak tahu apakah Cipher adalah kata yang tepat: P)

OscarRyz
sumber
8
Apakah teladan Anda tidak lebih merupakan Pola Pabrik? Juga saya pikir itu tidak akan berhasil di C # misalnya. Metode "getCipher ()" Anda adalah metode statis tetapi di C # Anda tidak dapat menentukan metode statis pada antarmuka (baik di Java, saya pikir, tetapi untuk ini saya tidak yakin).
FrenchData
10
Mereka pergi bersama. Pabrik membuat strategi, tetapi strategi itu sendiri memegang algoritme untuk melakukan (pada dasarnya) operasi yang sama. Strategi ini juga dapat diubah saat runtime. Tentang metode pabrik Anda benar, saya telah mengubahnya.
OscarRyz
Untuk menambahkan titik Osacars, tanpa pabrik ini dapat dibuat tanpa pabrik Cipher C =null; if (file.size() <= 2048) { C = new InMemoryCipherStrategy(); } else { c= SwaptToDiskCipher (); }
Abhijit Mazumder
Setuju dengan @FrenchData. Meskipun menjadi contoh yang bagus, kehadiran CipherFactorymungkin membingungkan mereka yang tidak terbiasa dengan pola Strategi.
pengguna487772
1
Pola pabrik adalah tentang kreasi, Strategi adalah tentang Perilaku. Ada yang sedikit berbeda kan?
nhoxbypass
62

Sekali lagi, posting lama tetapi masih muncul di pencarian jadi saya akan menambahkan dua contoh lagi (Kode ada di C #). Saya benar-benar menyukai pola Strategi karena telah menghemat banyak waktu saya ketika manajer proyek mengatakan: "Kami ingin aplikasi melakukan 'X', tetapi 'X' belum jelas dan dapat berubah dalam waktu dekat. " Video ini menjelaskan pola strategi , menggunakan StarCraft sebagai contoh.

Barang-barang yang termasuk dalam kategori ini:

  • Penyortiran: Kami ingin menyortir nomor ini, tetapi kami tidak tahu apakah kami akan menggunakan BrickSort, BubbleSort, atau penyortiran lainnya

  • Validasi: Kami perlu memeriksa item sesuai dengan "Beberapa aturan", tetapi belum jelas aturan apa itu nantinya, dan kami mungkin memikirkan yang baru.

  • Permainan: Kami ingin pemain berjalan atau berlari saat dia bergerak, tapi mungkin di masa depan, dia juga harus bisa berenang, terbang, teleportasi, menggali di bawah tanah, dll.

  • Menyimpan informasi: Kami ingin aplikasi menyimpan informasi ke Database, tetapi nanti mungkin perlu untuk menyimpan file, atau membuat panggilan web

  • Keluaran: Kita perlu mengeluarkan X sebagai string biasa, tapi nanti mungkin CSV, XML, JSON, dll.


Contoh

Saya memiliki proyek di mana pengguna dapat menetapkan produk ke orang di database. Penetapan produk kepada seseorang ini memiliki status "Disetujui" atau "Ditolak", yang bergantung pada beberapa aturan bisnis. Misalnya: jika pengguna memberikan produk kepada seseorang dengan usia tertentu, statusnya harus ditolak; Jika perbedaan antara dua bidang dalam item lebih besar dari 50, statusnya ditolak, dll.

Sekarang, pada saat perkembangan aturan bisnis ini belum sepenuhnya jelas, dan aturan baru dapat muncul kapan saja. Kekuatan dari stragety-pattern adalah saya membuat RuleAgent, yang diberi daftar IRules.

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

Pada saat menugaskan produk ke seseorang, saya membuat RuleAgent, memberinya daftar aturan (yang semuanya menerapkan IRule), dan memintanya untuk memvalidasi tugas. Ini akan berjalan melalui semua aturannya. Yang mana, karena mereka semua mengimplementasikan antarmuka yang sama, semua memiliki IsApprovedmetode dan mengembalikan false jika ada yang mengembalikan false.

Sekarang ketika misalnya manajer tiba-tiba muncul dan berkata, kami juga perlu menolak semua tugas untuk magang, atau semua tugas untuk orang yang bekerja lembur ... Anda membuat kelas baru seperti ini:

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;
    }
}

Anda melihat bahwa Anda tidak perlu terus menambahkan atau menghapus if-statement atau code, cukup buat kelas aturan baru yang mengimplementasikan antarmuka IRUle dan ganti jika diperlukan.


Contoh bagus lainnya: serial video Scott Allen di http://www.asp.net/mvc/pluralsight mana dia menggunakan pola strategi di bagian Uji-unit aplikasi

Ia membangun situs web yang memiliki halaman yang menampilkan item berdasarkan popularitas. Namun, "Populer" bisa berarti banyak hal (sebagian besar penayangan, sebagian besar pelanggan, tanggal pembuatan, aktivitas terbanyak, jumlah komentar paling sedikit, dll.), Dan jika manajemen belum tahu persis bagaimana cara memesan, dan mungkin ingin bereksperimen dengan yang berbeda memesan di kemudian hari. Anda membuat antarmuka (IOrderAlgorithm atau sesuatu) dengan metode pemesanan, dan biarkan objek Orderer mendelegasikan pengurutan untuk implementasi konkret dari antarmuka IOrderAlgorithm. Anda dapat membuat "CommentOrderer", "ActivityOrderer", dll ... Dan cukup ganti ini ketika persyaratan baru muncul.

Céryl Wiltink
sumber
Saya tahu ini sedikit di luar cakupan pertanyaan, tetapi apa yang terjadi selanjutnya? Kami memiliki ini InternRulesekarang tetapi bagaimana kami memicu OvertimeRule? Bagaimana kita memastikan bahwa logika apa pun yang dipanggil OvertimeRule.IsApprovedsekarang juga memanggil InternRule.IsApproved?
Spencer Ruport
14

Catatan kunci:

  1. Strategi adalah pola desain perilaku. Ini digunakan untuk beralih di antara keluarga algoritme.

  2. Pola ini berisi satu antarmuka strategi abstrak dan banyak implementasi strategi konkret ( algoritme ) dari antarmuka itu.

  3. Aplikasi hanya menggunakan antarmuka strategi . Bergantung pada beberapa parameter konfigurasi, strategi konkret akan diberi tag ke antarmuka .

Diagram UML dari wikipedia

masukkan deskripsi gambar di sini

Satu contoh nyata: Maskapai yang menawarkan diskon selama beberapa bulan (Juli-Desember) . Anda dapat memiliki satu modul Tarif , yang menentukan opsi harga tergantung pada nomor bulan.

Lihat contoh sederhana. Contoh ini dapat diperluas ke aplikasi ritel online, yang memberikan diskon untuk item keranjang belanja pada hari-hari khusus / happy hour dengan mudah.

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);
    }

}

keluaran:

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

Artikel yang berguna:

pola strategi oleh dzone

pola strategi dengan pembuatan sumber

Ravindra babu
sumber
terima kasih .... masuk akal .... setuju applyStrategy () adalah monster untuk mencapai banyak ilmu hitam. Juga cara non-statis dalam menahan strategi dalam strategyContext adalah yang terbaik
Arnab Dutta
12

Saya dapat memikirkan beberapa contoh yang cukup sederhana:

  • Menyortir daftar. Strategi adalah perbandingan yang digunakan untuk memutuskan mana dari dua item dalam daftar yang "Pertama"
  • Anda mungkin memiliki aplikasi di mana algoritme pengurutan itu sendiri (QuickSort, HeapSort, dll.) Dapat dipilih saat runtime
  • Penambah, Tata Letak, dan Filter di Log4Net dan Log4j
  • Manajer Tata Letak di toolkit UI
  • Kompresi data. Anda mungkin memiliki antarmuka ICompressor yang satu-satunya metode terlihat seperti ini:

    byte [] kompres (input byte []);

    Kelas kompresi konkret Anda mungkin seperti RunLengthCompression, DeflateCompression, dll.

Eric Pohl
sumber
9

Salah satu penggunaan umum dari pola strategi adalah untuk menentukan strategi penyortiran kustom (dalam bahasa tanpa fungsi tingkat tinggi), misalnya untuk mengurutkan daftar string berdasarkan panjangnya di Java, meneruskan kelas dalam anonim (implementasi antarmuka strategi):

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);

Dengan cara yang sama, strategi dapat digunakan untuk kueri asli dengan database objek, misalnya di db4o:

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

Saya memiliki aplikasi yang menyinkronkan basis penggunanya setiap hari dengan direktori perusahaan kami. Pengguna memenuhi syarat atau tidak memenuhi syarat berdasarkan status mereka di Universitas. Setiap hari program penyediaan berjalan dan memastikan bahwa mereka yang seharusnya memenuhi syarat disediakan dalam aplikasi dan mereka yang tidak dicabut (sebenarnya sesuai dengan algoritma degradasi yang anggun, tapi itu bukan intinya). Pada hari Sabtu saya melakukan pembaruan yang lebih menyeluruh yang menyinkronkan beberapa properti dari setiap pengguna serta memastikan bahwa mereka memiliki kelayakan yang sesuai. Di akhir bulan saya melakukan beberapa pemrosesan tagihan kembali berdasarkan penggunaan untuk bulan itu.

Saya menggunakan pola strategi yang dapat disusun untuk melakukan sinkronisasi ini. Program utama pada dasarnya memilih strategi master tergantung pada hari dalam seminggu (hanya sinkronkan perubahan / sinkronkan semua) dan waktu semester relatif terhadap kalender akademik. Jika siklus penagihan berakhir, maka itu juga menyusunnya dengan strategi penagihan. Kemudian menjalankan strategi yang dipilih melalui antarmuka standar.

Saya tidak tahu seberapa umum hal ini, tetapi saya merasa ini sangat cocok untuk pola strategi.

tvanfosson.dll
sumber
Ini adalah contoh yang sangat bagus. Juga, ini dengan jelas memberitahu Anda perbedaan antara pola perintah dan strategi secara singkat - maksudnya. "Program utama pada dasarnya memilih strategi utama tergantung pada hari dalam seminggu"
Utsav T
7

Saya tahu ini adalah pertanyaan lama, tapi saya rasa saya memiliki contoh menarik lain yang saya terapkan baru-baru ini.

Ini adalah contoh yang sangat praktis dari pola strategi yang digunakan dalam sistem pengiriman dokumen.

Saya memiliki sistem pengiriman PDF yang menerima arsip yang berisi banyak dokumen dan beberapa metadata. Berdasarkan metadata, diputuskan di mana harus meletakkan dokumen; katakanlah, tergantung pada data, saya bisa menyimpan dokumen dalam A, BatauC sistem penyimpanan, atau campuran dari tiga.

Pelanggan yang berbeda menggunakan sistem ini, dan mereka memiliki persyaratan penanganan rollback / error yang berbeda jika terjadi kesalahan: seseorang ingin sistem pengiriman berhenti pada kesalahan pertama, membiarkan semua dokumen yang sudah terkirim di penyimpanan mereka, tetapi menghentikan proses dan tidak mengirimkan yang lain ; yang lain ingin mengembalikannya Bjika terjadi kesalahan saat menyimpan C, tetapi biarkan apa pun yang telah dikirim ke A. Mudah untuk membayangkan bahwa yang ketiga atau keempat juga memiliki kebutuhan yang berbeda.

Untuk mengatasi masalah ini, saya telah membuat kelas pengiriman dasar yang berisi logika pengiriman, ditambah metode untuk mengembalikan barang dari semua penyimpanan. Metode tersebut sebenarnya tidak dipanggil oleh sistem pengiriman secara langsung jika terjadi kesalahan. Sebaliknya, kelas tersebut menggunakan Injeksi Ketergantungan untuk menerima kelas "Strategi Penanganan Rollback / Error" (berdasarkan pelanggan yang menggunakan sistem), yang dipanggil jika terjadi kesalahan, yang pada gilirannya akan memanggil metode rollback jika sesuai untuk strategi itu.

Kelas pengiriman itu sendiri melaporkan apa yang terjadi pada kelas strategi (dokumen apa yang dikirim ke penyimpanan apa, dan kegagalan apa yang terjadi), dan setiap kali terjadi kesalahan, ia menanyakan strategi apakah akan melanjutkan atau tidak. Jika strategi mengatakan "hentikan", kelas akan memanggil metode "pembersihan" strategi, yang menggunakan informasi yang dilaporkan sebelumnya untuk memutuskan metode rollback mana yang akan dipanggil dari kelas pengiriman, atau tidak melakukan apa pun.

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

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

Jadi saya sekarang memiliki dua strategi berbeda: satu adalah QuitterStrategy(yang berhenti pada kesalahan pertama dan tidak membersihkan apa-apa) dan yang lainnya adalah MaximizeDeliveryToAStrategy(yang berusaha semaksimal mungkin untuk tidak membatalkan proses dan tidak pernah mengembalikan barang yang dikirim ke penyimpanan A, tetapi rollback barang dari Bjika pengiriman Cgagal).

Dari pemahaman saya, inilah salah satu contoh pola strategi. Jika Anda (ya, Anda membaca) merasa saya salah, beri komentar di bawah dan beri tahu saya. Saya ingin tahu tentang apa yang merupakan penggunaan pola strategi yang "murni", dan aspek penerapan apa yang melanggar definisi tersebut. Saya rasa ini terlihat agak lucu karena antarmuka strateginya agak gemuk. Semua contoh yang saya lihat sejauh ini hanya menggunakan satu metode, tetapi saya masih berpikir ini merangkum algoritma (jika sepotong logika bisnis dapat dianggap sebagai algoritma, yang menurut saya memang demikian).

Karena strategi juga diberitahukan tentang peristiwa selama pelaksanaan pengiriman, itu juga dapat dianggap sebagai Pengamat , tapi itu cerita lain.

Dari melakukan sedikit riset, sepertinya ini adalah "pola komposit" (seperti MVC, pola yang menggunakan beberapa pola desain di bawahnya dengan cara tertentu) yang disebut Advisor . Ini adalah penasihat tentang apakah pengiriman harus dilanjutkan atau tidak, tetapi ini juga merupakan penangan kesalahan aktif karena dapat mengembalikan barang ketika diminta.

Bagaimanapun, ini adalah contoh yang cukup kompleks yang mungkin membuat perasaan Anda bahwa penggunaan pola strategi terlalu sederhana / konyol. Ini bisa sangat kompleks dan bahkan lebih dapat diterapkan bila digunakan bersama dengan pola lain.

Gui Prá
sumber
6

Pola strategi adalah pola yang paling umum digunakan khusus untuk validasi dan algoritma pengurutan.

Izinkan saya menjelaskan dengan contoh praktis sederhana

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);
 }

}  

Kode tes untuk ini adalah

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);
 }

}

Contoh yang sama diambil dari http://coder2design.com/strategy-pattern/

Jatinder Pal
sumber
Penggunaan yang berbeda dari pola strategi: Validasi: Ketika ada banyak validasi yang perlu dilakukan dalam kode Anda. Algoritme Berbeda: Khususnya saat algoritme pengurutan yang berbeda dapat digunakan, misalnya pengurutan gelembung atau pengurutan cepat. Menyimpan Informasi: Ketika kita mungkin mendapatkan informasi di tempat yang berbeda, misalnya database atau sistem file. Parsing: saat mem-parsing kita dapat menggunakan strategi yang berbeda untuk input yang berbeda. Strategi Penyaringan. Strategi Tata Letak.
Jatinder Pal
5

Contoh pola strategi yang baik adalah dalam permainan di mana kita dapat memiliki karakter yang berbeda dan setiap karakter dapat memiliki banyak senjata untuk diserang tetapi dalam satu waktu hanya dapat menggunakan satu senjata. Jadi kita memiliki karakter sebagai konteksnya, misalnya Raja, Komandan, Ksatria, Prajurit dan senjata sebagai strategi di mana serangan () bisa menjadi metode / algoritma yang bergantung pada senjata yang digunakan. Jadi jika kelas senjata beton adalah Sword, Axe, Crossbow, BowAndArrow dll .. mereka semua akan menerapkan metode attack (). Saya yakin penjelasan lebih lanjut tidak diperlukan.

Sandipan Karmakar
sumber
1
Saya pikir jawaban yang diterima seharusnya berbicara tentang contoh ini :)
Jeancarlo Fontalvo
2

Saya menggunakan pendekatan strategi di mesin yang cukup kompleks dalam aplikasi yang merupakan contoh yang baik. Pada dasarnya peran mesin adalah pergi dan pertama-tama menemukan daftar orang yang memiliki widget, peran kedua adalah untuk mencari tahu 10 orang terbaik dengan widget berdasarkan jumlah parameter yang tidak diketahui (hal-hal seperti jarak harga bisnis sebelumnya bersama-sama , jumlah stok, opsi pengiriman, dll dll ...)

Pada dasarnya apa yang kami lakukan adalah kami memecahkan masalah menjadi dua strategi yang pertama adalah pengambilan data, karena kami tahu bahwa kami memiliki banyak sumber widget dan kami harus bisa mendapatkan data dan mengubahnya menjadi struktur umum.

Kami kemudian juga menyadari bahwa kami memiliki beberapa algoritme beberapa didasarkan pada pembobotan parameter, yang lain sangat aneh dan menguntungkan dan saya tidak dapat melakukannya dengan adil tanpa mengeluarkan visios dan bagan dan Anda mendapatkan gambarannya, kami memiliki banyak algoritme untuk memilih orang terbaik.

Layanan kami sendiri pada dasarnya mendefinisikan input, output dan melakukan beberapa normalisasi data, itu juga menggunakan pola penyedia untuk plug-in penyedia data spesifik aplikasi dan penyedia algoritma yang menggunakan strategi tersebut. Ini adalah sistem yang cukup efektif.

Kami mengalami beberapa perdebatan jika kami menggunakan strategi atau pola template yang tidak pernah kami selesaikan.

JoshBerke
sumber
2

Apakah Anda yakin bahwa status "pesanan" bukanlah pola Negara Bagian? Saya memiliki firasat bahwa pesanan tidak akan ditangani secara berbeda tergantung pada statusnya.

Ambil contoh metode Kirim pada Pesanan:

order.Ship();
  • Jika metode pengiriman bervariasi dalam fungsi statusnya, maka Anda memiliki pola strategi.
  • Namun, jika metode Ship () berhasil hanya ketika pesanan telah dibayar, dan pesanan belum dikirim, Anda memiliki pola status.

Contoh terbaik dari pola keadaan (dan pola lainnya) yang saya temukan ada di buku " Pola Desain Kepala Pertama ", yang luar biasa. Yang kedua adalah rangkaian pola blog David Cumps .

grootjans
sumber
2

Misalkan Anda ingin menulis algoritme untuk menghitung hari ke-X pada bulan dan tahun tertentu, misalnya, Senin kedua bulan Oktober 2014. Anda ingin menggunakan kelas Waktu Android android.text.format.Timeuntuk merepresentasikan tanggal, tetapi Anda juga ingin menulis algoritme umum yang juga dapat diterapkan ke java.util.Calendar.

Inilah yang saya lakukan.

Di DatetimeMath.java:

public interface DatetimeMath { 
    public Object createDatetime(int year, int month, int day);

    public int getDayOfWeek(Object datetime);

    public void increment(Object datetime);
}

Di TimeMath.java:

public class TimeMath implements DatetimeMath {
    @Override
    public Object createDatetime(int year, int month, int day) {
        Time t = new Time();
        t.set(day, month, year);
        t.normalize(false);
        return t;
    }

    @Override
    public int getDayOfWeek(Object o) {
        Time t = (Time)o;
        return t.weekDay;
    }   

    @Override
    public void increment(Object o) {
        Time t = (Time)o;
        t.set(t.monthDay + 1, t.month, t.year);
        t.normalize(false);
    }
}

Di OrdinalDayOfWeekCalculator.java, kelas dengan algoritme umum:

public class OrdinalDayOfWeekCalculator {   
    private DatetimeMath datetimeMath;

    public OrdinalDayOfWeekCalculator(DatetimeMath m) {
        datetimeMath = m;
    }

    public Object getDate(int year, int month, int dayOfWeek, int ordinal) {
        Object datetime = datetimeMath.createDatetime(year, month, 1);
        if (datetimeMath.getDayOfWeek(datetime) == dayOfWeek) {
            return datetime;
        } 
        int xDayCount = 0;
        while (xDayCount != ordinal) {
            datetimeMath.increment(datetime);
            if (datetimeMath.getDayOfWeek(datetime) == dayOfWeek) {
                xDayCount++;
            }
        }
        return datetime;
    }
}

Di aplikasi Android saya, saya akan memanggil sesuatu seperti

OrdinalDayOfWeekCalculator odowc = 
        new OrdinalDayOfWeekCalculator(new TimeMath());
Time canadianThanksgiving = (Time)odowc.getDate(
        year, Calendar.OCTOBER, Time.MONDAY, 2);

Jika saya ingin menggunakan kembali algoritme yang sama java.util.Calendar, saya hanya akan menulis kelas CalendarMath yang mengimplementasikan tiga metode di DatetimeMath dan kemudian menggunakan

OrdinalDayOfWeekCalculator odowc2 = 
        new OrdinalDayOfWeekCalculator(new CalendarMath());
Calendar canadianThanksgivingCal = (Calendar)odowc2.getDate(
        year, Calendar.OCTOBER, Calendar.MONDAY, 2);
anomal
sumber
2
public class StrategyDemo {
    public static void main(String[] args) {
        ShoppingCart cart = new ShoppingCart();

        Item item1 = new Item("1234", 10);
        Item item2 = new Item("5678", 40);

        cart.addItem(item1);
        cart.addItem(item2);

        // pay by paypal
        cart.pay(new PaypalStrategy("[email protected]", "mypwd"));

        // pay by credit card
        cart.pay(new CreditCardStrategy("Pankaj Kumar", "1234567890123456", "786", "12/15"));
    }
}

interface PaymentStrategy {
    public void pay(int amount);
}

class CreditCardStrategy implements PaymentStrategy {

    private String name;
    private String cardNumber;
    private String cvv;
    private String dateOfExpiry;

    public CreditCardStrategy(String nm, String ccNum, String cvv, String expiryDate) {
        this.name = nm;
        this.cardNumber = ccNum;
        this.cvv = cvv;
        this.dateOfExpiry = expiryDate;
    }

    @Override
    public void pay(int amount) {
        System.out.println(amount + " paid with credit/debit card");
    }

}

class PaypalStrategy implements PaymentStrategy {

    private String emailId;
    private String password;

    public PaypalStrategy(String email, String pwd) {
        this.emailId = email;
        this.password = pwd;
    }

    @Override
    public void pay(int amount) {
        System.out.println(amount + " paid using Paypal.");
    }

}

class Item {

    private String upcCode;
    private int price;

    public Item(String upc, int cost) {
        this.upcCode = upc;
        this.price = cost;
    }

    public String getUpcCode() {
        return upcCode;
    }

    public int getPrice() {
        return price;
    }

}

class ShoppingCart {

    // List of items
    List<Item> items;

    public ShoppingCart() {
        this.items = new ArrayList<Item>();
    }

    public void addItem(Item item) {
        this.items.add(item);
    }

    public void removeItem(Item item) {
        this.items.remove(item);
    }

    public int calculateTotal() {
        int sum = 0;
        for (Item item : items) {
            sum += item.getPrice();
        }
        return sum;
    }

    public void pay(PaymentStrategy paymentMethod) {
        int amount = calculateTotal();
        paymentMethod.pay(amount);
    }
}
Vivek Goel
sumber
1

Beberapa minggu yang lalu, saya menambahkan antarmuka Java umum yang diimplementasikan oleh salah satu objek domain kami. Objek domain ini dimuat dari database, dan representasi database adalah skema bintang dengan sekitar 10+ cabang. Salah satu konsekuensi dari memiliki objek domain yang sangat berat adalah kami harus membuat objek domain lain yang mewakili skema yang sama, meskipun bobotnya lebih ringan. Jadi saya membuat objek ringan lainnya menerapkan antarmuka yang sama. Jika tidak, kami memiliki:

public interface CollectibleElephant { 
    long getId();
    String getName();
    long getTagId();
}

public class Elephant implements CollectibleElephant { ... }
public class BabyElephant implements CollectibleElephant { ... }

Awalnya, saya ingin menggunakan CollectibleElephantuntuk mengurutkan Elephants. Cukup cepat, rekan satu tim saya CollectibleElephantdengan senang hati menjalankan pemeriksaan keamanan, memfilter mereka saat dikirim ke GUI, dll.

Alan
sumber
1

Kami harus membuat antarmuka penyediaan pihak ketiga untuk platform perusahaan dengan database yang sangat rumit. Pengiriman data yang akan disediakan adalah sebagai daftar tipe data kami yang dimasukkan ke dalam antrian prioritas dalam aplikasi kami sehingga dapat ditulis ke database dalam urutan yang benar karena ketergantungan.

Proses untuk menulis data tersebut kemudian cukup sederhana, tetap muncul di atas antrian prioritas dan kemudian pilih strategi berdasarkan jenis objek yang Anda ekstrak.

Kurang ajar
sumber
0

Dari wikipedia

Dalam pemrograman komputer, pola strategi (juga dikenal sebagai pola kebijakan) adalah pola desain perangkat lunak perilaku yang memungkinkan pemilihan algoritma saat runtime. Alih-alih menerapkan satu algoritme secara langsung, kode menerima instruksi run-time seperti yang akan digunakan dalam keluarga algoritme

Dalam aplikasi Windows Paint Anda dapat melihat pola strategi di mana Anda dapat memilih bentuk dan warna secara terpisah di bagian yang berbeda. Di sini bentuk dan warna adalah algoritma yang dapat diubah saat runtime.

Jika Anda ingin menggambar lingkaran dengan warna merah, daripada memberikan pilihan 'RedCircle' mereka membiarkan Anda memilih lingkaran dan warna pilihan Anda.

Shape redCircle = new RedCircle(); // Without stretegy Pattern
Shaped redCircle = new Shape("red","circle"); // With Strategy pattern

Tanpa pola strategi akan menambah jumlah kelas dengan produk Cartesian berupa bentuk dan warna. Juga antarmuka berubah untuk setiap implementasi.

bharanitharan
sumber
0

Bayangkan game penembak dengan musuh AI misalnya. Anda ingin mereka terus berjuang dengan cara yang berbeda berdasarkan apa yang terjadi .. Dengan pola strategi, Anda dapat terus berputar dan secara dinamis mengubah cara suatu tindakan atau tindakan akan dilakukan.

interface FightingStategy{
    public void fight();
}
public Defense implements FightingStrategy{
    public void figth(){
        ... hide behind wall to shoot
    }
}
public Berserker implements FightingStrategy{
    public void fight(){
        ... run towards you, headrolls and shoots
    }
}
public Dead implements FightingStrategy{
    public void fight(){
        ... is dead, doesn't move
    }
}

public AiShooter{

    FightingStrategy fightingStrategy;

    public AiShooter(){
        fightStrategy = new Berserker();
    }

    public void fight(){
        this.fightingStrategy.fight();
    }

    public void changeStrategy(FightingStrategy f){
        this.fightingStrategy = f;
    }
}

public static void main(){

    ... create list of AiShooters...
    while (condition){
        list.forEach(shooter -> shooter.fight());
    }
    ... you shoot back
    list.ForEach(shooter -> shooter.changeStrategy(new 
Defense()));

    ... you kill one
    list.get(n).changeStrategy(new Dead());
}
Cédric S
sumber