JavaRush /جاوا بلاگ /Random-UR /بہار سبق 2. عملی طور پر IoC/DI
Umaralikhon
سطح
Красноярск

بہار سبق 2. عملی طور پر IoC/DI

گروپ میں شائع ہوا۔
اور اسی طرح... پچھلے سبق میں ہم نے مختصر طور پر IoC اور DI کے نظریاتی حصے کا جائزہ لیا۔ ہم نے اپنے پروجیکٹ کے لیے pom.xml کنفیگریشن فائل بھی ترتیب دی ہے۔ آج ہم پروگرام کا مرکزی حصہ بنانا شروع کرتے ہیں۔ سب سے پہلے، میں آپ کو دکھاؤں گا کہ IoC/DI کے بغیر پروگرام کیسے بنایا جائے۔ اور پھر ہم براہ راست ایک پروگرام بنائیں گے جو آزادانہ طور پر انحصار کو متعارف کرائے گا۔ یعنی، کوڈ کا کنٹرول فریم ورک کے ہاتھ میں چلا جاتا ہے (ڈراونا لگتا ہے)۔ جب ہم پروگرام کا انتظام کر رہے ہیں، تصور کریں کہ کوئی خاص کمپنی ہے۔ اور کمپنی (ابھی کے لیے) کے دو شعبے ہیں: جاوا ڈویلپمنٹ اور ہائرنگ ڈیپارٹمنٹ۔ "جاوا ڈویلپمنٹ ڈیپارٹمنٹ" کو بیان کرنے والی کلاس کے پاس دو طریقے ہیں: String getName() - ملازم کا نام واپس کرنا، String getJob() - ملازم کی پوزیشن واپس کرنا۔ (فہرست 1)
package org.example;

public class JavaDevelopment {

    public String getName(){
        return "Alexa";
    }

    public String getJob(){
        return "Middle Java developer";
    }
}
ہائرنگ ڈپارٹمنٹ کی وضاحت کرنے والی کلاس کے پاس ایک ان پٹ کنسٹرکٹر ہے جو ملازم کو قبول کرتا ہے، اور ایک void displayInfo() طریقہ جو ملازمین کے بارے میں معلومات ظاہر کرتا ہے۔ (فہرست 2)
package org.example;

public class HiringDepartment {
    private JavaDevelopment javaDevelopment;

    public HiringDepartment(JavaDevelopment javaDevelopment) {
        this.javaDevelopment = javaDevelopment;
    }

    public void displayInfo() {
        System.out.println("Name: " + javaDevelopment.getName());
        System.out.println("Job: " + javaDevelopment.getJob());
    }
}
مین بھی ہے - ایک کلاس جو تمام محکموں کا انتظام کرتی ہے۔ (فہرست 3)
package org.example;

public class Main {
    public static void main(String ... args){
        JavaDevelopment javaDevelopment = new JavaDevelopment();
        HiringDepartment hiringDepartment = new HiringDepartment(javaDevelopment);

        hiringDepartment.displayInfo();
    }
}
ابھی کے لیے استحکام۔ جب ہم مین کلاس چلاتے ہیں تو ہمیں درج ذیل نتیجہ ملتا ہے:
Name: Alexa
Job: Middle Java developer
اب تصور کریں کہ کمپنی بہت اچھا کام کر رہی ہے۔ لہذا، انہوں نے اپنی سرگرمیوں کے دائرہ کار کو بڑھانے کا فیصلہ کیا اور ایک ازگر کی ترقی کا شعبہ کھولا۔ اور یہاں سوال یہ پیدا ہوتا ہے کہ اس شعبہ کو پروگرام کی سطح پر کیسے بیان کیا جائے؟ جواب: جہاں بھی آپ کو اس شعبہ کی وضاحت کرنے کی ضرورت ہے وہاں آپ کو "کاپی اور پیسٹ" کرنے کی ضرورت ہے (اچھا پرانا طریقہ🙃)۔ پہلے، آئیے خود کلاس بنائیں، جو "Pythonists" ڈیپارٹمنٹ کو بیان کرے گا۔ (فہرست 4)
package org.example;

public class PythonDevelopment {
    public String getName(){
        return "Mike";
    }

    public String getJob(){
        return "Middle Python developer";
    }
}
اور پھر ہم اسے ہائرنگ ڈیپارٹمنٹ میں منتقل کر دیں گے۔ اور HiringDepartment اس محکمہ کے بارے میں کچھ نہیں کہتا۔ لہذا، آپ کو PythonDevelopment کلاس کا ایک نیا آبجیکٹ اور ایک کنسٹرکٹر بنانا ہو گا جو Python ڈویلپرز کو قبول کرے۔ آپ کو displayInfo() طریقہ کو بھی تبدیل کرنا پڑے گا تاکہ یہ معلومات کو صحیح طریقے سے دکھائے۔ (فہرست 5)
package org.example;

public class HiringDepartment {
    private JavaDevelopment javaDevelopment;

    public HiringDepartment(JavaDevelopment javaDevelopment) {
        this.javaDevelopment = javaDevelopment;
    }


    //Тут создается отдел найма для Python - разработчиков
    private PythonDevelopment pythonDevelopment;

    public HiringDepartment(PythonDevelopment pythonDevelopment) {
        this.pythonDevelopment = pythonDevelopment;
    }

    //Тогда придется изменить метод displayInfo()
    public void displayInfo() {
        if(javaDevelopment != null) {
            System.out.println("Name: " + javaDevelopment.getName());
            System.out.println("Job: " + javaDevelopment.getJob());
        } else if (pythonDevelopment != null){
            System.out.println("Name: " + pythonDevelopment.getName());
            System.out.println("Job: " + pythonDevelopment.getJob());
        }
    }
}
جیسا کہ ہم دیکھ سکتے ہیں، کوڈ کا حجم دوگنا، یا اس سے بھی زیادہ ہو گیا ہے۔ کوڈ کی ایک بڑی مقدار کے ساتھ، اس کی پڑھنے کی اہلیت کم ہو جاتی ہے۔ اور سب سے بری بات یہ ہے کہ ہم تمام اشیاء کو دستی طور پر بناتے ہیں اور ایسی کلاسیں بناتے ہیں جو ایک دوسرے پر بہت زیادہ انحصار کرتی ہیں۔ ٹھیک ہے، ہم نے اس سے اتفاق کیا۔ انہوں نے صرف ایک شعبہ بیان کیا۔ ہم اس سے کچھ نہیں کھویں گے۔ ٹھیک ہے، اگر ہم ایک اور محکمہ شامل کریں تو کیا ہوگا؟ اگر دو ہیں تو کیا ہوگا؟ تین؟ لیکن کسی نے بھی "کان کنی اور چرنے" سے منع نہیں کیا۔ بہار  سبق 2. عملی طور پر IoC/DI - 1 ہاں، کسی نے "میرا اور چراگاہ" کو منع نہیں کیا، لیکن یہ پیشہ ورانہ نہیں ہے۔ Tyzh ایک پروگرامر ہے۔ اور یہاں آپ DI استعمال کر سکتے ہیں۔ یعنی ہم کلاس کی سطح پر نہیں بلکہ انٹرفیس کی سطح پر کام کریں گے۔ اب ہماری اشیاء کی حالتیں انٹرفیس میں محفوظ کی جائیں گی۔ اس طرح، کلاسوں کے درمیان انحصار کم سے کم ہوگا۔ ایسا کرنے کے لیے، ہم سب سے پہلے ڈیولپمنٹ انٹرفیس بناتے ہیں، جس میں ملازم کو بیان کرنے کے دو طریقے ہیں۔ (فہرست 6)
package org.example;

public interface Development {
    String getName();
    String getJob();
}
اس کے بعد اس انٹرفیس سے دو کلاسوں جاوا ڈیولپمنٹ اور پائتھون ڈیولپمنٹ کو لاگو (وراثت) کرنے دیں اور String getName() اور String getJob() کے طریقوں کو اوور رائیڈ کریں۔ (فہرست 7، 8)
package org.example;

public class JavaDevelopment implements Development {
    @Override
    public String getName(){
        return "Alexa";
    }

    @Override
    public String getJob(){
        return "Middle Java developer";
    }
}
package org.example;

public class PythonDevelopment implements Development {
    @Override
    public String getName(){
        return "Mike";
    }

    @Override
    public String getJob(){
        return "Middle Python developer";
    }
}
پھر HiringDepartment کلاس میں آپ آسانی سے ترقی کی قسم کے ایک انٹرفیس آبجیکٹ کی وضاحت کر سکتے ہیں اور آپ ایسی چیز کو کنسٹرکٹر کو بھی دے سکتے ہیں۔ (فہرست 9)
package org.example;

public class HiringDepartment {
    private Development development; //Определяем интерфейс

    //Конструктор принимает an object интерфейса
    public HiringDepartment(Development development){
        this.development = development;
    }

    public void displayInfo(){
        System.out.println("Name: " + development.getName());
        System.out.println("Job: " + development.getJob());
    }
}
جیسا کہ ہم دیکھ سکتے ہیں، کوڈ کی مقدار کم ہو گئی ہے۔ اور سب سے اہم بات یہ ہے کہ انحصار کو کم کیا گیا۔ ان اشیاء کے لیے اقدار اور انحصار کو اصل میں کیسے لاگو کیا جاتا ہے؟ انحصار انجکشن کرنے کے تین طریقے ہیں:
  • کنسٹرکٹر کا استعمال کرتے ہوئے
  • سیٹرز کا استعمال
  • آٹو وائرنگ (خودکار بائنڈنگ)
کنسٹرکٹر کا استعمال کرتے ہوئے نفاذ اب آئیے کنسٹرکٹر کا استعمال کرتے ہوئے عمل درآمد کے بارے میں بات کرتے ہیں۔ لسٹنگ 9 کو دیکھیں۔ HiringDepartment کلاس کا کنسٹرکٹر ان پٹ کے طور پر ڈویلپمنٹ کی قسم کی کسی چیز کی توقع کرتا ہے۔ ہم اس کنسٹرکٹر کے ذریعے انحصار کو انجیکشن لگانے کی کوشش کریں گے۔ یہ بھی قابل غور ہے کہ انحصار انجیکشن نام نہاد بہار کنٹینرز کا استعمال کرتے ہوئے انجام دیا جاتا ہے۔ بہار کے کنٹینرز کو ترتیب دینے کے تین طریقے ہیں:
  • XML فائلوں کا استعمال (پرانا طریقہ)
  • تشریحات + XML فائلوں کا استعمال (جدید طریقہ)
  • جاوا کوڈ کا استعمال (جدید طریقہ)
اب ہم XML فائلوں کا استعمال کرتے ہوئے کنفیگریشن استعمال کر رہے ہیں۔ اس حقیقت کے باوجود کہ یہ طریقہ پرانا سمجھا جاتا ہے، بہت سے منصوبے اب بھی اسی طرح لکھے جاتے ہیں۔ اس لیے آپ کو جاننے کی ضرورت ہے۔ سب سے پہلے، آپ کو وسائل کے فولڈر میں ایک xML فائل بنانا ہوگی۔ آپ اسے کوئی بھی نام دے سکتے ہیں، لیکن ترجیحا ایک معنی خیز۔ میں نے اسے "applicationContext.xml" کہا۔ بہار  سبق 2. عملی طور پر IoC/DI - 2 اس فائل میں ہم درج ذیل کوڈ لکھیں گے ( لسٹنگ 10):
<?xml version="1.0" encoding="UTF-8"?>
<beans  xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <bean id="javaDeveloper" class="org.example.JavaDevelopment"/>
    <bean id="pythonDeveloper" class="org.example.PythonDevelopment"/>

    <bean id="hiringDepartment" class="org.example.HiringDepartment">
        <constructor-arg ref="javaDeveloper"/>
    </bean>

</beans>
اب، ترتیب میں. کوڈ کی پہلی آٹھ لائنیں ہمارے لیے دلچسپ نہیں ہیں، وہ پہلے سے طے شدہ ہیں۔ آپ انہیں آسانی سے کاپی کر سکتے ہیں۔ <bean> </bean> ٹیگ اسپرنگ بین کی وضاحت کرتا ہے۔ بین ایک ایسی چیز ہے جو اسپرنگ کنٹینر کے ذریعہ بنائی اور منظم کی جاتی ہے۔ سادہ الفاظ میں، اسپرنگ کنٹینر خود ہمارے لیے ایک نیا کلاس آبجیکٹ بناتا ہے (مثال کے طور پر: JavaDevelopment javaDevelopment = new JavaDevelopment();)۔ اس ٹیگ کے اندر id اور class کی خصوصیات ہیں۔ id بین کا نام بتاتا ہے۔ اس آئی ڈی کو آبجیکٹ تک رسائی کے لیے استعمال کیا جائے گا۔ یہ جاوا کلاس میں کسی شے کے نام کے برابر ہے۔ کلاس - اس کلاس کے نام کی وضاحت کرتا ہے جس سے ہماری بین (آبجیکٹ) پابند ہے۔ آپ کو کلاس کا پورا راستہ بتانا ہوگا۔ ہائرنگ ڈپارٹمنٹ بین پر توجہ دیں۔ اس بین کے اندر ایک اور <constructor-arg ref="javaDeveloper"/> ٹیگ ہے۔ یہ وہ جگہ ہے جہاں انحصار انجیکشن ہوتا ہے (ہمارے معاملے میں ، کنسٹرکٹر کا استعمال کرتے ہوئے انجیکشن)۔ <constructor-arg> - اسپرنگ کو بتاتا ہے کہ اسپرنگ کنٹینر کو بین وصف میں بیان کردہ کلاس کنسٹرکٹر میں انحصار تلاش کرنا چاہیے۔ اور کس چیز کے ساتھ منسلک ہونے کی ضرورت ہے اس کا تعین <constructor-arg> ٹیگ کے اندر ref انتساب سے ہوتا ہے۔ ref - رابطہ کرنے والی بین کی شناخت کی نشاندہی کرتا ہے۔ اگر ref میں javaDeveloper کے بجائے ہم id pythonDeveloper کی وضاحت کرتے ہیں، تو کنکشن PythonDevelopmen کلاس کے ساتھ ہوتا ہے۔ اب ہمیں مین کلاس کو بیان کرنے کی ضرورت ہے۔ یہ اس طرح نظر آئے گا: (فہرست 11)
package org.example;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {
    public static void main(String ... args){
        //Определяем контекст файл в котором содержатся прописанные нами бины
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

        //Получем бины, которые были определены в файле applicationContext.xml
        HiringDepartment hiringDepartment = context.getBean("hiringDepartment", HiringDepartment.class);

        hiringDepartment.displayInfo();

        context.close(); //Контекст всегда должен закрываться
    }
}
یہاں کیا ہے؟
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
یہ لائن مین کلاس کو .xml فائل سے جوڑتی ہے جو ہماری پھلیاں بیان کرتی ہے۔ کنسٹرکٹر کو بھیجی گئی قیمت .xml فائل کے نام سے مماثل ہونی چاہیے۔ (ہمارے معاملے applicationContext.xml میں)۔
HiringDepartment hiringDepartment = context.getBean("hiringDepartment", HiringDepartment.class);
اشارہ کرتا ہے کہ ہم HiringDepartment کلاس کی بین (آبجیکٹ) حاصل کرنا چاہتے ہیں۔ پہلی دلیل بین آئی ڈی کی طرف اشارہ کرتی ہے جو ہم نے xML فائل میں لکھی ہے۔ دوسری دلیل اس کلاس کی طرف اشارہ کرتی ہے جس سے ہم رابطہ کرنا چاہتے ہیں۔ اس عمل کو عکاسی کہتے ہیں ۔
hiringDepartment.displayInfo();
 context.close(); //Контекст всегда должен закрываться
یہاں ہمیں ہائرنگ ڈیپارٹمنٹ کلاس کا طریقہ آسانی سے ملتا ہے۔ نوٹ کریں کہ ہم نے آبجیکٹ حاصل کرنے کے لیے نیا کلیدی لفظ استعمال نہیں کیا، اور ہم نے کہیں بھی JavaDevelopment یا PythonDevelopment کی قسم کے منحصر اشیاء کی وضاحت نہیں کی۔ انہیں صرف applicationContext.xml فائل میں بیان کیا گیا تھا۔ آخری لائن پر بھی توجہ دیں۔ آپ کو بند کرنے سے پہلے ہمیشہ سیاق و سباق کو بند کرنا چاہئے۔ بصورت دیگر، وسائل کو آزاد نہیں کیا جائے گا، اور پروگرام کا میموری لیک یا غلط آپریشن ہوسکتا ہے۔ اگر آپ کے سوالات یا مشورے ہیں تو کمنٹس میں لکھیں، میں ضرور جواب دوں گا۔ توجہ کے لئے شکریہ. لنک پر ماخذ کوڈ My GitHub کارٹ کورس کے مواد کو جاری رکھنے کے لیے...
تبصرے
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION