CodeGym /جاوا بلاگ /Random-SD /پراکسي ڊيزائن جو نمونو
John Squirrels
سطح
San Francisco

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

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

توهان کي پراکسي جي ضرورت ڇو آهي؟

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

مثال 1

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

مثال 2

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

ڊزائن جي نموني جي پويان اصول

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

پراکسي لاءِ ڪهڙا ڪم بهترين آهن؟

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

فائدا ۽ نقصان

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

عمل ۾ پراکسي نموني

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

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
اچو ته جانچ ڪريون:
public static void main(String[] args) {
   TimetableDisplay timetableDisplay = new timetableDisplay();
   timetableDisplay.printTimetable();
}
پيداوار:

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
هاڻي اچو ته اسان جي نموني کي متعارف ڪرائڻ لاء گهربل قدمن ذريعي هلون:
  1. ھڪڙو انٽرفيس بيان ڪريو جيڪو اصل اعتراض جي بدران پراکسي جي استعمال جي اجازت ڏئي ٿو. اسان جي مثال ۾، هي آهي TrainTimetable.

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

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

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

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

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

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

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

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

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

  4. ڪلائنٽ ڪوڊ ۾، اصل اعتراض جي بدران هڪ پراکسي اعتراض ٺاهيو:

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

    چيڪ

    
    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

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

    توھان ھڪڙي ڪارخاني جي اختيار تي پڻ غور ڪري سگھو ٿا جيڪو ھڪڙي اصل اعتراض ۽ ھڪڙو پراکسي اعتراض پيدا ڪري ٿو، خاص شرطن تي منحصر آھي.

اسان کي الوداع چوڻ کان اڳ، هتي هڪ مددگار لنڪ آهي

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