JavaRush /جاوا بلاگ /Random-SD /پراکسي ڊيزائن جو نمونو

پراکسي ڊيزائن جو نمونو

گروپ ۾ شايع ٿيل
پروگرامنگ ۾، اهو ضروري آهي ته مناسب طريقي سان منصوبابندي ڪرڻ لاء ايپليڪيشن فن تعمير. هن لاء هڪ لازمي اوزار ڊزائن جي نمونن آهي. اڄ اسان پراکسي بابت ڳالهائينداسين، يا ٻين لفظن ۾، ڊپٽي.

توهان کي ڊپٽي ڇو ضرورت آهي؟

اهو نمونو هڪ اعتراض تائين ڪنٽرول رسائي سان لاڳاپيل مسئلن کي حل ڪرڻ ۾ مدد ڪري ٿو. توهان وٽ شايد هڪ سوال آهي: "اسان کي اهڙي ڪنٽرول رسائي جي ضرورت ڇو آهي؟" اچو ته ڪجهه حالتن تي نظر رکون جيڪي توهان جي مدد ڪندا ته ڇا آهي.

مثال 1

اچو ته تصور ڪريون ته اسان وٽ ھڪڙو وڏو پروجيڪٽ آھي پراڻو ڪوڊ، جتي ھڪڙو ڪلاس آھي جيڪو ڊيٽابيس مان رپورٽون ڊائون لوڊ ڪرڻ جو ذميوار آھي. ڪلاس هم وقت ڪم ڪري ٿو، يعني سڄو سسٽم بيڪار آهي جڏهن ته ڊيٽابيس درخواست تي عمل ڪري ٿي. سراسري طور تي، هڪ رپورٽ 30 منٽن ۾ ٺاهي وئي آهي. هن فيچر جي ڪري، ان جي اپلوڊ 00:30 تي شروع ٿئي ٿي، ۽ انتظاميا صبح جو هي رپورٽ وصول ڪري ٿي. تجزيي دوران، اهو ظاهر ٿيو ته اهو ضروري آهي ته اها رپورٽ حاصل ڪرڻ کان پوء فوري طور تي پيدا ٿئي ٿي، يعني هڪ ڏينهن اندر. شروعاتي وقت کي ٻيهر شيڊول ڪرڻ ناممڪن آهي، ڇاڪاڻ ته سسٽم ڊيٽابيس مان جواب جو انتظار ڪندو. حل اهو آهي ته اپلوڊ شروع ڪندي آپريٽنگ اصول کي تبديل ڪيو وڃي ۽ هڪ الڳ سلسلي ۾ رپورٽ تيار ڪيو وڃي. اهو حل سسٽم کي معمول وانگر هلائڻ جي اجازت ڏيندو، ۽ انتظاميا تازيون رپورٽون وصول ڪندي. بهرحال، اتي هڪ مسئلو آهي: موجوده ڪوڊ ٻيهر نه ٿو لکي سگھجي، ڇاڪاڻ ته ان جا ڪم سسٽم جي ٻين حصن طرفان استعمال ڪيا ويا آهن. انهي حالت ۾، توهان ڊپٽي پيٽرن کي استعمال ڪندي هڪ وچولي پراڪس ڪلاس متعارف ڪرائي سگهو ٿا، جيڪو هڪ رپورٽ اپلوڊ ڪرڻ، شروعاتي وقت لاگ ان ڪرڻ ۽ هڪ الڳ موضوع شروع ڪرڻ جي درخواست وصول ڪندو. جڏهن رپورٽ ٺاهي ويندي ته ٿريڊ پنهنجو ڪم پورو ڪندو ۽ سڀ خوش ٿيندا.

مثال 2

ترقياتي ٽيم ٺاهي ٿي پوسٽر ويب سائيٽ. نون واقعن جي باري ۾ ڊيٽا حاصل ڪرڻ لاء، اهي هڪ ٽئين پارٽي جي خدمت ڏانهن رخ ڪن ٿا، جنهن سان گڏ هڪ خاص بند لائبريري ذريعي عمل ڪيو ويندو آهي. ترقي جي دوران، هڪ مسئلو پيدا ٿيو: هڪ ٽئين پارٽي سسٽم هڪ ڏينهن ۾ هڪ ڀيرو ڊيٽا کي اپڊيٽ ڪري ٿو، ۽ ان جي درخواست هر وقت ٿيندي آهي جڏهن صارف صفحي کي ريفريش ڪري ٿو. هي درخواستن جو هڪ وڏو تعداد ٺاهي ٿو ۽ خدمت جواب ڏيڻ بند ڪري ٿي. حل اهو آهي ته خدمت جي جواب کي ڪيش ڪرڻ ۽ هر ريبوٽ تي محفوظ ڪيل نتيجن سان گڏ سنڌين کي مهيا ڪرڻ، هن ڪيش کي ضرورت مطابق اپڊيٽ ڪرڻ. انهي حالت ۾، ڊپٽي نموني استعمال ڪندي ختم ٿيل ڪارڪردگي کي تبديل ڪرڻ کان سواء هڪ بهترين حل آهي.

ڪئين نموني ڪم ڪري ٿو

ھن نموني کي لاڳو ڪرڻ لاء، توھان کي ھڪڙو پراکسي ڪلاس ٺاھڻ جي ضرورت آھي. اهو هڪ سروس ڪلاس انٽرفيس کي لاڳو ڪري ٿو، ڪلائنٽ ڪوڊ لاء ان جي رويي کي نقل ڪندي. اهڙيء طرح، حقيقي اعتراض جي بدران، ڪلائنٽ ان جي پراکسي سان رابطو ڪري ٿو. عام طور تي، سڀني درخواستن تي گذري ويا آهن سروس ڪلاس تي، پر ان جي ڪال کان اڳ يا بعد ۾ اضافي ڪارناما سان. بس ڪر، هي پراکسي اعتراض ڪلائنٽ ڪوڊ ۽ ٽارگيٽ اعتراض جي وچ ۾ هڪ پرت آهي. اچو ته هڪ تمام سست پراڻي ڊسڪ کان درخواست کي ڪيش ڪرڻ جو هڪ مثال ڏسو. اچو ته اهو ڪجهه قديم ايپليڪيشن ۾ هڪ برقي ٽرين شيڊول هجي، جنهن جي آپريٽنگ اصول کي تبديل نٿو ڪري سگهجي. اپڊيٽ ٿيل شيڊول سان ڊسڪ هر روز هڪ مقرر وقت تي داخل ڪيو ويندو آهي. تنهنڪري اسان وٽ آهي:
  1. انٽرفيس TimetableTrains.
  2. اهو طبقو TimetableElectricTrainsجيڪو هن انٽرفيس کي لاڳو ڪري ٿو.
  3. اهو هن طبقي جي ذريعي آهي ته ڪلائنٽ ڪوڊ ڊسڪ فائل سسٽم سان رابطو ڪري ٿو.
  4. ڪلائنٽ ڪلاس DisplayTimetable. ان جو طريقو printTimetable()استعمال ڪري ٿو TimetableElectricTrains.
اسڪيم سادو آهي: پراکسي ڊيزائن جو نمونو - 2في الحال، هر وقت هڪ طريقو سڏيو ويندو آهي، printTimetable()ڪلاس TimetableElectricTrainsڊسڪ تائين رسائي ڪري ٿو، ڊيٽا کي لوڊ ڪري ٿو ۽ ڪلائنٽ کي مهيا ڪري ٿو. اهو نظام سٺو ڪم ڪري ٿو، پر تمام سست آهي. تنهن ڪري، اهو فيصلو ڪيو ويو ته سسٽم جي ڪارڪردگي کي وڌائڻ لاء ڪيچنگ ميڪانيزم شامل ڪندي. اهو ڪري سگهجي ٿو پراڪسي نموني استعمال ڪندي: پراکسي ڊيزائن جو نمونو - 3هن طريقي سان ڪلاس DisplayTimetableاهو به نه محسوس ڪندو ته اهو ڪلاس سان رابطو ڪري رهيو آهي TimetableElectricTrainsProxy۽ نه اڳئين سان. نئين عمل درآمد شيڊول کي ڏينهن ۾ هڪ ڀيرو لوڊ ڪري ٿو، ۽ بار بار درخواستن تي، ميموري مان اڳ ۾ ئي لوڊ ٿيل اعتراض واپس ڪري ٿو.

ڪھڙن ​​ڪمن لاءِ پراڪسي استعمال ڪرڻ بھتر آھي؟

هتي ڪجھ حالتون آهن جن ۾ هي نمونو ضرور هٿ ۾ ايندو:
  1. ڪيشنگ.
  2. سست عمل کي سست عمل جي طور تي پڻ سڃاتو وڃي ٿو. ڪنهن شئي کي هڪ ئي وقت ڇو لوڊ ڪريو جڏهن توهان ان کي ضرورت مطابق لوڊ ڪري سگهو ٿا؟
  3. لاگنگ درخواستون.
  4. عبوري ڊيٽا ۽ رسائي چيڪ.
  5. متوازي پروسيسنگ سلسلا شروع ڪرڻ.
  6. ڪال جي تاريخ رڪارڊ ڪرڻ يا ڳڻڻ.
ٻيا استعمال جا ڪيس پڻ آهن. هن نموني جي آپريشن جي اصول کي سمجهڻ، توهان پاڻ کي ان لاء هڪ ڪامياب درخواست ڳولي سگهو ٿا. پهرين نظر ۾، ڊپٽي ساڳيو ڪم ڪري ٿو Facade وانگر ، پر اهو ناهي. پراکسي وٽ ساڳيو انٽرفيس آهي جيئن خدمت اعتراض. انهي سان گڏ، ڊيڪرائيندڙ يا اڊاپٽر سان نموني کي پريشان نه ڪريو . ڊيڪرٽر هڪ وڌايل انٽرفيس مهيا ڪري ٿو، جڏهن ته اڊاپٽر هڪ متبادل مهيا ڪري ٿو.

فائدا ۽ نقصان

  • + توهان سروس اعتراض تائين رسائي کي ڪنٽرول ڪري سگهو ٿا جيئن توهان چاهيو؛
  • + هڪ خدمت اعتراض جي زندگي جي چڪر کي منظم ڪرڻ لاء اضافي صلاحيتون؛
  • + خدمت جي اعتراض کان سواء ڪم؛
  • + ڪوڊ ڪارڪردگي ۽ سيڪيورٽي کي بهتر بڻائي ٿو.
  • - اضافي علاج جي ڪري ڪارڪردگي ۾ خراب ٿيڻ جو خطرو آهي؛
  • - پروگرام طبقن جي جوڙجڪ کي پيچيده.

عملي طور تي متبادل نموني

اچو ته توهان سان گڏ هڪ سسٽم لاڳو ڪريو جيڪو ڊسڪ مان ٽرين شيڊول پڙهي ٿو:
public interface TimetableTrains {
   String[] getTimetable();
   String getTrainDepartureTime();
}
ھڪڙو طبقو جيڪو بنيادي انٽرفيس کي لاڳو ڪري ٿو:
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 "";
   }
}
هر دفعي توهان سڀني ٽرينن جو شيڊول حاصل ڪرڻ جي ڪوشش ڪريو، پروگرام ڊسڪ مان فائل پڙهي ٿو. پر اهي اڃا به گل آهن. فائل پڻ پڙهي ويندي آهي هر وقت توهان کي صرف هڪ ٽرين لاء شيڊول حاصل ڪرڻ جي ضرورت آهي! اهو سٺو آهي ته اهڙو ڪوڊ صرف خراب مثالن ۾ موجود آهي :) ڪلائنٽ ڪلاس:
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]);
       }
   }
}
مثال فائل:

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
اچو ته امتحان وٺون:
public static void main(String[] args) {
   DisplayTimetable displayTimetable = new DisplayTimetable();
   displayTimetable.printTimetable();
}
نتيجو:

Поезд  Откуда  Куда   Время отправления Время прибытия    Время в пути
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
هاڻي اچو ته اسان جي نموني کي لاڳو ڪرڻ جي مرحلن ذريعي وڃو:
  1. ھڪڙو انٽرفيس بيان ڪريو جيڪو توھان کي اجازت ڏئي ٿو ھڪڙو نئون پراکسي استعمال ڪرڻ بدران اصل اعتراض جي. اسان جي مثال ۾ اهو آهي TimetableTrains.

  2. هڪ پراکسي ڪلاس ٺاهيو. اهو لازمي طور تي هڪ خدمت اعتراض جو حوالو هجڻ گهرجي (ڪلاس ۾ ٺاهيو يا تعمير ڪندڙ ۾ پاس ڪريو)؛

    هتي اسان جي پراکسي ڪلاس آهي:

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

    هن اسٽيج تي، اسان صرف اصل اعتراض جي حوالي سان هڪ ڪلاس ٺاهي ۽ سڀني ڪالن کي ان ڏانهن منتقل ڪيو.

  3. اسان پراکسي ڪلاس جي منطق کي لاڳو ڪريون ٿا. بنيادي طور تي ڪال هميشه اصل اعتراض ڏانهن منتقل ڪيو ويندو آهي.

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

    طريقو getTimetable()چيڪ ڪري ٿو ته ڇا شيڊول صف ميموري ۾ ڪيش ٿيل آهي. جيڪڏهن نه، اهو ڊسڪ مان ڊيٽا کي لوڊ ڪرڻ لاء هڪ درخواست جاري ڪري ٿو، نتيجو محفوظ ڪندي. جيڪڏهن درخواست اڳ ۾ ئي هلائي رهي آهي، اهو جلدي جلدي ميموري مان هڪ اعتراض واپس ڪندو.

    ان جي سادي ڪارڪردگي جي مهرباني، getTrainDepartireTime() طريقي کي اصل شئي ڏانهن ريڊائريڪٽ ٿيڻ جي ضرورت نه هئي. اسان صرف ان جي ڪارڪردگي کي نئين طريقي سان نقل ڪيو.

    توهان اهو نٿا ڪري سگهو. جيڪڏهن توهان کي نقل ڪرڻي هئي ڪوڊ يا هڪجهڙا هٿرادو ڪم ڪرڻ، ان جو مطلب آهي ته ڪجهه غلط ٿي ويو آهي ۽ توهان کي مسئلي کي مختلف زاوي کان ڏسڻ جي ضرورت آهي. اسان جي سادي مثال ۾ ڪو ٻيو طريقو ناهي، پر حقيقي منصوبن ۾، گهڻو ڪري، ڪوڊ وڌيڪ صحيح لکيو ويندو.

  4. ڪلائنٽ ڪوڊ ۾ اصل اعتراض جي تخليق کي متبادل اعتراض سان تبديل ڪريو:

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

    امتحان

    
    Поезд  Откуда  Куда   Время отправления Время прибытия    Время в пути
    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

    عظيم، اهو صحيح ڪم ڪري ٿو.

    توھان ھڪڙي ڪارخاني تي پڻ غور ڪري سگھو ٿا جيڪو اصل شئي ۽ ھڪڙي متبادل شئي پيدا ڪري سگھي ٿو خاص شرطن جي بنياد تي.

ڊٽ جي بدران مفيد لنڪ

  1. نمونن جي باري ۾ بهترين مضمون ۽ "ڊپٽي" بابت ٿورڙو

اهو سڀ ڪجهه اڄ لاء آهي! اهو سٺو ٿيندو ته سکڻ ڏانهن واپس وڃو ۽ پنهنجي نئين علم کي عملي طور تي آزمائي :)
تبصرا
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION