Penggunaan praktis dari template Strategi

Penggunaan template (atau pola) dalam pemrograman berorientasi objek berasal dari keinginan untuk membuat kode lebih sederhana, lebih dapat diandalkan, dan tidak untuk menemukan kembali roda, serta untuk secara efektif mengatur kerja bersama para programmer dengan berbagai tingkat pelatihan yang memberi mereka dasar tunggal untuk memahami kode sumber dalam kerangka kerja konsep logika bisnis. aplikasi. Ini berarti bahwa mempelajari pola desain adalah langkah kunci dalam pengembangan profesional seorang programmer.

Bagaimana cara mempelajari pola desain? Ada dua pendekatan: membosankan dan dapat dipahami (Anda suka klasifikasi saya?). Pendekatan yang membosankan melibatkan studi akademis dari daftar pola menggunakan contoh-contoh abstrak. Secara pribadi, saya lebih suka yang sebaliknya - pendekatan yang masuk akal, ketika menetapkan tugas pada tingkat formulasi yang relatif tinggi memungkinkan Anda untuk memilih pola desain. Meskipun Anda bisa menggabungkan kedua pendekatan tersebut.

Jadi ayo pergi?

Templat Strategi mengacu pada sekelompok templat perilaku.

Definisi Singkat Templat Strategi


Templat ini berfungsi untuk beralih di antara sekelompok algoritme saat suatu objek mengubah perilakunya berdasarkan perubahan dalam kondisi internalnya.

Contoh praktis penerapan templat Strategi


  • Penyortiran: kami ingin menyortir angka-angka ini, tetapi kami tidak tahu apakah kami akan menggunakan BrickSort, BubbleSort, atau penyortiran lainnya. Misalnya, Anda memiliki situs web tempat laman menampilkan elemen berdasarkan popularitas. Namun, banyak hal dapat menjadi "Populer" (sebagian besar tampilan, sebagian besar pelanggan, tanggal pembuatan, sebagian besar aktivitas, paling tidak komentar). Jika manajemen belum tahu persis bagaimana cara memesan, dan mungkin ingin bereksperimen dengan pesanan yang berbeda di kemudian hari, Anda membuat antarmuka (IOrderAlgorithm atau yang lainnya) dengan metode pemesanan dan memungkinkan objek Pemesan mendelegasikan urutan implementasi konkret dari antarmuka IOrderAlgorithm . Anda dapat membuat CommentOrderer, ActivityOrderer, dll., Dan matikan saja ketika persyaratan baru muncul.
  • Memproses antrian dari objek heterogen (pemrosesan antrian dan menyimpan data): Contohnya adalah sistem proxy yang mengakumulasi objek dari sumber data yang berbeda, kemudian setelah mengekstraksi objek dari antrian dan menyimpannya, ditentukan oleh strategi pemilihan berdasarkan pada sifat-sifat objek ini.
  • Validasi Kita perlu memeriksa elemen-elemen sesuai dengan "Some Rule", tetapi belum jelas apa aturan ini, dan kita bisa memikirkan yang baru.
  • Otentikasi: Pilih strategi otentikasi antara skema Basic, Digest, OpenID, OAuth.

Berikut ini sebuah contoh:

interface AuthStrategy {
    auth(): void;
}
class Auth0 implements AuthStrategy {
    auth() {
        log('Authenticating using Auth0 Strategy')
    }
}
class Basic implements AuthStrategy {
    auth() {
        log('Authenticating using Basic Strategy')
    }
}
class OpenID implements AuthStrategy {
    auth() {
        log('Authenticating using OpenID Strategy')
    }
}

class AuthProgram {
    private _strategy: AuthStrategy
    use(strategy: AuthStrategy) {
        this._strategy = strategy
        return this
    }
    authenticate() {
        if(this._strategy == null) {
            log("No Authentication Strategy set.")
        }
        this._strategy.auth()
    }
    route(path: string, strategy: AuthStrategy) {
        this._strategy = strategy
        this.authenticate()
        return this
    }
}

  • (games): — , , , , , , , . , , , , . «», «», «» Attack() . , «», «», «», « » Attack ().
  • (storing information): , , -. , PDF, , . , ; , , A, B C, . PDF , / PDF. , , , , , , B C, , A. , . PDF, , , . . Dependency Injection « / » ( , ), , , , , . , ( , ), , , , . « », «cleanUp» , , , , .
  • (outputting): X , CSV, XML, JSON .
  • (invoicing): - , , - .
  • (navigation): .
  • (logging): Log4Net Log4j , Appenders, Layouts, and Filters.
  • Enkripsi: untuk file kecil, Anda dapat menggunakan strategi dalam memori ketika seluruh file dibaca dan disimpan dalam memori (misalnya, untuk file <1 GB). Untuk file besar, Anda dapat menggunakan strategi berbeda di mana sebagian file dibaca dalam memori dan sebagian hasil terenkripsi disimpan dalam file tmp. Ini bisa menjadi dua strategi berbeda untuk tugas yang sama.

Berikut ini sebuah contoh:

//   ""
interface  Cipher  {
     public void performAction();
}

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

class SwaptToDiskCipher implements Cipher { 
         public void performAction() {
             //     .... 
         }

}

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

  • Editor grafis: misalnya, dalam aplikasi Windows Paint terdapat implementasi templat strategi di mana Anda dapat secara mandiri memilih bentuk dan warna di berbagai bagian. Di sini, bentuk dan warna adalah algoritma yang dapat diubah saat runtime.

Shape redCircle = new RedCircle(); //    «»
Shaped redCircle = new Shape("red","circle"); //   «»

SOLID dan implementasi templat Strategi


Apa masalah utama yang dipecahkan oleh templat "Strategi"? Bahkan, ini adalah pengganti kode datar JIKA .... BAHWA ... ... tentang implementasi objeknya.

Contoh kode flat kotor (salah):

class Document {...}
class Printer {
    print(doc: Document, printStyle: Number) {
        if(printStyle == 0 /*   */) {
            // ...
        }
        if(printStyle == 1 /*  */) {
            // ...            
        }
        if(printStyle == 2 /*     */) {
            // ...
        }
        if(printStyle == 3 /*     */) {
            // ...            
        }
        if(printStyle == 4 /*     */) {
            // ...
        }
        // ...
    }
}

Contoh kode yang sama dengan templat "Strategi" (dengan benar):

class Document {...}
interface PrintingStrategy {
    printStrategy(d: Document): void;
}
class ColorPrintingStrategy implements PrintingStrategy {
    printStrategy(doc: Document) {
        log(" ")
        // ...
    }
}
class InvertedColorPrintingStrategy implements PrintingStrategy {
    printStrategy(doc: Document) {
        log("  ")
        // ...
    }
}
class Printer {
    private printingStrategy: PrintingStrategy
    print(doc: Document) {
        this.printingStrategy.printStrategy(doc)
    }
}

Berikut adalah contoh lain dari implementasi yang benar dari templat Strategi berdasarkan SOLID.

//  /
interface LockOpenStrategy {
    open();
    lock();
}
//      
class RetinaScannerLockOpenStrategy implements LockOpenStrategy {
    open() {
        //...
    }
    lock() {
        //...
    }
}

//       
class KeypadLockOpenStrategy implements LockOpenStrategy {
    open() {
        if(password != ""){
            log("Entry Denied")
            return
        }
        //...
    }
    lock() {
        //...
    }
}
//        .
abstract class Door {
    public lockOpenStrategy: LockOpenStrategy
}
//   .
class GlassDoor extends Door {}
//    .
class MetalDoor extends Door {}
//       .
class DoorAdapter {
    openDoor(d: Door) {
        d.lockOpenStrategy.open()
    }
}

Di bawah ini adalah penyandian logika yang sebenarnya.

var glassDoor = new GlassDoor(); //   
glassDoor.lockOpenStrategy = new RetinaScannerLockOpenStrategy(); //         
var metalDoor = new MetalDoor(); //     
metalDoor.lockOpenStrategy = new KeypadLockOpenStrategy(); //      .
var door1 = new DoorAdapter().openDoor(glassDoor); //    . 
var door2  = new DoorAdapter().openDoor(metalDoor); //    . 

Seperti yang Anda lihat di atas, ini adalah kode berorientasi objek sepenuhnya yang mengecualikan gaya prosedural IF ... LAIN ....... atau SAKLAR ... KASUS ...

Ngomong-ngomong, mengapa kita menggunakan kelas adaptor? Pintu itu sendiri tidak akan terbuka, selalu terbuka dengan sesuatu di satu sisi, dan di sisi lain mungkin ada beberapa peristiwa sebelum pembukaan pintu atau setelah selesai dibuka, misalnya BeforeOpen () dan AfterOpen (), juga dapat dihubungkan dengan adaptor.

Template Refactoring dan Strategi


Templat "Strategi" harus digunakan ketika Anda mulai memperhatikan algoritma berulang, tetapi dalam variasi yang berbeda. Dengan demikian, perlu untuk membagi algoritma ke dalam kelas dan mengisinya sesuai keperluan dalam program Anda.

Lebih lanjut, jika Anda melihat pernyataan bersyarat duplikat di sekitar algoritma saudara.
Ketika sebagian besar kelas memiliki perilaku yang terkait. Dan kemudian Anda harus memilihnya dan memindahkannya ke kelas yang terpisah.

Saya harap pilihan contoh ini membantu Anda menggunakan templat "Strategi" dengan tepat.
Saya akan senang jika Anda dapat memberikan lebih banyak contoh template ini di komentar.

Selamat coding, teman dan kolega!

Source: https://habr.com/ru/post/undefined/


All Articles