CodeGym /Blog Jawa /Acak /Pola Desain Strategi
John Squirrels
tingkat
San Francisco

Pola Desain Strategi

Diterbitake ing grup
Hi! Ing wulangan dina iki, kita bakal ngomong babagan pola Strategi. Ing wulangan sadurunge, kita wis ngerti babagan konsep warisan. Yen sampeyan lali, aku bakal ngelingake yen istilah iki nuduhake solusi standar kanggo tugas pemrograman umum. Ing CodeGym, kita asring ujar manawa sampeyan bisa google jawaban kanggo meh kabeh pitakonan. Iki amarga tugas sampeyan, apa wae, mesthine wis kasil dirampungake dening wong liya. Pola minangka solusi sing dicoba lan bener kanggo tugas sing paling umum, utawa cara kanggo ngrampungake kahanan sing bermasalah. Iki kaya "gembong" sing ora perlu maneh invent ing dhewe, nanging sampeyan kudu ngerti carane lan nalika nggunakake :) Tujuan liyane kanggo pola punika ningkataké arsitektur seragam. Maca kode wong liya dudu tugas sing gampang! Saben wong nulis kode sing beda-beda, amarga tugas sing padha bisa ditanggulangi kanthi pirang-pirang cara. Nanging nggunakake pola mbantu programer beda ngerti logika pemrograman tanpa delving menyang saben baris kode (sanajan nalika ndeleng iku kanggo pisanan!) Dina iki kita katon ing salah siji saka pola desain paling umum disebut "Strategi". Pola desain: Strategi - 2Bayangake yen kita lagi nulis program sing bakal aktif nggarap obyek Conveyance. Ora masalah apa persis program kita. Kita wis nggawe hirarki kelas kanthi siji kelas induk Conveyance lan telung kelas anak: Sedan , Truk lan F1Car .

public class Conveyance {

   public void go() {
       System.out.println("Moving forward");
   }

   public void stop() {

       System.out.println("Braking!");
   }
}

public class Sedan extends Conveyance {
}

public class Truck extends Conveyance {
}

public class F1Car extends Conveyance {
}
Kabeh telung kelas anak marisi rong cara standar saka wong tuwa: go () lan mandeg () . Program kita gampang banget: mobil kita mung bisa maju lan ngetrapake rem. Nerusake karya, kita mutusaké kanggo menehi mobil cara anyar: isi () (tegese, "isi tank bensin"). Kita ditambahake menyang kelas induk Conveyance :

public class Conveyance {

   public void go() {
       System.out.println("Moving forward");
   }

   public void stop() {

       System.out.println("Braking!");
   }
  
   public void fill() {
       System.out.println("Refueling!");
   }
}
Apa masalah bisa muncul ing kahanan sing prasaja? Nyatane, dheweke wis duwe ... Pola desain: Strategi - 3

public class Stroller extends Conveyance {

   public void fill() {
      
       // Hmm... This is a stroller for children. It doesn't need to be refueled :/
   }
}
Program kita saiki duwe conveyance (kereta bayi) sing ora cocog karo konsep umum. Bisa uga ana pedal utawa dikontrol radio, nanging siji bab sing mesthi - ora bakal ana papan kanggo ngedhunake gas. Hierarki kelas kita nyebabake cara umum diwarisake dening kelas sing ora mbutuhake. Apa sing kudu kita lakoni ing kahanan iki? Inggih, kita bisa ngalahake cara isi () ing kelas Stroller supaya ora ana apa-apa nalika sampeyan nyoba ngisi bahan bakar kereta dorong:

public class Stroller extends Conveyance {

   @Override
   public void fill() {
       System.out.println("A stroller cannot be refueled!");
   }
}
Nanging iki meh ora bisa diarani solusi sing sukses yen ora ana alesan liyane tinimbang kode duplikat. Contone, umume kelas bakal nggunakake metode kelas induk, nanging liyane bakal dipeksa ngilangi. Yen kita duwe 15 kelas lan kita kudu ngalahake prilaku ing 5-6 mau, duplikasi kode bakal dadi cukup ekstensif. Mungkin antarmuka bisa mbantu kita? Contone, kaya iki:

public interface Fillable {
  
   public void fill();
}
Kita bakal nggawe antarmuka Isi kanthi cara siji isi () . Banjur, conveyances sing kudu ngisi bahan bakar bakal ngleksanakake antarmuka iki, nalika conveyances liyane (contone, kereto bayi kita) ora bakal. Nanging pilihan iki ora cocog karo kita. Ing mangsa ngarep, hierarki kelas kita bisa dadi gedhe banget (bayangake pira macem-macem jinis conveyances ing donya). We nilar versi sadurungé nglibatno pusaka, amarga kita ora pengin ngganti isi ()metode kaping pirang-pirang. Saiki kita kudu ngetrapake ing saben kelas! Lan yen kita duwe 50? Lan yen owah-owahan sing kerep ditindakake ing program kita (lan iki meh mesthi bener kanggo program nyata!), Kita kudu cepet-cepet ngliwati kabeh 50 kelas lan kanthi manual ngganti prilaku saben wong. Dadi, apa sing kudu ditindakake ing kahanan iki? Kanggo ngatasi masalah kita, kita bakal milih cara sing beda. Yaiku, kita bakal misahake prilaku kelas kita saka kelas dhewe. Apa tegese? Kaya sing sampeyan ngerteni, saben obyek duwe negara (sakumpulan data) lan prilaku (sawijine metode). Prilaku kelas conveyance kita kasusun saka telung cara: go() , stop() lan fill() . Rong cara sing sepisanan apik banget. Nanging kita bakal mindhah cara katelu metu sakaKelas transportasi . Iki bakal misahake prilaku saka kelas (luwih akurat, bakal misahake mung bagean saka prilaku, wiwit loro cara pisanan bakal tetep ing ngendi). Dadi ing ngendi kita kudu nyelehake metode fill() ? Ora ana sing kepikiran :/ Kayane pancen kudune. Kita bakal pindhah menyang antarmuka sing kapisah: FillStrategy !

public interface FillStrategy {

   public void fill();
}
Apa kita kudu antarmuka kuwi? Kabeh iku langsung. Saiki kita bisa nggawe sawetara kelas sing ngleksanakake antarmuka iki:

public class HybridFillStrategy implements FillStrategy {
  
   @Override
   public void fill() {
       System.out.println("Refuel with gas or electricity — your choice!");
   }
}

public class F1PitstopStrategy implements FillStrategy {
  
   @Override
   public void fill() {
       System.out.println("Refuel with gas only after all other pit stop procedures are complete!");
   }
}

public class StandardFillStrategy implements FillStrategy {
   @Override
   public void fill() {
       System.out.println("Just refuel with gas!");
   }
}
Kita nggawe telung strategi prilaku: siji kanggo mobil biasa, siji kanggo hibrida, lan siji kanggo mobil balap Formula 1. Saben strategi ngetrapake algoritma pengisian bahan bakar sing beda. Ing kasus kita, kita mung nampilake senar ing console, nanging saben cara bisa ngemot sawetara logika rumit. Apa sing kudu kita tindakake sabanjure?

public class Conveyance {

   FillStrategy fillStrategy;

   public void fill() {
       fillStrategy.fill();
   }

   public void go() {
       System.out.println("Moving forward");
   }

   public void stop() {
       System.out.println("Braking!");
   }
  
}
Kita nggunakake antarmuka FillStrategy minangka lapangan ing kelas induk Conveyance . Elinga yen kita ora nuduhake implementasine tartamtu - kita nggunakake antarmuka. Kelas mobil mbutuhake implementasi khusus saka antarmuka FillStrategy :

public class F1Car extends Conveyance {

   public F1Car() {
       this.fillStrategy = new F1PitstopStrategy();
   }
}

public class HybridCar extends Conveyance {

   public HybridCar() {
       this.fillStrategy = new HybridFillStrategy();
   }
}

public class Sedan extends Conveyance {

   public Sedan() {
       this.fillStrategy = new StandardFillStrategy();
   }
}

Ayo ndeleng apa sing kita entuk!

public class Main {

   public static void main(String[] args) {

       Conveyance sedan = new Sedan();
       Conveyance hybrid = new HybridCar();
       Conveyance f1car = new F1Car();

       sedan.fill();
       hybrid.fill();
       f1car.fill();
   }
}
Output konsol:

Just refuel with gas! 
Refuel with gas or electricity — your choice! 
Refuel with gas only after all other pit stop procedures are complete!
apik tenan! Proses ngisi bahan bakar bisa ditindakake! Miturut cara, ora ana sing ngalangi kita nggunakake strategi minangka parameter ing konstruktor! Contone, kaya iki:

public class Conveyance {

   private FillStrategy fillStrategy;

   public Conveyance(FillStrategy fillStrategy) {
       this.fillStrategy = fillStrategy;
   }

   public void fill() {
       this.fillStrategy.fill();
   }

   public void go() {
       System.out.println("Moving forward");
   }

   public void stop() {
       System.out.println("Braking!");
   }
}

public class Sedan extends Conveyance {

   public Sedan() {
       super(new StandardFillStrategy());
   }
}



public class HybridCar extends Conveyance {

   public HybridCar() {
       super(new HybridFillStrategy());
   }
}

public class F1Car extends Conveyance {

   public F1Car() {
       super(new F1PitstopStrategy());
   }
}
Ayo mbukak metode utama () (sing tetep ora diganti). Kita entuk asil sing padha! Output konsol:

Just refuel with gas! 
Refuel with gas or electricity — your choice! 
Refuel with gas only after all other pit stop procedures are complete!
Pola desain strategi nemtokake kulawarga algoritma, encapsulates saben mau, lan mesthekake yen padha bisa diijolke. Iku ngijini sampeyan ngowahi algoritma preduli saka carane padha digunakake dening klien (definisi iki, dijupuk saka buku "Head First Design Patterns", katon apik banget kanggo kula). Pola desain: Strategi - 4Kita wis nemtokake kulawarga algoritma sing kita kasengsem (cara kanggo ngisi bahan bakar mobil) ing antarmuka sing kapisah kanthi implementasine beda. Kita misahake saka mobil dhewe. Saiki yen kita kudu nggawe owah-owahan ing algoritma ngisi bahan bakar tartamtu, iki ora bakal mengaruhi kelas mobil kita kanthi cara apa wae. Lan kanggo entuk interchangeability, kita mung kudu nambah cara setter siji kanggo kelas Conveyance kita:

public class Conveyance {

   FillStrategy fillStrategy;

   public void fill() {
       fillStrategy.fill();
   }

   public void go() {
       System.out.println("Moving forward");
   }

   public void stop() {
       System.out.println("Braking!");
   }

   public void setFillStrategy(FillStrategy fillStrategy) {
       this.fillStrategy = fillStrategy;
   }
}
Saiki kita bisa ngganti strategi kanthi cepet:

public class Main {

   public static void main(String[] args) {

       Stroller stroller= new Stroller();
       stroller.setFillStrategy(new StandardFillStrategy());

       stroller.fill();
   }
}
Yen stroller bayi dumadakan wiwit mlaku nganggo bensin, program kita bakal siap kanggo nangani skenario iki :) Lan babagan iki! Sampeyan wis sinau siji liyane pola desain sing temtu bakal penting lan mbiyantu nalika nggarap proyek nyata :) Nganti wektu sabanjuré!
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION