JavaRush /جاوا بلاگ /Random-SD /جاوا ۾ ڪلاس ڊيزائن جا پنج بنيادي اصول (SOLID).
Ve4niY
سطح

جاوا ۾ ڪلاس ڊيزائن جا پنج بنيادي اصول (SOLID).

گروپ ۾ شايع ٿيل
ڪلاس اهي بلاڪ آهن جن مان ايپليڪيشن ٺاهي وئي آهي. بلڊنگ ۾ سرن وانگر. خراب لکيل ڪلاس هڪ ڏينهن مسئلا پيدا ڪري سگهن ٿا. جاوا ۾ ڪلاس ڊيزائن جا پنج بنيادي اصول (SOLID) - 1سمجھڻ لاءِ ته ڇا ڪو ڪلاس صحيح لکيو ويو آھي، توھان چيڪ ڪري سگھو ٿا ”معياري معيار“. جاوا ۾، اهي نام نهاد SOLID اصول آهن. اچو ته انهن بابت ڳالهايون.

جاوا ۾ SOLID اصول

SOLID هڪ مخفف آهي جيڪو OOP ۽ ڊيزائن جي پهرين پنجن اصولن جي وڏن اکرن مان ٺهيل آهي. اصول 2000 جي شروعات ۾ رابرٽ مارٽن پاران ايجاد ڪيا ويا، ۽ مخفف بعد ۾ مائيڪل فيدرز پاران ٺهرايو ويو. ھتي آھي جيڪي SOLID اصولن ۾ شامل آھن:
  1. اڪيلو ذميواري اصول.
  2. کليل بند اصول.
  3. Liskov جي متبادل جو اصول.
  4. انٽرفيس الڳ ڪرڻ جو اصول.
  5. انحصار جي ڦيرڦار جو اصول.

اڪيلو ذميواري اصول (SRP)

اهو اصول ٻڌائي ٿو ته ڪنهن به طبقي کي تبديل ڪرڻ لاءِ هڪ کان وڌيڪ سبب نه هجڻ گهرجن. هر شئي هڪ ذميواري آهي، مڪمل طور تي هڪ طبقي ۾ ڍڪيل آهي. سڀني طبقاتي خدمتن جو مقصد هن ذميواري کي يقيني بڻائڻ آهي. جيڪڏهن ضروري هجي ته اهڙن طبقن کي تبديل ڪرڻ ۾ هميشه آسان ٿي ويندي، ڇاڪاڻ ته اهو واضح آهي ته اهو طبقو ڪهڙو ذميوار آهي ۽ ڇا نه آهي. اهو آهي، اهو ممڪن ٿيندو ته تبديليون ڪرڻ ۽ نتيجن کان ڊڄو نه - ٻين شين تي اثر. ۽ اهڙي ڪوڊ کي جانچڻ تمام آسان آهي، ڇاڪاڻ ته توهان هڪ ڪارڪردگي کي ٻين سڀني کان الڳ ڪرڻ ۾ ٽيسٽ سان ڍڪيندا آهيو. تصور ڪريو ھڪڙو ماڊل جيڪو عمل ڪري ٿو آرڊر. جيڪڏهن آرڊر صحيح طرح ٺهيل آهي، اهو ان کي ڊيٽابيس ۾ محفوظ ڪري ٿو ۽ آرڊر جي تصديق ڪرڻ لاء هڪ اي ميل موڪلي ٿو:
public class OrderProcessor {

    public void process(Order order){
        if (order.isValid() && save(order)) {
            sendConfirmationEmail(order);
        }
    }

    private boolean save(Order order) {
        MySqlConnection connection = new MySqlConnection("database.url");
        // save the order to the database

        return true;
    }

    private void sendConfirmationEmail(Order order) {
        String name = order.getCustomerName();
        String email = order.getCustomerEmail();

        // Sending a letter to the client
    }
}
اهڙو ماڊل ٽن سببن جي ڪري تبديل ٿي سگهي ٿو. پهرين، آرڊر پروسيسنگ منطق مختلف ٿي سگهي ٿي، ٻيو، ان کي محفوظ ڪرڻ جو طريقو (ڊيٽابيس جو قسم)، ٽيون، هڪ تصديق واري خط موڪلڻ جو طريقو (مثال طور، اي ميل جي بدران توهان کي ايس ايم ايس موڪلڻ جي ضرورت آهي). اڪيلو ذميواري اصول جو مطلب آهي ته هن مسئلي جا ٽي پهلو اصل ۾ ٽي مختلف ذميواريون آهن. هن جو مطلب آهي ته اهي مختلف طبقن يا ماڊلز ۾ هجن. ڪيترن ئي ادارن کي گڏ ڪرڻ جيڪي مختلف وقتن تي تبديل ٿي سگهن ٿا ۽ مختلف سببن لاءِ خراب ڊيزائن جو فيصلو سمجهيو ويندو آهي. اهو بهتر آهي ته ماڊل کي ٽن جدا جدا حصن ۾ ورهايو وڃي، جن مان هر هڪ هڪ واحد فنڪشن انجام ڏيندو:
public class MySQLOrderRepository {
    public boolean save(Order order) {
        MySqlConnection connection = new MySqlConnection("database.url");
        // save the order to the database

        return true;
    }
}

public class ConfirmationEmailSender {
    public void sendConfirmationEmail(Order order) {
        String name = order.getCustomerName();
        String email = order.getCustomerEmail();

        // Sending a letter to the client
    }
}

public class OrderProcessor {
    public void process(Order order){

        MySQLOrderRepository repository = new MySQLOrderRepository();
        ConfirmationEmailSender mailSender = new ConfirmationEmailSender();

        if (order.isValid() && repository.save(order)) {
            mailSender.sendConfirmationEmail(order);
        }
    }

}

کليل/بند اصول (OCP)

اهو اصول مختصر طور تي هن ريت بيان ڪيو ويو آهي: سافٽ ويئر ادارن (ڪلاس، ماڊل، فنڪشن، وغيره) کي وڌائڻ لاء کليل هجڻ گهرجي، پر تبديلي لاء بند ڪيو وڃي . هن جو مطلب اهو آهي ته اهو ممڪن آهي ته ڪنهن طبقي جي خارجي رويي کي تبديل ڪرڻ بغير جسماني تبديلين جي پاڻ ۾. هن اصول تي عمل ڪندي، ڪلاس ٺاهيا ويا آهن ته جيئن طبقي کي مخصوص ايپليڪيشن جي حالتن سان ترتيب ڏيڻ لاء، اهو ڪافي آهي ته ان کي وڌائڻ ۽ ڪجهه ڪمن کي ٻيهر بيان ڪرڻ لاء. تنهن ڪري، سسٽم کي لچڪدار هجڻ گهرجي، ماخذ ڪوڊ کي تبديل ڪرڻ کان سواء متغير حالتن ۾ ڪم ڪرڻ جي قابل. اسان جي آرڊر جي مثال سان اڳتي وڌو، اچو ته چئو ته اسان کي ڪجهه عمل ڪرڻ جي ضرورت آهي آرڊر تي عمل ٿيڻ کان اڳ ۽ تصديق واري اي ميل موڪلڻ کان پوء. ڪلاس کي تبديل ڪرڻ بدران OrderProcessor، اسان ان کي وڌائينداسين ۽ او سي پي اصول جي ڀڃڪڙي ڪرڻ کان سواءِ هٿ ۾ موجود مسئلي جو حل حاصل ڪنداسين:
public class OrderProcessorWithPreAndPostProcessing extends OrderProcessor {

    @Override
    public void process(Order order) {
        beforeProcessing();
        super.process(order);
        afterProcessing();
    }

    private void beforeProcessing() {
        // Perform some actions before processing the order
    }

    private void afterProcessing() {
        // Perform some actions after order processing
    }
}

باربرا ليسڪوف متبادل اصول (LSP)

هي کليل/بند اصول جو هڪ فرق آهي جنهن تي اڳ ۾ بحث ڪيو ويو آهي. اهو هن ريت بيان ڪري سگهجي ٿو: هڪ پروگرام ۾ شيون انهن جي وارثن طرفان تبديل ٿي سگهن ٿيون بغير پروگرام جي ملڪيت کي تبديل ڪرڻ جي. هن جو مطلب اهو آهي ته هڪ بنيادي طبقي کي وڌائڻ سان ترقي يافته طبقي کي لازمي طور تي ان جي طريقن کي ختم ڪرڻ گهرجي جيڪو ڪلائنٽ جي نقطي نظر کان ڪارڪردگي کي ٽوڙي نٿو سگهي. اهو آهي، جيڪڏهن هڪ ڊولپر توهان جي ڪلاس کي وڌائي ٿو ۽ ان کي ايپليڪيشن ۾ استعمال ڪري ٿو، هن کي ختم ٿيل طريقن جي متوقع رويي کي تبديل نه ڪرڻ گهرجي. ذيلي طبقن کي لازمي طور تي بنيادي طبقي جي طريقن کي ختم ڪرڻ گهرجي، جيڪو ڪلائنٽ جي نقطي نظر کان ڪارڪردگي کي ٽوڙي نٿو سگهي. اهو هيٺ ڏنل مثال استعمال ڪندي تفصيل سان جانچي سگهجي ٿو. اچو ته فرض ڪريو اسان وٽ ھڪڙو ڪلاس آھي جيڪو آرڊر جي تصديق لاءِ ذميوار آھي ۽ چيڪ ڪري ٿو ته ڇا آرڊر جون سڀئي شيون اسٽاڪ ۾ آھن. ھن طبقي ۾ ھڪڙو طريقو آھي isValidجيڪو موٽائي ٿو صحيح يا غلط :
public class OrderStockValidator {

    public boolean isValid(Order order) {
        for (Item item : order.getItems()) {
            if (! item.isInStock()) {
                return false;
            }
        }

        return true;
    }
}
اچو ته اهو پڻ فرض ڪريون ته ڪجهه آرڊر کي مختلف طور تي تصديق ڪرڻ جي ضرورت آهي: چيڪ ڪريو ته ڇا آرڊر ۾ سڀ سامان اسٽاڪ ۾ آهن ۽ ڇا سڀئي سامان پيڪيج ٿيل آهن. هن کي ڪرڻ لاء، اسان OrderStockValidatorڪلاس سان ڪلاس وڌايو OrderStockAndPackValidator:
public class OrderStockAndPackValidator extends OrderStockValidator {

    @Override
    public boolean isValid(Order order) {
        for (Item item : order.getItems()) {
            if ( !item.isInStock() || !item.isPacked() ){
                throw new IllegalStateException(
                     String.format("Order %d is not valid!", order.getId())
                );
            }
        }

        return true;
    }
}
بهرحال، هن طبقي ۾ اسان LSP اصول جي ڀڃڪڙي ڪئي، ڇاڪاڻ ته غلط موٽڻ جي بدران جيڪڏهن آرڊر جي تصديق نه ڪئي وئي، اسان جو طريقو هڪ استثنا ڏئي ٿو IllegalStateException. هن ڪوڊ جا گراهڪ هن جي توقع نٿا ڪن: اهي سچا يا غلط موٽڻ جي اميد رکندا آهن . اهو ٿي سگهي ٿو پروگرام ۾ غلطيون.

انٽرفيس ورهائڻ جو اصول (ISP)

هيٺ ڏنل بيان جي خاصيت: ڪلائنٽ کي مجبور نه ڪيو وڃي ته اهي طريقا لاڳو ڪن جيڪي اهي استعمال نه ڪندا . انٽرفيس جي علحدگيءَ جو اصول ٻڌائي ٿو ته انٽرفيس جيڪي ڏاڍا ”ٿلها“ هوندا آهن انهن کي ننڍڙن ۽ وڌيڪ مخصوص حصن ۾ ورهائڻ جي ضرورت آهي، ته جيئن ننڍڙن انٽرفيس جا گراهڪ صرف انهن جي ڪم لاءِ ضروري طريقن جي باري ۾ ڄاڻن. نتيجي طور، جڏهن هڪ انٽرفيس جو طريقو تبديل ڪندي، ڪلائنٽ جيڪي هن طريقي کي استعمال نٿا ڪن، انهن کي تبديل نه ڪرڻ گهرجي. اچو ته هڪ مثال ڏسو. ڊولپر ايڪس "رپورٽ" انٽرفيس ٺاهي ۽ ٻه طريقا شامل ڪيا: generateExcel()۽ generatedPdf(). ھاڻي ڪلائنٽ A ھن انٽرفيس کي استعمال ڪرڻ گھري ٿو، پر ھو صرف پي ڊي ايف رپورٽون استعمال ڪرڻ جو ارادو رکي ٿو ۽ Excel نه. ڇا هو هن ڪارڪردگيءَ سان مطمئن هوندو؟ نه. هن کي ٻن طريقن تي عمل ڪرڻو پوندو، جن مان هڪ گهڻو ڪري غير ضروري آهي ۽ موجود آهي صرف Alex جي مهرباني، سافٽ ويئر ڊزائينر. ڪلائنٽ يا ته مختلف انٽرفيس استعمال ڪندو يا ايڪسل فيلڊ کي خالي ڇڏيندو. پوءِ ان جو حل ڇا آهي؟ اهو موجوده انٽرفيس کي ٻن ننڍن ۾ ورهائڻ تي مشتمل آهي. هڪ پي ڊي ايف فارميٽ ۾ رپورٽ آهي، ٻي ايڪسل فارميٽ ۾ رپورٽ آهي. اهو صارف کي صرف ان لاء ضروري ڪارڪردگي استعمال ڪرڻ جو موقعو ڏيندو.

انحصار جي ڦيرڦار جو اصول (DIP)

جاوا ۾ اهو SOLID اصول هن ريت بيان ڪيو ويو آهي: سسٽم جي اندر انحصار خلاصن جي بنياد تي ٺهيل آهن . مٿين سطح جا ماڊل هيٺين سطح جي ماڊلز کان آزاد آهن. خلاصو تفصيل تي منحصر نه هجڻ گهرجي. تفصيلات لازمي طور تي خلاصن تي منحصر آهن. سافٽ ويئر کي ڊزائين ڪرڻ جي ضرورت آهي ته جيئن مختلف ماڊل خودمختيار آهن ۽ تجزيه استعمال ڪندي هڪ ٻئي سان ڳنڍيل آهن. هن اصول جي هڪ کلاسک درخواست بهار فريم ورڪ آهي. بهار جي فريم ورڪ جي اندر، سڀئي ماڊلز الڳ الڳ اجزاء طور لاڳو ڪيا ويا آهن جيڪي گڏجي ڪم ڪري سگهن ٿيون. اهي ايترو ته خود مختيار آهن ته اهي بهار جي فريم ورڪ کان علاوه ٻين سافٽ ويئر ماڊلز ۾ آساني سان استعمال ڪري سگھجن ٿيون. اهو حاصل ٿئي ٿو بند ۽ کليل اصولن جي انحصار ذريعي. سڀئي ماڊلز صرف هڪ خلاصي تائين رسائي فراهم ڪن ٿيون جيڪي ٻئي ماڊل ۾ استعمال ڪري سگھجن ٿيون. اچو ته ان کي هڪ مثال سان ڏيکارڻ جي ڪوشش ڪريون. اڪيلي ذميواري جي اصول جي باري ۾ ڳالهائيندي، اسان ڪجهه غور ڪيو OrderProcessor. اچو ته هن ڪلاس جي ڪوڊ تي هڪ ٻيو نظر وجهون:
public class OrderProcessor {
    public void process(Order order){

        MySQLOrderRepository repository = new MySQLOrderRepository();
        ConfirmationEmailSender mailSender = new ConfirmationEmailSender();

        if (order.isValid() && repository.save(order)) {
            mailSender.sendConfirmationEmail(order);
        }
    }

}
هن مثال ۾، اسان جو OrderProcessorدارومدار ٻن مخصوص طبقن تي آهي MySQLOrderRepository۽ ConfirmationEmailSender. اسان انهن ڪلاسن لاءِ ڪوڊ پڻ پيش ڪريون ٿا:
public class MySQLOrderRepository {
    public boolean save(Order order) {
        MySqlConnection connection = new MySqlConnection("database.url");
        // save the order to the database

        return true;
    }
}

public class ConfirmationEmailSender {
    public void sendConfirmationEmail(Order order) {
        String name = order.getCustomerName();
        String email = order.getCustomerEmail();

        // Sending a letter to the client
    }
}
اهي طبقا تجريد سڏجڻ کان پري آهن. ۽ DIP اصول جي نقطي نظر کان، اهو وڌيڪ صحيح ٿيندو ته ڪجهه تجريد ٺاهڻ سان شروع ڪيو وڃي جيڪي اسان کي مستقبل ۾ انهن سان هلائڻ جي اجازت ڏين، بلڪه مخصوص عملن سان. اچو ته ٻه انٽرفيس ٺاهيون MailSender۽ OrderRepository, جيڪي اسان جا تجريد بڻجي ويندا:
public interface MailSender {
    void sendConfirmationEmail(Order order);
}

public interface OrderRepository {
    boolean save(Order order);
}
ھاڻي اچو ته انھن انٽرفيس کي ڪلاسن ۾ لاڳو ڪريون جيڪي اڳ ۾ ئي ھن لاءِ تيار آھن:
public class ConfirmationEmailSender implements MailSender {

    @Override
    public void sendConfirmationEmail(Order order) {
        String name = order.getCustomerName();
        String email = order.getCustomerEmail();

        // Sending a letter to the client
    }

}

public class MySQLOrderRepository implements OrderRepository {

    @Override
    public boolean save(Order order) {
        MySqlConnection connection = new MySqlConnection("database.url");
        // save the order to the database

        return true;
    }
}
اسان تياري وارو ڪم ڪيو آهي ته جيئن اسان جو ڪلاس OrderProcessorڪنڪريٽ تفصيلن تي نه، پر تجريد تي منحصر هجي. اچو ته ان ۾ تبديليون آڻيون ڪلاس ڪنسٽرڪٽر ۾ اسان جي انحصار کي متعارف ڪرائڻ سان:
public class OrderProcessor {

    private MailSender mailSender;
    private OrderRepository repository;

    public OrderProcessor(MailSender mailSender, OrderRepository repository) {
        this.mailSender = mailSender;
        this.repository = repository;
    }

    public void process(Order order){
        if (order.isValid() && repository.save(order)) {
            mailSender.sendConfirmationEmail(order);
        }
    }
}
اسان جو طبقو هاڻي ڪنڪريٽ تي عمل ڪرڻ بجاءِ تجريد تي منحصر آهي. توهان آساني سان ان جي رويي کي تبديل ڪري سگهو ٿا مطلوب انحصار کي انجيڪشن ڪندي ان وقت جڏهن مثال ٺاهي وئي آهي OrderProcessor. اسان جاوا ۾ SOLID - ڊيزائن جا اصول نظر آيا. عام طور تي OOP جي باري ۾ وڌيڪ، هن پروگرامنگ ٻولي جي بنياديات - نه بورنگ ۽ سوين ڪلاڪن جي مشق سان - JavaRush ڪورس ۾. ڪجهه مسئلا حل ڪرڻ جو وقت :) جاوا ۾ ڪلاس ڊيزائن جا پنج بنيادي اصول (SOLID) - 2
تبصرا
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION