توهان کي ڊپٽي ڇو ضرورت آهي؟
اهو نمونو هڪ اعتراض تائين ڪنٽرول رسائي سان لاڳاپيل مسئلن کي حل ڪرڻ ۾ مدد ڪري ٿو. توهان وٽ شايد هڪ سوال آهي: "اسان کي اهڙي ڪنٽرول رسائي جي ضرورت ڇو آهي؟" اچو ته ڪجهه حالتن تي نظر رکون جيڪي توهان جي مدد ڪندا ته ڇا آهي.مثال 1
اچو ته تصور ڪريون ته اسان وٽ ھڪڙو وڏو پروجيڪٽ آھي پراڻو ڪوڊ، جتي ھڪڙو ڪلاس آھي جيڪو ڊيٽابيس مان رپورٽون ڊائون لوڊ ڪرڻ جو ذميوار آھي. ڪلاس هم وقت ڪم ڪري ٿو، يعني سڄو سسٽم بيڪار آهي جڏهن ته ڊيٽابيس درخواست تي عمل ڪري ٿي. سراسري طور تي، هڪ رپورٽ 30 منٽن ۾ ٺاهي وئي آهي. هن فيچر جي ڪري، ان جي اپلوڊ 00:30 تي شروع ٿئي ٿي، ۽ انتظاميا صبح جو هي رپورٽ وصول ڪري ٿي. تجزيي دوران، اهو ظاهر ٿيو ته اهو ضروري آهي ته اها رپورٽ حاصل ڪرڻ کان پوء فوري طور تي پيدا ٿئي ٿي، يعني هڪ ڏينهن اندر. شروعاتي وقت کي ٻيهر شيڊول ڪرڻ ناممڪن آهي، ڇاڪاڻ ته سسٽم ڊيٽابيس مان جواب جو انتظار ڪندو. حل اهو آهي ته اپلوڊ شروع ڪندي آپريٽنگ اصول کي تبديل ڪيو وڃي ۽ هڪ الڳ سلسلي ۾ رپورٽ تيار ڪيو وڃي. اهو حل سسٽم کي معمول وانگر هلائڻ جي اجازت ڏيندو، ۽ انتظاميا تازيون رپورٽون وصول ڪندي. بهرحال، اتي هڪ مسئلو آهي: موجوده ڪوڊ ٻيهر نه ٿو لکي سگھجي، ڇاڪاڻ ته ان جا ڪم سسٽم جي ٻين حصن طرفان استعمال ڪيا ويا آهن. انهي حالت ۾، توهان ڊپٽي پيٽرن کي استعمال ڪندي هڪ وچولي پراڪس ڪلاس متعارف ڪرائي سگهو ٿا، جيڪو هڪ رپورٽ اپلوڊ ڪرڻ، شروعاتي وقت لاگ ان ڪرڻ ۽ هڪ الڳ موضوع شروع ڪرڻ جي درخواست وصول ڪندو. جڏهن رپورٽ ٺاهي ويندي ته ٿريڊ پنهنجو ڪم پورو ڪندو ۽ سڀ خوش ٿيندا.مثال 2
ترقياتي ٽيم ٺاهي ٿي پوسٽر ويب سائيٽ. نون واقعن جي باري ۾ ڊيٽا حاصل ڪرڻ لاء، اهي هڪ ٽئين پارٽي جي خدمت ڏانهن رخ ڪن ٿا، جنهن سان گڏ هڪ خاص بند لائبريري ذريعي عمل ڪيو ويندو آهي. ترقي جي دوران، هڪ مسئلو پيدا ٿيو: هڪ ٽئين پارٽي سسٽم هڪ ڏينهن ۾ هڪ ڀيرو ڊيٽا کي اپڊيٽ ڪري ٿو، ۽ ان جي درخواست هر وقت ٿيندي آهي جڏهن صارف صفحي کي ريفريش ڪري ٿو. هي درخواستن جو هڪ وڏو تعداد ٺاهي ٿو ۽ خدمت جواب ڏيڻ بند ڪري ٿي. حل اهو آهي ته خدمت جي جواب کي ڪيش ڪرڻ ۽ هر ريبوٽ تي محفوظ ڪيل نتيجن سان گڏ سنڌين کي مهيا ڪرڻ، هن ڪيش کي ضرورت مطابق اپڊيٽ ڪرڻ. انهي حالت ۾، ڊپٽي نموني استعمال ڪندي ختم ٿيل ڪارڪردگي کي تبديل ڪرڻ کان سواء هڪ بهترين حل آهي.ڪئين نموني ڪم ڪري ٿو
ھن نموني کي لاڳو ڪرڻ لاء، توھان کي ھڪڙو پراکسي ڪلاس ٺاھڻ جي ضرورت آھي. اهو هڪ سروس ڪلاس انٽرفيس کي لاڳو ڪري ٿو، ڪلائنٽ ڪوڊ لاء ان جي رويي کي نقل ڪندي. اهڙيء طرح، حقيقي اعتراض جي بدران، ڪلائنٽ ان جي پراکسي سان رابطو ڪري ٿو. عام طور تي، سڀني درخواستن تي گذري ويا آهن سروس ڪلاس تي، پر ان جي ڪال کان اڳ يا بعد ۾ اضافي ڪارناما سان. بس ڪر، هي پراکسي اعتراض ڪلائنٽ ڪوڊ ۽ ٽارگيٽ اعتراض جي وچ ۾ هڪ پرت آهي. اچو ته هڪ تمام سست پراڻي ڊسڪ کان درخواست کي ڪيش ڪرڻ جو هڪ مثال ڏسو. اچو ته اهو ڪجهه قديم ايپليڪيشن ۾ هڪ برقي ٽرين شيڊول هجي، جنهن جي آپريٽنگ اصول کي تبديل نٿو ڪري سگهجي. اپڊيٽ ٿيل شيڊول سان ڊسڪ هر روز هڪ مقرر وقت تي داخل ڪيو ويندو آهي. تنهنڪري اسان وٽ آهي:- انٽرفيس
TimetableTrains
. - اهو طبقو
TimetableElectricTrains
جيڪو هن انٽرفيس کي لاڳو ڪري ٿو. - اهو هن طبقي جي ذريعي آهي ته ڪلائنٽ ڪوڊ ڊسڪ فائل سسٽم سان رابطو ڪري ٿو.
- ڪلائنٽ ڪلاس
DisplayTimetable
. ان جو طريقوprintTimetable()
استعمال ڪري ٿوTimetableElectricTrains
.
printTimetable()
ڪلاس TimetableElectricTrains
ڊسڪ تائين رسائي ڪري ٿو، ڊيٽا کي لوڊ ڪري ٿو ۽ ڪلائنٽ کي مهيا ڪري ٿو. اهو نظام سٺو ڪم ڪري ٿو، پر تمام سست آهي. تنهن ڪري، اهو فيصلو ڪيو ويو ته سسٽم جي ڪارڪردگي کي وڌائڻ لاء ڪيچنگ ميڪانيزم شامل ڪندي. اهو ڪري سگهجي ٿو پراڪسي نموني استعمال ڪندي: هن طريقي سان ڪلاس DisplayTimetable
اهو به نه محسوس ڪندو ته اهو ڪلاس سان رابطو ڪري رهيو آهي TimetableElectricTrainsProxy
۽ نه اڳئين سان. نئين عمل درآمد شيڊول کي ڏينهن ۾ هڪ ڀيرو لوڊ ڪري ٿو، ۽ بار بار درخواستن تي، ميموري مان اڳ ۾ ئي لوڊ ٿيل اعتراض واپس ڪري ٿو.
ڪھڙن ڪمن لاءِ پراڪسي استعمال ڪرڻ بھتر آھي؟
هتي ڪجھ حالتون آهن جن ۾ هي نمونو ضرور هٿ ۾ ايندو:- ڪيشنگ.
- سست عمل کي سست عمل جي طور تي پڻ سڃاتو وڃي ٿو. ڪنهن شئي کي هڪ ئي وقت ڇو لوڊ ڪريو جڏهن توهان ان کي ضرورت مطابق لوڊ ڪري سگهو ٿا؟
- لاگنگ درخواستون.
- عبوري ڊيٽا ۽ رسائي چيڪ.
- متوازي پروسيسنگ سلسلا شروع ڪرڻ.
- ڪال جي تاريخ رڪارڊ ڪرڻ يا ڳڻڻ.
فائدا ۽ نقصان
- + توهان سروس اعتراض تائين رسائي کي ڪنٽرول ڪري سگهو ٿا جيئن توهان چاهيو؛
- + هڪ خدمت اعتراض جي زندگي جي چڪر کي منظم ڪرڻ لاء اضافي صلاحيتون؛
- + خدمت جي اعتراض کان سواء ڪم؛
- + ڪوڊ ڪارڪردگي ۽ سيڪيورٽي کي بهتر بڻائي ٿو.
- - اضافي علاج جي ڪري ڪارڪردگي ۾ خراب ٿيڻ جو خطرو آهي؛
- - پروگرام طبقن جي جوڙجڪ کي پيچيده.
عملي طور تي متبادل نموني
اچو ته توهان سان گڏ هڪ سسٽم لاڳو ڪريو جيڪو ڊسڪ مان ٽرين شيڊول پڙهي ٿو: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
هاڻي اچو ته اسان جي نموني کي لاڳو ڪرڻ جي مرحلن ذريعي وڃو:
-
ھڪڙو انٽرفيس بيان ڪريو جيڪو توھان کي اجازت ڏئي ٿو ھڪڙو نئون پراکسي استعمال ڪرڻ بدران اصل اعتراض جي. اسان جي مثال ۾ اهو آهي
TimetableTrains
. -
هڪ پراکسي ڪلاس ٺاهيو. اهو لازمي طور تي هڪ خدمت اعتراض جو حوالو هجڻ گهرجي (ڪلاس ۾ ٺاهيو يا تعمير ڪندڙ ۾ پاس ڪريو)؛
هتي اسان جي پراکسي ڪلاس آهي:
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; } }
هن اسٽيج تي، اسان صرف اصل اعتراض جي حوالي سان هڪ ڪلاس ٺاهي ۽ سڀني ڪالن کي ان ڏانهن منتقل ڪيو.
-
اسان پراکسي ڪلاس جي منطق کي لاڳو ڪريون ٿا. بنيادي طور تي ڪال هميشه اصل اعتراض ڏانهن منتقل ڪيو ويندو آهي.
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() طريقي کي اصل شئي ڏانهن ريڊائريڪٽ ٿيڻ جي ضرورت نه هئي. اسان صرف ان جي ڪارڪردگي کي نئين طريقي سان نقل ڪيو.
توهان اهو نٿا ڪري سگهو. جيڪڏهن توهان کي نقل ڪرڻي هئي ڪوڊ يا هڪجهڙا هٿرادو ڪم ڪرڻ، ان جو مطلب آهي ته ڪجهه غلط ٿي ويو آهي ۽ توهان کي مسئلي کي مختلف زاوي کان ڏسڻ جي ضرورت آهي. اسان جي سادي مثال ۾ ڪو ٻيو طريقو ناهي، پر حقيقي منصوبن ۾، گهڻو ڪري، ڪوڊ وڌيڪ صحيح لکيو ويندو.
-
ڪلائنٽ ڪوڊ ۾ اصل اعتراض جي تخليق کي متبادل اعتراض سان تبديل ڪريو:
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
عظيم، اهو صحيح ڪم ڪري ٿو.
توھان ھڪڙي ڪارخاني تي پڻ غور ڪري سگھو ٿا جيڪو اصل شئي ۽ ھڪڙي متبادل شئي پيدا ڪري سگھي ٿو خاص شرطن جي بنياد تي.
ڊٽ جي بدران مفيد لنڪ
-
نمونن جي باري ۾ بهترين مضمون ۽ "ڊپٽي" بابت ٿورڙو
GO TO FULL VERSION