سافٽ ويئر ڊولپمينٽ کي وڌيڪ ڏکيو بنايو ويو آهي غير مطابقت رکندڙ اجزاء جن کي گڏجي ڪم ڪرڻ جي ضرورت آهي. مثال طور، جيڪڏهن توهان کي هڪ نئين لائبريري کي هڪ پراڻي پليٽ فارم سان ضم ڪرڻ جي ضرورت آهي، جاوا جي اڳوڻي نسخن ۾ لکيل آهي، توهان کي شايد غير مطابقت رکندڙ شيون، يا بلڪه غير مطابقت واري انٽرفيس سان منهن ڏيڻو پوندو. اڊاپٽر ڊيزائن جو نمونو ڪهڙو مسئلو حل ڪري ٿو؟  - 1هن معاملي ۾ ڇا ڪجي؟ ڪوڊ ٻيهر لکو؟ اسان اهو نٿا ڪري سگهون، ڇاڪاڻ ته سسٽم جو تجزيو ڪرڻ ۾ گهڻو وقت لڳندو يا ايپليڪيشن جي اندروني منطق جي ڀڃڪڙي ٿيندي. هن مسئلي کي حل ڪرڻ لاء، اڊاپٽر نموني ٺاهي وئي. اهو ڪم ڪرڻ ۾ غير مطابقت واري انٽرفيس سان شيون مدد ڪري ٿو. اچو ته ڏسو ته ڪيئن استعمال ڪجي!

مسئلي بابت وڌيڪ اصطلاح

پهرين، اسان پراڻي نظام جي رويي کي نقل ڪنداسين. فرض ڪريو اهو ڪم يا اسڪول ۾ دير ٿيڻ لاءِ عذر پيدا ڪري ٿو. هن کي ڪرڻ لاء، اهو هڪ Excuseانٽرفيس آهي جنهن ۾ آهي generateExcuse()، likeExcuse()۽ dislikeExcuse()طريقا.
public interface Excuse {
   String generateExcuse();
   void likeExcuse(String excuse);
   void dislikeExcuse(String excuse);
}
ڪلاس WorkExcuseهن انٽرفيس کي لاڳو ڪري ٿو:
public class WorkExcuse implements Excuse {
   private String[] excuses = {"in an incredible confluence of circumstances, I ran out of hot water and had to wait until sunlight, focused using a magnifying glass, heated a mug of water so that I could wash.",
   "the artificial intelligence in my alarm clock failed me, waking me up an hour earlier than normal. Because it is winter, I thought it was still nighttime and I fell back asleep. Everything after that is a bit hazy.",
   "my pre-holiday mood slows metabolic processes in my body, leading to depression and insomnia."};
   private String [] apologies = {"This will not happen again, of course. I'm very sorry.", "I apologize for my unprofessional behavior.", "There is no excuse for my actions. I am not worthy of this position."};

   @Override
   public String generateExcuse() { // Randomly select an excuse from the array
       String result = "I was late today because " + excuses[(int) Math.round(Math.random() + 1)] + "\\n" +
               apologies[(int) Math.round(Math.random() + 1)];
       return result;
   }

   @Override
   public void likeExcuse(String excuse) {
       // Duplicate the element in the array so that its chances of being chosen are higher
   }

   @Override
   public void dislikeExcuse(String excuse) {
       // Remove the item from the array
   }
}
اچو ته اسان جي مثال کي جانچيو:
Excuse excuse = new WorkExcuse();
System.out.println(excuse.generateExcuse());
پيداوار:
"I was late today because my pre-holiday mood slows metabolic processes in my body, leading to depression and insomnia.
I apologize for my unprofessional behavior.
ھاڻي تصور ڪريو ته توھان ھڪڙي عذر پيدا ڪرڻ واري سروس شروع ڪئي آھي، انگ اکر گڏ ڪيا، ۽ محسوس ڪيو ته توھان جا گھڻا استعمال ڪندڙ يونيورسٽي جا شاگرد آھن. هن گروپ جي بهتر خدمت ڪرڻ لاءِ، توهان هڪ ٻئي ڊولپر کان پڇيو ته هڪ اهڙو نظام ٺاهيو جيڪو خاص ڪري يونيورسٽي جي شاگردن لاءِ عذر پيدا ڪري. ڊولپمينٽ ٽيم مارڪيٽ ريسرچ ڪئي، درجه بندي عذر، ڪجهه مصنوعي ذهانت کي ڇڪايو، ۽ سروس کي ٽريفڪ رپورٽن، موسم جي رپورٽن، وغيره سان ضم ڪيو. هاڻي توهان وٽ يونيورسٽي جي شاگردن لاءِ عذر پيدا ڪرڻ لاءِ لائبريري آهي، پر ان جو هڪ مختلف انٽرفيس آهي: StudentExcuse.
public interface StudentExcuse {
   String generateExcuse();
   void dislikeExcuse(String excuse);
}
هن انٽرفيس جا ٻه طريقا آهن: generateExcuse, جيڪو هڪ عذر پيدا ڪري ٿو، ۽ dislikeExcuse, جيڪو عذر کي مستقبل ۾ ٻيهر ظاهر ٿيڻ کان روڪي ٿو. ٽئين پارٽي لئبرريءَ ۾ ترميم نه ٿي ڪري سگھجي، يعني توھان ان جو سورس ڪوڊ تبديل نه ٿا ڪري سگھو. جيڪو اسان وٽ آھي ھاڻي ھڪڙو نظام آھي ٻن طبقن سان جيڪو Excuseانٽرفيس کي لاڳو ڪري ٿو، ۽ ھڪڙي SuperStudentExcuseڪلاس سان گڏ لائبريري جيڪو StudentExcuseانٽرفيس کي لاڳو ڪري ٿو:
public class SuperStudentExcuse implements StudentExcuse {
   @Override
   public String generateExcuse() {
       // Logic for the new functionality
       return "An incredible excuse adapted to the current weather conditions, traffic jams, or delays in public transport schedules.";
   }

   @Override
   public void dislikeExcuse(String excuse) {
       // Adds the reason to a blacklist
   }
}
ڪوڊ تبديل نه ٿو ڪري سگھجي. موجوده درجي جو درجو هن طرح نظر اچي ٿو: اڊاپٽر ڊيزائن جو نمونو ڪهڙو مسئلو حل ڪري ٿو؟  - 2سسٽم جو هي نسخو صرف عذر انٽرفيس سان ڪم ڪري ٿو. توهان ڪوڊ ٻيهر نه لکي سگهو ٿا: وڏي ايپليڪيشن ۾، اهڙيون تبديليون ڪرڻ هڪ ڊگهو عمل بڻجي سگهي ٿو يا ايپليڪيشن جي منطق کي ٽوڙي سگهي ٿو. اسان هڪ بنيادي انٽرفيس متعارف ڪري سگهون ٿا ۽ دائري کي وڌايو: اڊاپٽر ڊيزائن جو نمونو ڪهڙو مسئلو حل ڪري ٿو؟  - 3هن کي ڪرڻ لاء، اسان کي Excuseانٽرفيس جو نالو تبديل ڪرڻو پوندو. پر اضافي حد بندي سنجيده ايپليڪيشنن ۾ ناپسنديده آهي: هڪ عام روٽ عنصر متعارف ڪرائڻ فن تعمير کي ڀڃي ٿو. توهان کي هڪ وچولي طبقي کي لاڳو ڪرڻ گهرجي جيڪا اسان کي گهٽ ۾ گهٽ نقصان سان نئين ۽ پراڻي ڪارڪردگي ٻنهي کي استعمال ڪرڻ ڏي. مختصر ۾، توهان کي هڪ اڊاپٽر جي ضرورت آهي .

اڊاپٽر جي نموني جي پويان اصول

هڪ اڊاپٽر هڪ وچولي اعتراض آهي جيڪو هڪ اعتراض جي طريقي جي ڪالن کي ٻئي کي سمجهڻ جي اجازت ڏئي ٿو. اچو ته اسان جي مثال لاء هڪ اڊاپٽر لاڳو ڪريو ۽ ان کي سڏين Middleware. اسان جي اڊاپٽر کي لازمي طور تي ھڪڙو انٽرفيس لاڳو ڪرڻ گھرجي جيڪو ھڪڙي شين سان مطابقت رکي. ان کي ٿيڻ ڏي Excuse. هي Middlewareپهرين اعتراض جي طريقن کي سڏڻ جي اجازت ڏئي ٿو. Middlewareڪال وصول ڪري ٿو ۽ انهن کي ٻئي شئي ڏانهن موازن طريقي سان اڳتي وڌائي ٿو. ھتي آھي عملدرآمد ۽ طريقن Middlewareسان : generateExcusedislikeExcuse
public class Middleware implements Excuse { // 1. Middleware becomes compatible with WorkExcuse objects via the Excuse interface

   private StudentExcuse superStudentExcuse;

   public Middleware(StudentExcuse excuse) { // 2. Get a reference to the object being adapted
       this.superStudentExcuse = excuse;
   }

   @Override
   public String generateExcuse() {
       return superStudentExcuse.generateExcuse(); // 3. The adapter implements an interface method
   }

    @Override
    public void dislikeExcuse(String excuse) {
        // The method first adds the excuse to the blacklist,
        // Then passes it to the dislikeExcuse method of the superStudentExcuse object.
    }
   // The likeExcuse method will appear later
}
جاچ (ڪلائنٽ ڪوڊ ۾):
public class Test {
   public static void main(String[] args) {
       Excuse excuse = new WorkExcuse(); // We create objects of the classes
       StudentExcuse newExcuse = new SuperStudentExcuse(); // that must be compatible.
       System.out.println("An ordinary excuse for an employee:");
       System.out.println(excuse.generateExcuse());
       System.out.println("\n");
       Excuse adaptedStudentExcuse = new Middleware(newExcuse); // Wrap the new functionality in the adapter object
       System.out.println("Using new functionality with the adapter:");
       System.out.println(adaptedStudentExcuse.generateExcuse()); // The adapter calls the adapted method
   }
}
پيداوار:
An ordinary excuse for an employee:
I was late today because my pre-holiday mood slows metabolic processes in my body, leading to depression and insomnia.
There is no excuse for my actions. I am not worthy of this position. Using new functionality with the adapter:
موجوده موسمي حالتن، ٽرئفڪ جام، يا عوامي ٽرانسپورٽ جي شيڊول ۾ دير سان ٺهڪندڙ هڪ ناقابل اعتماد عذر. اهو generateExcuseطريقو صرف ڪال کي ٻئي اعتراض ڏانهن منتقل ڪري ٿو، بغير ڪنهن اضافي تبديلين جي. طريقي dislikeExcuseجي ضرورت آهي ته اسان کي پهريان عذر کي بليڪ لسٽ ڪرڻ گهرجي. وچولي ڊيٽا پروسيسنگ کي انجام ڏيڻ جي صلاحيت هڪ سبب آهي ڇو ته ماڻهو اڊاپٽر جي نموني سان پيار ڪندا آهن. پر likeExcuseطريقي جي باري ۾ ڇا آهي، جيڪو Excuseانٽرفيس جو حصو آهي پر StudentExcuseانٽرفيس جو حصو نه آهي؟ نئين ڪارڪردگي هن آپريشن کي سپورٽ نٿو ڪري. UnsupportedOperationExceptionهن صورتحال لاء ايجاد ڪيو ويو . اهو اڇلايو ويندو آهي جيڪڏهن گهربل آپريشن سپورٽ نه آهي. اچو ته ان کي استعمال ڪريون. هي ڪيئن Middlewareڪلاس جي نئين عمل درآمد ڏسڻ ۾ اچي ٿو:
public class Middleware implements Excuse {

   private StudentExcuse superStudentExcuse;

   public Middleware(StudentExcuse excuse) {
       this.superStudentExcuse = excuse;
   }

   @Override
   public String generateExcuse() {
       return superStudentExcuse.generateExcuse();
   }

   @Override
   public void likeExcuse(String excuse) {
       throw new UnsupportedOperationException("The likeExcuse method is not supported by the new functionality");
   }

   @Override
   public void dislikeExcuse(String excuse) {
       // The method accesses a database to fetch additional information,
       // and then passes it to the superStudentExcuse object's dislikeExcuse method.
   }
}
پهرين نظر ۾، هي حل تمام سٺو نه ٿو لڳي، پر ڪارڪردگي جي تقليد صورتحال کي پيچيده ڪري سگهي ٿي. جيڪڏهن ڪلائنٽ ڌيان ڏئي ٿو، ۽ اڊاپٽر چڱي طرح دستاويز ٿيل آهي، اهڙي حل قابل قبول آهي.

جڏهن هڪ اڊاپٽر استعمال ڪرڻ لاء

  1. جڏهن توهان کي ٽئين پارٽي ڪلاس استعمال ڪرڻ جي ضرورت آهي، پر ان جو انٽرفيس مکيه ايپليڪيشن سان مطابقت ناهي. مٿي ڏنل مثال ڏيکاري ٿو ته هڪ اڊاپٽر اعتراض ڪيئن ٺاهيو جيڪو ڪالن کي هڪ فارميٽ ۾ لپي ٿو جيڪو هڪ ٽارگيٽ اعتراض سمجهي سگهي ٿو.

  2. جڏهن ڪيترن ئي موجود ذيلي طبقن کي ڪجهه عام ڪارڪردگي جي ضرورت آهي. اضافي ذيلي ڪلاسز ٺاهڻ جي بدران (جيڪو ڪوڊ جي نقل جو سبب بڻجندو)، اهو بهتر آهي ته هڪ اڊاپٽر استعمال ڪريو.

فائدا ۽ نقصان

فائدو: اڊاپٽر ڪلائنٽ کان لڪائيندو آهي پروسيسنگ درخواستن جا تفصيل هڪ اعتراض کان ٻئي ڏانهن. ڪلائنٽ ڪوڊ ڊيٽا کي فارميٽ ڪرڻ يا ھدف واري طريقي سان ڪالن کي ھٿ ڪرڻ بابت نه ٿو سوچي. اهو تمام پيچيده آهي، ۽ پروگرامر سست آهن :) نقصان: پروجيڪٽ جو ڪوڊ بنيادي اضافي طبقن کان پيچيده آهي. جيڪڏهن توهان وٽ ڪيترائي غير مطابقت رکندڙ انٽرفيس آهن، اضافي طبقن جو تعداد غير منظم ٿي سگهي ٿو.

اڊاپٽر کي منهن يا سجاڳيءَ سان نه ٺهيو

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

قدم بہ قدم الگورتھم

  1. پهرين، پڪ ڪريو ته توهان وٽ هڪ مسئلو آهي ته اهو نمونو حل ڪري سگهي ٿو.

  2. وضاحت ڪريو ڪلائنٽ انٽرفيس جيڪو استعمال ڪيو ويندو اڻ سڌي طرح غير مطابقت واري شين سان رابطو ڪرڻ لاءِ.

  3. اڊاپٽر ڪلاس کي ورثي ۾ ٺاهيو انٽرفيس جو اڳئين قدم ۾ بيان ڪيو ويو آهي.

  4. اڊاپٽر ڪلاس ۾، adaptee اعتراض جي حوالي سان ذخيرو ڪرڻ لاء هڪ فيلڊ ٺاهيو. هي حوالو تعمير ڪندڙ ڏانهن منتقل ڪيو ويو آهي.

  5. اڊاپٽر ۾ سڀني ڪلائنٽ انٽرفيس طريقن کي لاڳو ڪريو. هڪ طريقو ٿي سگهي ٿو:

    • بغير ڪنهن تبديلي جي ڪالن سان گڏ

    • ڊيٽا کي تبديل ڪريو يا اضافي ڪريو، ٽارگيٽ طريقي سان ڪالن جو تعداد وڌايو/گهٽايو، وغيره.

    • انتهائي حالتن ۾، جيڪڏهن ڪو خاص طريقو غير مطابقت رکي ٿو، هڪ اڻڄاتل آپريشن استثنا اڇلايو. غير معاون عملن کي سختي سان دستاويز ڪيو وڃي.

  6. جيڪڏهن ايپليڪيشن صرف ڪلائنٽ انٽرفيس ذريعي اڊاپٽر ڪلاس استعمال ڪري ٿي (جيئن مٿي ڏنل مثال ۾)، پوء اڊاپٽر مستقبل ۾ دردناڪ طور تي وڌايو وڃي ٿو.

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