JavaRush /جاوا بلاگ /Random-SD /ڊيزائن جو نمونو "حڪمت"

ڊيزائن جو نمونو "حڪمت"

گروپ ۾ شايع ٿيل
سلام! پوئين ليڪچرن ۾، اسان اڳ ۾ ئي "ڊزائن جي نموني" جي طور تي اهڙي تصور کي منهن ڏنو آهي. جي صورت ۾ توهان وساري ڇڏيو، اچو ته توهان کي ياد ڏياريون: هي اصطلاح پروگرامنگ ۾ هڪ عام مسئلي جي هڪ خاص معياري حل کي ظاهر ڪري ٿو. ڊيزائن جو نمونو "حڪمت" - 1JavaRush تي اسان اڪثر چوندا آهيون ته تقريبن ڪنهن به سوال جو جواب گوگل ٿي سگهي ٿو. تنهن ڪري، ڪنهن ماڻهو شايد اڳ ۾ ئي ڪاميابي سان حل ڪيو آهي هڪ مسئلو توهان وانگر. تنهن ڪري، نمونن وقت-آزمائشي ۽ مشق-آزمائشي حل آهن سڀ کان عام مسئلن يا طريقن جي مسئلن کي حل ڪرڻ جا طريقا. اهي تمام "سائيڪلون" آهن جيڪي ڪنهن به صورت ۾ توهان کي پنهنجو پاڻ کي ايجاد ڪرڻ جي ضرورت ناهي، پر توهان کي ڄاڻڻ جي ضرورت آهي ته ڪيئن ۽ ڪڏهن انهن کي لاڳو ڪرڻ :) نمونن جو ٻيو ڪم هڪ واحد معيار تي تعمير ڪرڻ آهي. ڪنهن ٻئي جو ڪوڊ پڙهڻ ڪو آسان ڪم ناهي! هرڪو ان کي مختلف انداز ۾ لکي ٿو، ڇاڪاڻ ته ساڳيو مسئلو ڪيترن ئي طريقن سان حل ڪري سگهجي ٿو. پر نمونن جو استعمال مختلف پروگرامرن کي اجازت ڏئي ٿو ته پروگرام جي منطق کي سمجھڻ کان سواءِ ڪوڊ جي هر لڪير ۾ (جيتوڻيڪ اهي ان کي پهريون ڀيرو ڏسن!) اڄ اسان هڪ تمام عام نمونن مان هڪ کي ڏسنداسين جنهن کي ”حڪومتي“ سڏيو ويندو آهي. ڊيزائن جو نمونو ”حڪومتي“ - 2اچو ته تصور ڪريو ته اسان هڪ پروگرام لکي رهيا آهيون جيڪو فعال طور تي ڪار اعتراض سان ڪم ڪري ٿو. انهي صورت ۾، اهو خاص طور تي اهم ناهي ته اسان جو پروگرام ڇا ڪندو آهي. هن کي ڪرڻ لاء، اسان هڪ وراثت وارو نظام ٺاهيو هڪ والدين طبقي Auto۽ ٽن ٻارن جي طبقن سان: Sedan, Truck۽ F1Car.
public class Auto {

   public void gas() {
       System.out.println("Едем вперед");
   }

   public void stop() {

       System.out.println("Тормозим!");
   }
}

public class Sedan extends Auto {
}

public class Truck extends Auto {
}

public class F1Car extends Auto {
}
سڀئي ٽي ٻار ڪلاس والدين کان ٻه معياري طريقا ورثي ۾ ملن ٿا - gas()۽ stop() اسان جو پروگرام تمام سادو آهي: ڪارون صرف اڳتي ۽ بريڪ هلائي سگهن ٿيون. اسان جي ڪم کي جاري رکندي، اسان فيصلو ڪيو ته ڪارن ۾ هڪ نئون طريقو شامل ڪيو وڃي - fill()(ريفيول). اچو ته ان کي والدين طبقي ۾ شامل ڪريون Auto:
public class Auto {

   public void gas() {
       System.out.println("Едем вперед");
   }

   public void stop() {

       System.out.println("Тормозим!");
   }

   public void fill() {
       System.out.println("Заправить бензин!");
   }
}
لڳي ٿو ته اهڙي سادي صورتحال ۾ مسئلا پيدا ٿي سگهن ٿا؟ خير، حقيقت ۾، اهي اڳ ۾ ئي پيدا ٿي چڪا آهن ... ڊيزائن جو نمونو ”حڪومتي“ - 3
public class ChildrenBuggies extends Auto {

   public void fill() {

       //хм... Это детский багги, его не надо заправлять :/
   }
}
اسان جي پروگرام ۾ هڪ ڪار ظاهر ٿيو آهي جيڪا عام تصور ۾ نه ايندي آهي - ٻارن جي بگي. اهو ٿي سگهي ٿو پيڊل هلائيندڙ يا ريڊيو ڪنٽرول، پر هڪ شيء يقيني آهي - ان ۾ گئسولين رکڻ لاء ڪٿي به ناهي. اسان جي وراثت واري اسڪيم جي نتيجي ۾ اسان عام طريقن کي به انهن طبقن کي ڏنو آهي جن کي انهن جي ضرورت ناهي. اهڙي صورتحال ۾ اسان کي ڇا ڪرڻ گهرجي؟ fill()خير، مثال طور، توهان ڪلاس ۾ طريقي کي ختم ڪري سگهو ٿا ChildrenBuggiesته جيئن توهان بگي کي ريفيول ڪرڻ جي ڪوشش ڪندا، ڪجھ به نه ٿيندو:
public class ChildrenBuggies extends Auto {

   @Override
   public void fill() {
       System.out.println("Игрушечную машину нельзя заправить!");
   }
}
پر اهو حل مشڪل سان ڪامياب ٿي سگهي ٿو، گهٽ ۾ گهٽ ڪوڊ جي نقل جي ڪري. مثال طور، گھڻا طبقا والدين طبقي مان ھڪڙو طريقو استعمال ڪندا، پر ٻين طبقن کي ان کي ختم ڪرڻ تي مجبور ڪيو ويندو. جيڪڏهن اسان وٽ 15 ڪلاس آهن، ۽ 5-6 ۾ اسان کي رويي کي ختم ڪرڻ تي مجبور ڪيو وڃي ٿو، ڪوڊ جي نقل ڪافي وسيع ٿي ويندي. ٿي سگهي ٿو انٽرفيس اسان جي مدد ڪري سگهي ٿو؟ مثال طور، هي هڪ:
public interface Fillable {

   public void fill();
}
Fillableاسان ھڪڙي طريقي سان ھڪڙو انٽرفيس ٺاھينداسين fill(). ان جي مطابق، اهي ڪارٽون جن کي ريفيول ڪرڻ جي ضرورت آهي هن انٽرفيس تي عمل ڪندي، پر ٻيون ڪارٽون (مثال طور، اسان جي بگي) نه ٿيندي. پر هي اختيار به اسان کي مناسب نه ٿيندو. مستقبل ۾ اسان جي طبقي جو درجو تمام وڏي تعداد ۾ وڌي سگھي ٿو (تصور ڪريو ته دنيا ۾ ڪيتريون مختلف قسم جون ڪارون آھن). اسان پوئين ورثي واري اختيار کي ڇڏي ڏنو ڇاڪاڻ ته اسان ان کي ختم ڪرڻ نٿا چاهيون fill(). هتي اسان کي ان کي هر طبقي ۾ لاڳو ڪرڻو پوندو! ڇا جيڪڏهن اسان وٽ انهن مان 50 آهن؟ ۽ جيڪڏهن اسان جي پروگرام ۾ بار بار تبديليون ڪيون وينديون آهن (۽ حقيقي پروگرامن ۾ اهو لڳ ڀڳ هميشه ٿيندو آهي!)، اسان کي پنهنجي زبان کي سڀني 50 طبقن جي وچ ۾ لٽڪائي چوڌاري هلڻو پوندو ۽ انهن مان هر هڪ جي رويي کي دستي طور تي تبديل ڪرڻو پوندو. پوء اسان کي آخر ۾ ڇا ڪرڻ گهرجي؟ اسان جي مسئلي کي حل ڪرڻ لاء، اچو ته هڪ مختلف رستو چونڊيو. يعني اچو ته پنهنجي طبقي جي رويي کي ڪلاس کان الڳ ڪريون. هن جو ڇا مطلب آهي؟ جيئن توهان ڄاڻو ٿا، ڪنهن به شئي جي هڪ رياست آهي (ڊيٽا جو هڪ سيٽ) ۽ هڪ رويي (طريقن جو هڪ سيٽ). اسان جي مشين طبقي جو رويو ٽن طريقن تي مشتمل آهي - gas(), stop()۽ fill(). پهرين ٻه طريقا ٺيڪ آهن. پر اسان ٽئين طريقي کي ڪلاس کان ٻاهر منتقل ڪنداسين Auto. هي ٿيندو ڪلاس کان رويي جي علحدگي (وڌيڪ واضح طور تي، اسان صرف رويي جو حصو الڳ ڪريون ٿا - پهرين ٻه طريقا پنهنجي جاء تي رهن ٿا). اسان کي اسان جو طريقو ڪٿي منتقل ڪرڻ گهرجي fill()؟ ڪجھ به فوري طور تي ذهن ۾ نه ٿو اچي:/ هو مڪمل طور تي پنهنجي جاء تي هو. اسان ان کي هڪ الڳ انٽرفيس ڏانهن منتقل ڪنداسين - FillStrategy!
public interface FillStrategy {

   public void fill();
}
ڇو اسان کي هن انٽرفيس جي ضرورت آهي؟ اهو سادو آهي. ھاڻي اسان ڪيترائي ڪلاس ٺاھي سگھون ٿا جيڪي ھن انٽرفيس کي لاڳو ڪندا:
public class HybridFillStrategy implements FillStrategy {

   @Override
   public void fill() {
       System.out.println("Заправляем бензином or электричеством на выбор!");
   }
}

public class F1PitstopStrategy implements FillStrategy {

   @Override
   public void fill() {
       System.out.println("Заправляем бензин только после всех остальных procedures пит-стопа!");
   }
}

public class StandartFillStrategy implements FillStrategy {
   @Override
   public void fill() {
       System.out.println("Просто заправляем бензин!");
   }
}
اسان ٽن رويي جي حڪمت عمليون ٺاھيون آھن - روايتي ڪارن لاءِ، ھائبرڊز لاءِ ۽ فارمولا 1 ڪارن لاءِ. هر حڪمت عملي هڪ الڳ ريفيولنگ ​​الگورتھم لاڳو ڪري ٿي. اسان جي حالت ۾، اهو صرف ڪنسول ڏانهن ٻاڦ آهي، پر طريقي جي اندر ڪجهه پيچيده منطق ٿي سگهي ٿي. اسان کي هن سان اڳتي ڇا ڪرڻ گهرجي؟
public class Auto {

   FillStrategy fillStrategy;

   public void fill() {
       fillStrategy.fill();
   }

   public void gas() {
       System.out.println("Едем вперед");
   }

   public void stop() {
       System.out.println("Тормозим!");
   }

}
اسان پنھنجي انٽرفيس کي FillStrategyوالدين طبقي ۾ فيلڊ طور استعمال ڪريون ٿا Auto. مهرباني ڪري نوٽ ڪريو: اسان هڪ خاص عمل جي وضاحت نه ڪندا آهيون، بلڪه انٽرفيس استعمال ڪندا آهيون. FillStrategy۽ اسان کي ٻارن جي ڪار ڪلاس ۾ انٽرفيس جي مخصوص عملن جي ضرورت پوندي :
public class F1Car extends Auto {

   public F1Car() {
       this.fillStrategy = new F1PitstopStrategy();
   }
}

public class HybridAuto extends Auto {

   public HybridAuto() {
       this.fillStrategy = new HybridFillStrategy();
   }
}

public class Sedan extends Auto {

   public Sedan() {
       this.fillStrategy = new StandartFillStrategy();
   }
}
اچو ته ڏسو ته اسان کي ڇا مليو:
public class Main {

   public static void main(String[] args) {

       Auto sedan = new Sedan();
       Auto hybrid = new HybridAuto();
       Auto f1car = new F1Car();

       sedan.fill();
       hybrid.fill();
       f1car.fill();
   }
}
ڪنسول آئوٽ:

Просто заправляем бензин!
Заправляем бензином or электричеством на выбор!
Заправляем бензин только после всех остальных procedures пит-стопа!
عظيم، تيل ڀرڻ وارو عمل ڪم ڪري ٿو جيئن ان کي گهرجي! رستي جي ذريعي، ڪجھ به اسان کي حڪمت عملي کي استعمال ڪرڻ کان روڪيو جيئن تعمير ڪندڙ ۾ پيٽرول! مثال طور، هن طرح:
public class Auto {

   private FillStrategy fillStrategy;

   public Auto(FillStrategy fillStrategy) {
       this.fillStrategy = fillStrategy;
   }

   public void fill() {
       this.fillStrategy.fill();
   }

   public void gas() {
       System.out.println("Едем вперед");
   }

   public void stop() {
       System.out.println("Тормозим!");
   }
}

public class Sedan extends Auto {

   public Sedan() {
       super(new StandartFillStrategy());
   }
}



public class HybridAuto extends Auto {

   public HybridAuto() {
       super(new HybridFillStrategy());
   }
}

public class F1Car extends Auto {

   public F1Car() {
       super(new F1PitstopStrategy());
   }
}
اچو ته اسان جي طريقي کي هلون main()(اهو اڻڄاتل رهي ٿو) ۽ ساڳيو نتيجو حاصل ڪريو! ڪنسول آئوٽ:

Просто заправляем бензин!
Заправляем бензином or электричеством на выбор!
Заправляем бензин только после всех остальных procedures пит-стопа!
حڪمت عملي جو نمونو الگورتھم جي ھڪڙي خاندان کي بيان ڪري ٿو، انھن مان ھر ھڪ کي گڏ ڪري ٿو، ۽ يقيني بڻائي ٿو ته اھي مٽائي سگھندا آھن. اهو توهان کي اجازت ڏئي ٿو ته الورورٿمز کي تبديل ڪرڻ جي بغير انهن جي ڪلائنٽ پاسي جي استعمال کان سواء (هي تعريف ڪتاب مان ورتو ويو آهي "Exploring Design Patterns" ۽ مون کي انتهائي ڪامياب لڳي ٿو). ڊيزائن جو نمونو ”حڪومتي“ - 4اسان الگورتھم جي خاندان کي الڳ ڪري ڇڏيو آھي جيڪي اسان کي دلچسپي ڏين ٿا (ڪارن جي ريفيولنگ ​​جا قسم) ڪيترن ئي عملن سان الڳ الڳ انٽرفيس ۾. اسان انهن کي ڪار جي بلڪل جوهر کان الڳ ڪري ڇڏيو آهي. تنهن ڪري، هاڻي، جيڪڏهن اسان کي ڪنهن به تبديلي ڪرڻ جي ضرورت آهي ته هن يا انهي کي تيل ڀرڻ واري عمل ۾، اهو اسان جي ڪارن جي طبقن کي ڪنهن به طريقي سان متاثر نه ڪندو. جيئن مٽاسٽا جي لاءِ، ان کي حاصل ڪرڻ لاءِ اسان کي صرف هڪ سيٽر طريقو شامل ڪرڻو پوندو اسان جي ڪلاس ۾ Auto:
public class Auto {

   FillStrategy fillStrategy;

   public void fill() {
       fillStrategy.fill();
   }

   public void gas() {
       System.out.println("Едем вперед");
   }

   public void stop() {
       System.out.println("Тормозим!");
   }

   public void setFillStrategy(FillStrategy fillStrategy) {
       this.fillStrategy = fillStrategy;
   }
}
هاڻي اسان اڏامي تي حڪمت عمليون تبديل ڪري سگهون ٿا:
public class Main {

   public static void main(String[] args) {

       ChildrenBuggies buggies = new ChildrenBuggies();
       buggies.setFillStrategy(new StandartFillStrategy());

       buggies.fill();
   }
}
جيڪڏهن اوچتو ٻارن جون بگي ڪارون پيٽرول سان ڀرڻ شروع ٿيون، اسان جو پروگرام اهڙي منظر لاء تيار ٿي ويندو :) اهو سڀ ڪجهه، حقيقت ۾! توهان هڪ ٻيو ڊزائن جو نمونو سکيو آهي، جنهن جي توهان کي بلاشڪ ضرورت پوندي ۽ حقيقي منصوبن تي ڪم ڪرڻ دوران توهان کي هڪ ڀيرو کان وڌيڪ مدد ملندي :) توهان سان ٻيهر ملن ٿا!
تبصرا
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION