JavaRush /Blog Jawa /Random-JV /Pola desain proxy

Pola desain proxy

Diterbitake ing grup
Ing pemrograman, penting kanggo ngrancang arsitektur aplikasi kanthi bener. Alat sing penting kanggo iki yaiku pola desain. Dina iki kita bakal ngomong babagan Proxy, utawa kanthi tembung liyane, Wakil.

Napa sampeyan butuh Wakil?

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

Tuladha 1

Ayo mbayangno yen kita duwe proyek gedhe kanthi akeh kode lawas, ing ngendi ana kelas sing tanggung jawab kanggo ngundhuh laporan saka database. Kelas kasebut bisa digunakake kanthi serentak, yaiku, kabeh sistem ora aktif nalika database ngolah panjaluk kasebut. Rata-rata, laporan digawe sajrone 30 menit. Amarga fitur iki, unggahan diwiwiti jam 00:30, lan manajemen nampa laporan iki ing wayah esuk. Sajrone analisis, ternyata laporan kasebut kudu ditampa kanthi cepet sawise digawe, yaiku, sajrone sedina. Ora bisa dijadwal maneh wektu wiwitan, amarga sistem bakal ngenteni respon saka database. Solusi kanggo ngganti prinsip operasi kanthi miwiti upload lan laporan generasi ing thread 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 fungsine digunakake dening bagean liya saka sistem. Ing kasus iki, sampeyan bisa ngenalake kelas proxy penengah nggunakake pola Wakil, sing bakal nampa panjalukan kanggo ngunggah laporan, log wektu wiwitan lan miwiti thread sing kapisah. Nalika laporan digawe, utas bakal ngrampungake karyane lan kabeh wong bakal seneng.

Tuladha 2

Tim pangembangan nggawe situs web poster. Kanggo njupuk data babagan acara anyar, padha nguripake menyang layanan pihak katelu, interaksi karo kang dileksanakake liwat perpustakaan tertutup khusus. Sajrone pangembangan, ana masalah: sistem pihak katelu nganyari data sapisan dina, lan panjaluk kasebut kedadeyan saben pangguna refresh kaca. Iki nggawe akeh panjalukan lan layanan mandheg nanggapi. Solusi kanggo cache respon layanan lan nyedhiyani pengunjung karo asil disimpen ing saben urip maneh, nganyari cache iki perlu. Ing kasus iki, nggunakake pola Wakil minangka solusi sing apik tanpa ngganti fungsi sing wis rampung.

Cara kerjane pola

Kanggo ngleksanakake pola iki, sampeyan kudu nggawe kelas proxy. Iku ngleksanakake antarmuka kelas layanan, simulating prilaku kanggo kode klien. Mangkono, tinimbang obyek nyata, klien sesambungan karo proxy. Biasane, kabeh panjalukan diterusake menyang kelas layanan, nanging kanthi tumindak tambahan sadurunge utawa sawise nelpon. Cukup, obyek proxy iki minangka lapisan antarane kode klien lan obyek target. Ayo goleki conto caching panjalukan saka disk lawas sing alon banget. Ayo dadi jadwal sepur listrik ing sawetara aplikasi kuno, sing prinsip operasi ora bisa diganti. Disk kanthi jadwal sing dianyari dilebokake saben dina ing wektu sing tetep. Dadi kita duwe:
  1. Antarmuka TimetableTrains.
  2. Kelas TimetableElectricTrainssing ngleksanakake antarmuka iki.
  3. Liwat kelas iki kode klien sesambungan karo sistem file disk.
  4. Kelas klien DisplayTimetable. Caranipun printTimetable()ngginakaken metode kelas TimetableElectricTrains.
Skema iki prasaja: Pola Desain Proksi - 2Saiki, saben metode diarani, printTimetable()kelas TimetableElectricTrainsngakses disk, mbongkar data lan menehi menyang klien. Sistem iki bisa dianggo kanthi apik, nanging alon banget. Mulane, diputusake kanggo nambah kinerja sistem kanthi nambah mekanisme caching. Iki bisa ditindakake kanthi nggunakake pola Proxy: Pola Desain Proksi - 3Kanthi cara iki kelas DisplayTimetableora bakal sok dong mirsani yen wis sesambungan karo kelas TimetableElectricTrainsProxylan ora karo sing sadurunge. Implementasi anyar ngemot jadwal sapisan dina, lan sawise panjalukan bola-bali, ngasilake obyek sing wis dimuat saka memori.

Kanggo tugas apa luwih apik nggunakake Proxy?

Ing ngisor iki sawetara kahanan sing pola iki mesthi bakal migunani:
  1. Caching.
  2. Implementasi kesed uga dikenal minangka implementasi kesed. Napa mbukak obyek bebarengan nalika sampeyan bisa mbukak yen perlu?
  3. Panjaluk logging.
  4. Data interim lan mriksa akses.
  5. Nguripake benang pangolahan paralel.
  6. Ngrekam utawa ngetung riwayat telpon.
Ana uga kasus panggunaan liyane. Ngerteni prinsip operasi pola iki, sampeyan bisa nemokake aplikasi sing sukses. Sepisanan, Wakil nindakake perkara sing padha karo Fasad , nanging ora. Proxy nduweni antarmuka sing padha karo obyek layanan. Uga, aja bingung pola karo Dekorator utawa Adaptor . Decorator menehi antarmuka lengkap, nalika Adaptor menehi alternatif.

Kaluwihan lan cacat

  • + Sampeyan bisa ngontrol akses menyang obyek layanan kaya sing dikarepake;
  • + Kapabilitas tambahan kanggo ngatur siklus urip obyek layanan;
  • + Bisa tanpa obyek layanan;
  • + Ngapikake kinerja kode lan keamanan.
  • - Ana risiko rusak ing kinerja amarga perawatan tambahan;
  • - Complicates struktur kelas program.

Pola substitusi ing laku

Ayo ngleksanakake sistem karo sampeyan sing maca jadwal sepur saka disk:
public interface TimetableTrains {
   String[] getTimetable();
   String getTrainDepartureTime();
}
Kelas sing ngetrapake antarmuka utama:
public class TimetableElectricTrains implements TimetableTrains {

   @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 nyoba njupuk jadwal kabeh sepur, program maca file saka disk. Nanging iki isih kembang. File kasebut uga diwaca saben-saben sampeyan kudu entuk jadwal mung siji sepur! Iku apik yen kode kasebut mung ana ing conto sing ala :) Kelas klien:
public class DisplayTimetable {
   private TimetableTrains timetableTrains = new TimetableElectricTrains();

   public void printTimetable() {
       String[] timetable = timetableTrains.getTimetable();
       String[] tmpArr;
       System.out.println("Поезд\tОткуда\tКуда\t\tВремя отправления\tВремя прибытия\tВремя в пути");
       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;Лондон;Прага;13:43;21:15;07:32
BA-1404;Париж;Грац;14:25;21:25;07:00
9B-8710;Прага;Вена;04:48;08:49;04:01;
9B-8122;Прага;Грац;04:48;08:49;04:01
Ayo nyoba:
public static void main(String[] args) {
   DisplayTimetable displayTimetable = new DisplayTimetable();
   displayTimetable.printTimetable();
}
Kesimpulan:

Поезд  Откуда  Куда   Время отправления Время прибытия    Время в пути
9B-6854  Лондон  Прага    13:43         21:15         07:32
BA-1404  Париж   Грац   14:25         21:25         07:00
9B-8710  Прага   Вена   04:48         08:49         04:01
9B-8122  Прага   Грац   04:48         08:49         04:01
Saiki ayo goleki langkah-langkah kanggo ngetrapake pola kita:
  1. Netepake antarmuka sing ngidini sampeyan nggunakake proxy anyar tinimbang obyek asli. Ing conto kita iki TimetableTrains.

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

    Iki kelas proxy kita:

    public class TimetableElectricTrainsProxy implements TimetableTrains {
       // Ссылка на оригинальный an object
       private TimetableTrains timetableTrains = new TimetableElectricTrains();
    
       private String[] timetableCache = null
    
       @Override
       public String[] getTimetable() {
           return timetableTrains.getTimetable();
       }
    
       @Override
       public String getTrainDepartureTime(String trainId) {
           return timetableTrains.getTrainDepartureTime(trainId);
       }
    
       public void clearCache() {
           timetableTrains = null;
       }
    }

    Ing tataran iki, kita mung nggawe kelas karo referensi kanggo obyek asli lan pass kabeh telpon menyang.

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

    public class TimetableElectricTrainsProxy implements TimetableTrains {
       // Ссылка на оригинальный an object
       private TimetableTrains timetableTrains = new TimetableElectricTrains();
    
       private String[] timetableCache = null
    
       @Override
       public String[] getTimetable() {
           if(timetableCache == null) {
               timetableCache = timetableTrains.getTimetable();
           }
           return timetableCache;
       }
    
       @Override
       public String getTrainDepartureTime(String trainId) {
           if(timetableCache == null) {
               timetableCache = timetableTrains.getTimetable();
           }
           for(int i = 0; i < timetableCache.length; i++) {
               if(timetableCache[i].startsWith(trainId+";")) return timetableCache[i];
           }
           return "";
       }
    
       public void clearCache() {
           timetableTrains = null;
       }
    }

    Cara getTimetable()mriksa manawa susunan jadwal di-cache ing memori. Yen ora, iku ngetokake panjalukan kanggo mbukak data saka disk, nyimpen asil. Yen panjalukan wis mlaku, bakal cepet bali obyek saka memori.

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

    Sampeyan ora bisa nindakake iku. Yen sampeyan kudu duplikat kode utawa nindakake manipulasi sing padha, tegese ana sing salah lan sampeyan kudu ndeleng masalah kasebut saka sudut sing beda. Ing conto prasaja kita ora ana cara liya, nanging ing proyek nyata, kemungkinan besar, kode kasebut bakal ditulis kanthi luwih bener.

  4. Ganti nggawe obyek asli ing kode klien karo obyek panggantos:

    public class DisplayTimetable {
       // Измененная link
       private TimetableTrains timetableTrains = new TimetableElectricTrainsProxy();
    
       public void printTimetable() {
           String[] timetable = timetableTrains.getTimetable();
           String[] tmpArr;
           System.out.println("Поезд\tОткуда\tКуда\t\tВремя отправления\tВремя прибытия\tВремя в пути");
           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]);
           }
       }
    }

    Ujian

    
    Поезд  Откуда  Куда   Время отправления Время прибытия    Время в пути
    9B-6854  Лондон  Прага    13:43         21:15         07:32
    BA-1404  Париж   Грац   14:25         21:25         07:00
    9B-8710  Прага   Вена   04:48         08:49         04:01
    9B-8122  Прага   Грац   04:48         08:49         04:01

    Apik, kerjane kanthi bener.

    Sampeyan uga bisa nimbang pabrik sing bakal nggawe loro obyek asli lan obyek panggantos gumantung ing kahanan tartamtu.

Link migunani tinimbang titik

  1. Artikel sing apik babagan pola lan sethithik babagan "Wakil"

Iku kabeh kanggo dina iki! Iku luwih apik kanggo bali sinau lan nyoba kawruh anyar ing laku :)
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION