CodeGym /Blog Jawa /Acak /Pola desain proxy
John Squirrels
tingkat
San Francisco

Pola desain proxy

Diterbitake ing grup
Ing pemrograman, penting kanggo ngrancang arsitektur aplikasi kanthi bener. Pola desain minangka cara sing penting kanggo ngrampungake iki. Dina iki ayo ngomong babagan proxy.

Napa sampeyan butuh proxy?

Pola iki mbantu ngatasi masalah sing ana gandhengane karo akses sing dikontrol menyang obyek. Sampeyan bisa uga takon, "Yagene kita butuh akses sing dikontrol?" Ayo goleki sawetara kahanan sing bakal mbantu sampeyan ngerteni apa.

Tuladha 1

Mbayangno sing kita duwe project gedhe karo Bunch saka kode lawas, ngendi ana kelas tanggung jawab kanggo ngekspor laporan saka database. Kelas dianggo bebarengan. Yaiku, kabeh sistem ora aktif nalika database ngolah panyuwunan kasebut. Rata-rata, butuh 30 menit kanggo nggawe laporan. Mulane, proses ekspor diwiwiti jam 12:30, lan manajemen nampa laporan kasebut ing wayah esuk. Audit kasebut nuduhake manawa luwih becik bisa langsung nampa laporan kasebut sajrone jam kerja normal. Wektu wiwitan ora bisa ditundha, lan sistem ora bisa mblokir nalika ngenteni respon saka database. Solusi kasebut yaiku ngganti cara kerja sistem, ngasilake lan ngekspor laporan ing benang sing kapisah. Solusi iki bakal ngidini sistem bisa digunakake kaya biasane, lan manajemen bakal nampa laporan anyar. Nanging, ana masalah: kode saiki ora bisa ditulis maneh, amarga bagéan saka sistem nggunakake fungsi sawijining. Ing kasus iki, kita bisa nggunakake pola proxy kanggo ngenalake kelas proxy penengah sing bakal nampa panjalukan kanggo ngekspor laporan, log wektu wiwitan, lan mbukak thread sing kapisah. Sawise laporan digawe, thread bakal mandheg lan kabeh wong seneng.

Tuladha 2

Tim pangembangan nggawe situs web acara. Kanggo entuk data babagan acara anyar, tim takon layanan pihak katelu. Perpustakaan pribadi khusus nggampangake interaksi karo layanan kasebut. Sajrone pembangunan, masalah ditemokake: sistem pihak katelu nganyari data sapisan dina, nanging panjalukan dikirim menyang saben pangguna refresh kaca. Iki nggawe akeh panjalukan, lan layanan mandheg nanggapi. Solusi kanggo cache respon layanan lan bali asil cache kanggo pengunjung minangka kaca dimuat maneh, nganyari cache yen perlu. Ing kasus iki, pola desain proxy minangka solusi sing apik banget sing ora ngganti fungsi sing ana.

Prinsip konco pola desain

Kanggo ngleksanakake pola iki, sampeyan kudu nggawe kelas proxy. Iki ngetrapake antarmuka kelas layanan, niru prilaku kanggo kode klien. Kanthi cara iki, klien sesambungan karo proxy tinimbang obyek nyata. Minangka aturan, kabeh panjalukan diterusake menyang kelas layanan, nanging kanthi tumindak tambahan sadurunge utawa sawise. Cukup, proxy minangka lapisan antarane kode klien lan obyek target. Coba conto caching query asil saka hard disk lawas lan alon banget. Contone, kita ngomong babagan jadwal sepur listrik ing sawetara aplikasi kuno sing logika ora bisa diganti. Disk kanthi jadwal sing dianyari dilebokake saben dina ing wektu sing tetep. Dadi, kita duwe:
  1. TrainTimetableantarmuka.
  2. ElectricTrainTimetable, sing ngleksanakake antarmuka iki.
  3. Kode klien sesambungan karo sistem file liwat kelas iki.
  4. TimetableDisplaykelas klien. Metode kasebut printTimetable()nggunakake metode kelas ElectricTrainTimetable.
Diagram kasebut prasaja: Pola desain proxy: - 2Saiki, kanthi saben telpon metode kasebut printTimetable(), ElectricTrainTimetablekelas ngakses disk, ngemot data, lan menehi menyang klien. Sistem fungsi oke, nanging alon banget. Akibaté, kaputusan digawe kanggo nambah kinerja sistem kanthi nambah mekanisme caching. Iki bisa rampung nggunakake pola proxy: Pola desain proxy: - 3Mangkono, TimetableDisplaykelas ora malah sok dong mirsani sing sesambungan karo kelas ElectricTrainTimetableProxytinimbang kelas lawas. Implementasi anyar ngemot jadwal sapisan dina. Kanggo panjalukan baleni, ngasilake obyek sing dimuat sadurunge saka memori.

Apa tugas sing paling apik kanggo proxy?

Ing ngisor iki sawetara kahanan ing ngendi pola iki mesthi bakal migunani:
  1. Caching
  2. Ditundha, utawa kesed, initialization Apa mbukak obyek langsung yen sampeyan bisa mbukak minangka needed?
  3. Panjaluk logging
  4. Verifikasi penengah data lan akses
  5. Miwiti thread buruh
  6. Akses ngrekam menyang obyek
Lan ana uga kasus panggunaan liyane. Ngerteni prinsip ing mburi pola iki, sampeyan bisa ngenali kahanan sing bisa ditrapake kanthi sukses. Sepisanan, proxy nindakake perkara sing padha karo fasad , nanging ora kaya ngono. Proxy nduweni antarmuka sing padha karo obyek layanan. Uga, aja bingung pola iki karo pola dekorator utawa Adaptor . A dekorator menehi antarmuka lengkap, lan adaptor menehi antarmuka alternatif.

Kaluwihan lan cacat

  • + Sampeyan bisa ngontrol akses menyang obyek layanan kaya sing dikarepake
  • + Kemampuan tambahan sing ana gandhengane karo ngatur siklus urip obyek layanan
  • + Kerjane tanpa obyek layanan
  • + Ngapikake kinerja lan keamanan kode.
  • - Ana risiko kinerja bisa dadi luwih elek amarga panjaluk tambahan
  • - Iku ndadekake hirarki kelas luwih rumit

Pola proxy ing laku

Ayo ngleksanakake sistem sing maca jadwal sepur saka hard disk:

public interface TrainTimetable {
   String[] getTimetable();
   String getTrainDepartureTime();
}
Mangkene kelas sing ngetrapake antarmuka utama:

public class ElectricTrainTimetable implements TrainTimetable {

   @Override
   public String[] getTimetable() {
       ArrayList<String> list = new ArrayList<>();
       try {
           Scanner scanner = new Scanner(new FileReader(new File("/tmp/electric_trains.csv")));
           while (scanner.hasNextLine()) {
               String line = scanner.nextLine();
               list.add(line);
           }
       } catch (IOException e) {
           System.err.println("Error:  " + e);
       }
       return list.toArray(new String[list.size()]);
   }

   @Override
   public String getTrainDepartureTime(String trainId) {
       String[] timetable = getTimetable();
       for (int i = 0; i < timetable.length; i++) {
           if (timetable[i].startsWith(trainId+";")) return timetable[i];
       }
       return "";
   }
}
Saben sampeyan entuk jadwal sepur, program kasebut maca file saka disk. Nanging iki mung wiwitan masalah kita. Kabeh file diwaca saben sampeyan entuk jadwal kanggo sepur siji! Iku apik yen kode kasebut mung ana ing conto sing ora kudu ditindakake :) Kelas klien:

public class TimetableDisplay {
   private TrainTimetable trainTimetable = new ElectricTrainTimetable();

   public void printTimetable() {
       String[] timetable = trainTimetable.getTimetable();
       String[] tmpArr;
       System.out.println("Train\\tFrom\\tTo\\t\\tDeparture time\\tArrival time\\tTravel time");
       for (int i = 0; i < timetable.length; i++) {
           tmpArr = timetable[i].split(";");
           System.out.printf("%s\t%s\t%s\t\t%s\t\t\t\t%s\t\t\t%s\n", tmpArr[0], tmpArr[1], tmpArr[2], tmpArr[3], tmpArr[4], tmpArr[5]);
       }
   }
}
Tuladha file:

9B-6854;London;Prague;13:43;21:15;07:32
BA-1404;Paris;Graz;14:25;21:25;07:00
9B-8710;Prague;Vienna;04:48;08:49;04:01;
9B-8122;Prague;Graz;04:48;08:49;04:01
Ayo dites:

public static void main(String[] args) {
   TimetableDisplay timetableDisplay = new timetableDisplay();
   timetableDisplay.printTimetable();
}
Output:

Train  From  To  Departure time  Arrival time  Travel time
9B-6854  London  Prague  13:43  21:15  07:32
BA-1404  Paris  Graz  14:25  21:25  07:00
9B-8710  Prague  Vienna  04:48  08:49  04:01
9B-8122  Prague  Graz  04:48  08:49  04:01
Saiki ayo mlaku liwat langkah-langkah sing dibutuhake kanggo ngenalake pola kita:
  1. Netepake antarmuka sing ngidini nggunakake proxy tinimbang obyek asli. Ing conto kita, iki TrainTimetable.

  2. Nggawe kelas proxy. Sampeyan kudu duwe referensi kanggo obyek layanan (nggawe ing kelas utawa pass kanggo konstruktor).

    Iki kelas proxy kita:

    
    public class ElectricTrainTimetableProxy implements TrainTimetable {
       // Reference to the original object
       private TrainTimetable trainTimetable = new ElectricTrainTimetable();
      
       private String[] timetableCache = null
    
       @Override
       public String[] getTimetable() {
           return trainTimetable.getTimetable();
       }
    
       @Override
       public String getTrainDepartureTime(String trainId) {
           return trainTimetable.getTrainDepartureTime(trainId);
       }
      
       public void clearCache() {
           trainTimetable = null;
       }
    }
    

    Ing tahap iki, kita mung nggawe kelas kanthi referensi menyang obyek asli lan nerusake kabeh telpon menyang.

  3. Ayo ngleksanakake logika kelas proxy. Sejatine, telpon tansah dialihake menyang obyek asli.

    
    public class ElectricTrainTimetableProxy implements TrainTimetable {
       // Reference to the original object
       private TrainTimetable trainTimetable = new ElectricTrainTimetable();
    
       private String[] timetableCache = null
    
       @Override
       public String[] getTimetable() {
           if (timetableCache == null) {
               timetableCache = trainTimetable.getTimetable();
           }
           return timetableCache;
       }
    
       @Override
       public String getTrainDepartureTime(String trainId) {
           if (timetableCache == null) {
               timetableCache = trainTimetable.getTimetable();
           }
           for (int i = 0; i < timetableCache.length; i++) {
               if (timetableCache[i].startsWith(trainId+";")) return timetableCache[i];
           }
           return "";
       }
    
       public void clearCache() {
           trainTimetable = null;
       }
    }
    

    Priksa getTimetable()manawa susunan jadwal wis di-cache ing memori. Yen ora, iku ngirim panjalukan kanggo mbukak data saka disk lan nyimpen asil. Yen jadwal wis dijaluk, cepet bali obyek saka memori.

    Thanks kanggo fungsi sing prasaja, metode getTrainDepartureTime () ora kudu dialihake menyang obyek asli. Kita mung duplikat fungsi ing cara anyar.

    Aja nindakake iki. Yen sampeyan kudu duplikat kode utawa nindakake soko padha, banjur ana sing salah, lan sampeyan kudu katon ing masalah maneh saka sudhut liyane. Ing conto prasaja kita, kita ora duwe pilihan liyane. Nanging ing proyek nyata, kode kasebut bakal ditulis kanthi luwih bener.

  4. Ing kode klien, gawe obyek proxy tinimbang obyek asli:

    
    public class TimetableDisplay {
       // Changed reference
       private TrainTimetable trainTimetable = new ElectricTrainTimetableProxy();
    
       public void printTimetable() {
           String[] timetable = trainTimetable.getTimetable();
           String[] tmpArr;
           System.out.println("Train\\tFrom\\tTo\\t\\tDeparture time\\tArrival time\\tTravel time");
           for (int i = 0; i < timetable.length; i++) {
               tmpArr = timetable[i].split(";");
               System.out.printf("%s\t%s\t%s\t\t%s\t\t\t\t%s\t\t\t%s\n", tmpArr[0], tmpArr[1], tmpArr[2], tmpArr[3], tmpArr[4], tmpArr[5]);
           }
       }
    }
    

    Mrikso

    
    Train  From  To  Departure time  Arrival time  Travel time
    9B-6854  London  Prague  13:43  21:15  07:32
    BA-1404  Paris  Graz  14:25  21:25  07:00
    9B-8710  Prague  Vienna  04:48  08:49  04:01
    9B-8122  Prague  Graz  04:48  08:49  04:01
    

    Apik, kerjane kanthi bener.

    Sampeyan uga bisa nimbang pilihan saka pabrik sing nggawe loro obyek asli lan obyek proxy, gumantung ing kahanan tartamtu.

Sadurunge pamit, iki link sing migunani

Iku kabeh kanggo dina iki! Ora bakal dadi ide sing ala kanggo bali menyang pelajaran lan nyoba kawruh anyar ing praktik :)
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION