Try using it in your preferred language.

English

  • English
  • 汉语
  • Español
  • Bahasa Indonesia
  • Português
  • Русский
  • 日本語
  • 한국어
  • Deutsch
  • Français
  • Italiano
  • Türkçe
  • Tiếng Việt
  • ไทย
  • Polski
  • Nederlands
  • हिन्दी
  • Magyar
translation

यह एक AI अनुवादित पोस्ट है।

제이온

[प्रभावी जावा] आइटम 1. कॉन्स्ट्रक्टर के बजाय स्टेटिक फैक्टरी मेथड पर विचार करें

  • लेखन भाषा: कोरियाई
  • आधार देश: सभी देश country-flag

भाषा चुनें

  • हिन्दी
  • English
  • 汉语
  • Español
  • Bahasa Indonesia
  • Português
  • Русский
  • 日本語
  • 한국어
  • Deutsch
  • Français
  • Italiano
  • Türkçe
  • Tiếng Việt
  • ไทย
  • Polski
  • Nederlands
  • Magyar

durumis AI द्वारा संक्षेपित पाठ

  • स्टेटिक फैक्टरी मेथड कॉन्स्ट्रक्टर से कई लाभ प्रदान करते हैं और वे वर्ग के इंस्टेंस बनाने का प्रभावी तरीका प्रदान करते हैं।
  • JDBC स्टेटिक फैक्टरी मेथड का उपयोग करने वाला प्रमुख उदाहरण है, जो सेवा प्रदाता फ्रेमवर्क पैटर्न के माध्यम से लचीला और विस्तारयोग्य वास्तुकला प्रदान करता है।
  • स्टेटिक फैक्टरी मेथड में विरासत की कमी और डेवलपर के लिए कठिनाइयां हो सकती हैं, लेकिन इन्हें अच्छी तरह से उपयोग करके अच्छा डिज़ाइन किया जा सकता है।

परिचय

सार्वजनिक कंस्ट्रक्टर कक्षाओं के उदाहरण बनाने का पारंपरिक तरीका है।


public class Member {

    private String name;

    private int age;

    private String hobby;

    private MemberStatus memberStatus;

    public Member(String name, int age, String hobby, MemberStatus memberStatus) {
        this.name = name;
        this.age = age;
        this.hobby = hobby;
        this.memberStatus = memberStatus;
    }
}

public enum MemberStatus {

    ADVANCED,
    INTERMEDIATE,
    BASIC;


सामान्य तौर पर, पब्लिक कंस्ट्रक्टर पर्याप्त होते हैं, लेकिन निर्माताओं के अलावा, स्थिर कारखाने के तरीके (स्टैटिक फैक्ट्री मेथड) प्रदान करने से उपयोगकर्ताओं के लिए वांछित उदाहरण बनाना आसान हो सकता है।


स्थिर कारखाने विधियों का एक प्रमुख उदाहरण बूलियन का valueof () विधि है।


public static Boolean valueOf(boolean b) {
    return b ? Boolean.TRUE : Boolean.FALSE;


उपरोक्त विधि एक बूलियन मान लेती है जो एक मूल प्रकार है और उसे वापस करने के लिए एक बूलियन ऑब्जेक्ट बनाती है।


स्थिर कारखाने विधियों के लाभ

नाम रखा जा सकता है।

ऐसे नाम का उपयोग कंस्ट्रक्टर बनाने में मदद करता है। यदि किसी कंस्ट्रक्टर का नाम लंबा है और उसे याद रखना मुश्किल है, तो आप एक ही हस्ताक्षर के साथ एक स्थिर फैक्ट्री विधि बना सकते हैं और इसे उपयोगकर्ता के लिए समझने में आसान नाम दे सकते हैं।


उदाहरण के लिए, मान लें कि आपके पास एक कंस्ट्रक्टर है जो पहले नाम, अंतिम नाम, आयु, व्यवसाय और वेतन लेता है। इस कंस्ट्रक्टर के लिए एक अच्छा नाम खोजना मुश्किल हो सकता है जो सभी मापदंडों को स्पष्ट रूप से इंगित करता है। हालांकि, आप इसके बजाय एक स्टैटिक फैक्ट्री विधि बना सकते हैं जिसका नाम 'क्रिएटएम्प्लॉयी' है और वही पैरामीटर लें। इससे उपयोगकर्ताओं के लिए फ़ंक्शन के उद्देश्य को आसानी से समझना आसान हो जाएगा।


उदाहरण के लिए, Member वर्ग के उपर्युक्त मुख्य कंस्ट्रक्टर (नाम, आयु, शौक, सदस्य स्थिति) को देखते हुए, किसी को यह पहचानना मुश्किल होगा कि यह किस प्रकार का सदस्य है।


इसके अतिरिक्त, एक हस्ताक्षर के साथ केवल एक ही कंस्ट्रक्टर बनाया जा सकता है, जबकि एक स्थिर फैक्ट्री विधि का नाम हो सकता है, इसलिए एक ही हस्ताक्षर के साथ उदाहरण वापस करने के लिए कई स्थिर फैक्ट्री विधियों को बनाया जा सकता है।


public class Member {

    private String name;

    private int age;

    private String hobby;

    private MemberStatus memberStatus;

    public Member(String name, int age, String hobby, MemberStatus memberStatus) {
        this.name = name;
        this.age = age;
        this.hobby = hobby;
        this.memberStatus = memberStatus;
    }

    public static Member basicMember(String name, int age, String hobby) {
        return new Member(name, age, hobby, MemberStatus.BASIC);
    }

    public static Member intermediateMember(String name, int age, String hobby) {
        return new Member(name, age, hobby, MemberStatus.INTERMEDIATE);
    }

    public static Member advancedMember(String name, int age, String hobby) {
        return new Member(name, age, hobby, MemberStatus.ADVANCED);
    }


जैसा कि ऊपर दिखाया गया है, कंस्ट्रक्टर में सदस्य की स्थिति को अलग करने की तुलना में, एक ही हस्ताक्षर के साथ कई स्थिर फैक्ट्री विधियों को बनाकर, उपयोगकर्ता किसी विशेष कौशल वाले सदस्य उदाहरण बना सकते हैं, बिना किसी भ्रम के।

जेडीके द्वारा परिभाषित लाइब्रेरी को देखते हुए, बिगइंटेगर का स्थिर फैक्ट्री विधि, प्रोबेबलप्राइम() मौजूद है।


public static BigInteger probablePrime(int bitLength, Random rnd) {
    if (bitLength < 2)
        throw new ArithmeticException("bitLength < 2");

    return (bitLength < SMALL_PRIME_THRESHOLD ?
            smallPrime(bitLength, DEFAULT_PRIME_CERTAINTY, rnd) :
            largePrime(bitLength, DEFAULT_PRIME_CERTAINTY, rnd));


बिगइंटेगर के सामान्य कंस्ट्रक्टर और बिगइंटेगर प्रोबेबलप्राइम() की स्थिर फैक्ट्री विधि की तुलना करते समय, 后 वाला उस स्थिति का बेहतर वर्णन करेगा जहां बिगइंटेगर मान लौटाया गया है


हर बार कॉल किए जाने पर इंस्टेंस को री-क्रिएट करने की आवश्यकता नहीं है।

public static Boolean valueOf(boolean b) {
    return (b ? Boolean.TRUE : Boolean.FALSE);


बूलियन का वेल्यूऑफ़() विधि को देखने से हम पाते हैं कि एक कैशिंग मैकेनिज्म शामिल है जहां कैश्ड किए गए मूल्य को वापस कर दिया जाता है। इस विशेषता से प्रदर्शन में उल्लेखनीय सुधार हो सकता है यदि अनुरोध की जाने वाली वस्तु महंगी है,फ्लाईवेट पैटर्नइसी तरह की तकनीक को भी माना जा सकता है।


एक क्लास जो स्थिर फैक्ट्री विधि विधि का उपयोग करता है जो समान वस्तु को दोहराए गए अनुरोधों पर वापस करता है, उसे इंस्टेंस नियंत्रण वर्ग कहा जाता है। इंस्टेंस को नियंत्रित करके, आप सिंगलटन क्लास बना सकते हैं या गैर-इंस्टेंटिएटेबल क्लास बना सकते हैं। आप यह भी सुनिश्चित कर सकते हैं कि अपरिवर्तनीय मूल्य वर्ग में केवल एक ही इंस्टेंस मौजूद है।

इंस्टेंस नियंत्रण फ्लाईवेट पैटर्न का आधार है और एनम यह गारंटी देता है कि केवल एक ही इंस्टेंस बनाया गया है।


उदाहरण

हमें माइनक्राफ्ट में एक पेड़ लगाना है। अगर हम प्रति पेड़ ऑब्जेक्ट बनाते हैं, तो हमारे पास मेमोरी ओवरफ्लो की संभावना है।

इसलिए, लाल और हरे रंग के पेड़ों की तरह, इन वस्तुओं को सहेजा जाता है, केवल स्थान को बदल दिया जाता है और वापस कर दिया जाता है। बेशक, रंग 2 से अधिक रंगों में बढ़ सकते हैं, इसलिएवृक्षों को संग्रहीत करने के लिए रंग के अनुसार एक नक्शा जैसी डेटा संरचना कुशल होगी।


public class Tree {

    // पेड़ में नीचे दी गई 3 जानकारी होती है।
    private String color;
    private int x;
    private int y;

    // केवल रंग का उपयोग करके रचनाकार बनाएं।
    public Tree(String color) {
        this.color = color;
    }

    public void setX(int x) {
        this.x = x;
    }

    public void setY(int y) {
        this.y = y;
    }

    // जब पेड़ लगाते हैं
    public void install(){
        System.out.println("x:"+x+" y:"+y+" 위치에 "+color+"색 나무를 설치했습니다!");
    }
}

public class TreeFactory {
    // HashMap डेटा संरचना का उपयोग करके बनाए गए पेड़ों को प्रबंधित करें।
    public static final Map treeMap = new HashMap<>();
    
   
    public static Tree getTree(String treeColor){
        // मैप में चेक करें कि निर्दिष्ट रंग का पेड़ पहले से है या नहीं। अगर है तो उसी ऑब्जेक्ट को रिटर्न करें।
        Tree tree = (Tree)treeMap.get(treeColor); 

       // अगर अभी तक मैप में उसी रंग का पेड़ नहीं है, तो एक नया ऑब्जेक्ट बनाएं और रिटर्न करें।
        if(tree == null){
            tree = new Tree(treeColor);
            treeMap.put(treeColor, tree);
            System.out.println("नया ऑब्जेक्ट बनाया गया है");
        }

        return tree;
    }
}

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        System.out.println("इच्छित रंग दर्ज करें :)");
        for(int i=0;i<10;i++){
            // पेड़ का रंग दर्ज करें
            String input = scanner.nextLine();
            // कारखाने से एक पेड़ की आपूर्ति प्राप्त करें
            Tree tree = (Tree)TreeFactory.getTree(input);
            // पेड़ का x,y सेट करें
            tree.setX((int) (Math.random()*100));
            tree.setY((int) (Math.random()*100));
            // पेड़ लगाना
            tree.install();
        }
    }


सिंगलटन पैटर्न के साथ अंतर

सिंगलटन पैटर्न यह सुनिश्चित करता है कि पेड़ वर्ग में केवल एक ही पेड़ बनाया जा सकता है। इसलिए, यदि आप सिंगलटन पैटर्न का उपयोग करते हैं, तो आपको रंग की परवाह किए बिना बनाए गए एकल वस्तु का रंग बदलना होगा।अर्थात, सिंगलटन पैटर्न बिना किसी भिन्नता के केवल एक ही वस्तु रख सकता है।


उपयोग के मामले

जावा के स्ट्रिंग कॉस्टेंट पूल में फ्लाईवेट पैटर्न का उपयोग किया जाता है।


आप उपवर्ग वस्तुओं को विभिन्न वापसी प्रकारों के साथ वापस कर सकते हैं।

यदि आपने कभी एरेज यूटिलिटीज क्लास की एजलिस्ट () विधि का उपयोग किया है, तो आप इस लाभ को समझेंगे।


public static  List asList(T... a) [
    return new ArrayList<>(a);


वापसी मानों को ArrayList जैसे ArrayList के उप प्रकार में लपेटा जाता है, लेकिन उपयोगकर्ताओं को इस कार्यान्वयन को जानने की आवश्यकता नहीं है। अर्थात, क्योंकि वापसी वस्तु के वर्ग का चयन स्वतंत्र रूप से किया जा सकता है, यह लचीलापन होता है जो डेवलपर्स को कार्यान्वयन को उजागर किए बिना कार्यान्वयन वापस करने की अनुमति देता है ताकि एपीआई को छोटा रखा जा सके


जावा इंटरफ़ेस के बारे में स्थिर विधि

जावा 8 से पहले, इंटरफेस में स्थिर विधियों को घोषित करना असंभव था, और "प्रकार" नाम की एक इंटरफेस से जुड़ी एक स्थिर विधि लौटाने के लिए, इसे विधियों को परिभाषित करने वाले" टाइप्स" नामक एक गैर-इंस्टेंटिएटेबल साथी वर्ग बनाया गया था।


जावा संग्रह रूपरेखा (JCF) में 45 प्रदाता कार्यान्वयन हैं और इनमें से अधिकांश कार्यान्वयन एक ही सहयोगी वर्ग java.util.Collections में केवल एक स्थिर फैक्ट्री विधि के माध्यम से उपलब्ध हैं। विशेष रूप से, इन कार्यान्वयनों में से, जनता नहीं हैं और इसलिए उन्हें केवल स्थिर फैक्ट्री विधि के माध्यम से ही बनाया जा सकता है। (इसके कार्यान्वयन को स्वाभाविक रूप से विरासत में नहीं लिया जा सकता है।)


इसके अतिरिक्त, 45 कार्यान्वयनों को उजागर नहीं किया गया है, इसलिए एपीआई को बहुत छोटा रखा गया है।


// इंटरफ़ेस और साथी वर्ग का उदाहरण


हालाँकि, जावा 8 से, एक साथी वर्ग को अलग से परिभाषित किए बिना सीधे इंटरफ़ेस में स्थिर विधियाँ जोड़ी जा सकती हैं।


यह विभिन्न निम्न श्रेणी की वस्तुओं को इनपुट पैरामीटर के आधार पर वापस कर सकता है।

केवल निम्न श्रेणियों को वापस करने के अलावा, यह पैरामीटर मान के आधार पर विभिन्न सबटाइप वापस कर सकता है। उदाहरण के लिए, यदि आप अंक के आधार पर सदस्य की स्थिति बदलना चाहते हैं, तो आप निम्न के रूप में एक स्थिर फैक्ट्री विधि बना सकते हैं और उसमें तुलना तर्क सेट कर सकते हैं।


public enum MemberStatus {

    ADVANCED(80, 100),
    INTERMEDIATE(50, 79),
    BASIC(0, 49);

    private final int minScore;
    private final int maxScore;

    MemberStatus(int minScore, int maxScore) {
        this.minScore = minScore;
        this.maxScore = maxScore;
    }

    public static MemberStatus of(int score) {
        return Arrays.stream(values())
                .filter(decideMemberStatus(score))
                .findAny()
                .orElseThrow(() -> new NoSuchElementException("संशोधित करने के लिए कोई संगत सदस्य स्थिति वस्तु नहीं है।"));
    }

    private static Predicate decideMemberStatus(int score) {
        return element -> element.minScore <= score && element.maxScore >= score;
    }
}

@DisplayName("सदस्य स्थिति परीक्षण")
class MemberStatusTest {

    @ParameterizedTest
    @CsvSource(value = {"0:BASIC", "30:BASIC", "50:INTERMEDIATE", "70:INTERMEDIATE", "80:ADVANCED", "100:ADVANCED"}, delimiter = ':')
    @DisplayName("अंक के आधार पर सदस्य की स्थिति अलग-अलग लौटाता है।")
    void of(int input, MemberStatus expected) {
        assertThat(MemberStatus.of(input)).isEqualTo(expected);
    }


स्थिर फैक्ट्री विधि बनाने के समय उस वस्तु का वर्ग मौजूद नहीं हो सकता है जिससे वापसी होगी।

उपर्युक्त वाक्य में class, वस्तु के वर्ग, यह हमारे द्वारा बनाई गई क्लास फ़ाइल है।

संदर्भ के लिए, Class क्लास लोडर द्वारा क्लास को लोड करते समय हीप क्षेत्र में असाइन की जाने वाली क्लास ऑब्जेक्ट को संदर्भित करता है। इस क्लास ऑब्जेक्ट में हमारे द्वारा बनाई गई क्लास का विभिन्न मेटाडेटा होता है।


package algorithm.dataStructure;

public abstract class StaticFactoryMethodType {

    public abstract void getName();

    public static StaticFactoryMethodType getNewInstance() {
        StaticFactoryMethodType temp = null;
        try {
            Class childClass = Class.forName("algorithm.dataStructure.StaticFactoryMethodTypeChild"); // परावर्तन
            temp = (StaticFactoryMethodType) childClass.newInstance(); // परावर्तन

        } catch (ClassNotFoundException e) {
           System.out.println("कोई वर्ग नहीं है।");
        } catch (InstantiationException  e) {
            System.out.println("स्मृति में लोड नहीं किया जा सकता है।");
        } catch (IllegalAccessException  e) {
            System.out.println("क्लास फ़ाइल एक्सेस त्रुटि।");
        }

        return temp;
    }


यदि आप ऊपर दिए गए कोड को देखते हैं, तो आप पाएंगे कि इंटरफ़ेस कार्यान्वयन का स्थान परावर्तन का उपयोग करके वास्तविक कार्यान्वयन को आरंभ करने के लिए एक वर्ग ऑब्जेक्ट बनाने के लिए उपयोग किया जाता है। इस समय स्थिर फैक्ट्री विधि लिखते समयStaticFactoryMethodTypeChild वर्ग मौजूद नहीं होना चाहिए।


हालांकि, अगर स्थैतिक फैक्ट्री विधि का उपयोग करते समय algorithm.dataStructure.StaticFactoryMethodTypeChild पथ पर कोई कार्यान्वयन नहीं है, तो एक त्रुटि होती है, लेकिन कोई समस्या नहीं है स्थिर फैक्ट्री विधि को लिखते समय क्योंकि यह लचीला है।


public interface Test {

    int sum(int a, int b);

    // स्थिर फैक्ट्री विधि, भले ही कोई कार्यान्वयन न हो, समस्याएँ पैदा नहीं करेगी क्योंकि यह लिखी गई है।
    static Test create() {
        return null;
    }
}

public class Main {

    public static void main(String[] args) {
        Test test = Test.create();
        System.out.println(test.sum(1, 2)); // NPEが発生
    }


आप प्रतिबिंब का उपयोग किए बिना भी उसी लचीलापन प्राप्त कर सकते हैं। Test का स्थिर फैक्ट्री विधि create() देखते ही, भले ही कोई कार्यान्वयन न हो, लिखने में कोई समस्या नहीं है। बेशक, जब वास्तव में उपयोग किया जाता है, तो एक NPE उत्पन्न होता है, इसलिए आपको बाद में एक कार्यान्वयन वापस करने की आवश्यकता होती है।


यह लचीलापन वह आधार है जिस पर सेवा प्रदाता रूपरेखा बनाई जाती है, जिसका प्रतिनिधि JDBC है। JDBC सेवा प्रदाता रूपरेखा के प्रदाता कार्यान्वयन हैं और रूपरेखा क्लाइंट को कार्यान्वयन प्रदान करने में एक भूमिका निभाती है, जिससे क्लाइंट को कार्यान्वयन से अलग किया जाता है। (डीआईपी)


  • सेवा प्रदाता रूपरेखा के घटक
    • सेवा इंटरफ़ेस
      • कार्यान्वयन व्यवहार को परिभाषित करता है
      • JDBC का कनेक्शन
    • प्रदाता पंजीकरण एपीआई
      • प्रदाता एक कार्यान्वयन पंजीकृत करता है
      • JDBC का DriverManager.registerDriver()
    • सेवा पहुंच एपीआई
      • क्लाइंट सेवा का एक उदाहरण प्राप्त करते समय उपयोग किया जाता है, और जब कोई स्थिति निर्दिष्ट नहीं होती है, तो यह डिफ़ॉल्ट कार्यान्वयन या समर्थित कार्यान्वयन देता है।
      • स्थिर फैक्ट्री विधि का समकक्ष
      • JDBC का DriverManager.getConnection()
    • (विकल्प) सेवा प्रदाता इंटरफ़ेस
      • यदि यह मौजूद नहीं है, तो आपको प्रत्येक कार्यान्वयन को प्रतिबिंब का उपयोग करके एक इंस्टेंस के रूप में बनाने की आवश्यकता है
      • JDBC का चालक


सेवा प्रदाता रूपरेखा पैटर्न के कई रूप हैं और पुल पैटर्न और निर्भरता इंजेक्शन रूपरेखा की तरह दिखते हैं।


एक विशिष्ट JDBC उदाहरण

Class.forName("oracle.jdbc.driver.OracleDriver"); 
Connection connection = null; 
connection = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:ORA92", "root", "root"); 


सामान्य तौर पर, JDBC को ऊपर की तरह लिखा जाता है। Class.forName() का उपयोग करके, OracleDriver जैसे ड्राइवर कार्यान्वयन में से एक पंजीकृत है, और DriverManager.getConnection() का उपयोग करके, कनेक्शन OracleDriver जैसे कनेक्शन कार्यान्वयन में से एक है।


यहां, हम देख सकते हैं कि Connection सेवा इंटरफ़ेस है, DriverManager.getConnection() सेवा एक्सेस एपीआई है, और Driver सेवा प्रदाता इंटरफ़ेस है। हालाँकि, DriverManager.registerDriver() जिसे प्रदाता पंजीकरण API कहा जाता है, का उपयोग नहीं किया गया था। फिर भी, हम Class.forName() का उपयोग करके OracleDriver जैसे ड्राइवर कार्यान्वयन को पंजीकृत कर सकते हैं। यह कैसे संभव है?


Class.forName() का संचालन सिद्धांत

यह विधि एक भौतिक वर्ग फ़ाइल नाम इनपुट के रूप में लेती है और JVM से क्लास लोड करने का अनुरोध करती है। फिर क्लास लोडर क्लास के मेटाडेटा को विधि क्षेत्र में संग्रहीत करता है, जबकिस्टेटिक फ़ील्ड और स्टेटिक ब्लॉक को इनिशियलाइज़ किया गया है। इस समय, प्रदाता पंजीकरण एपीआई का उपयोग किया जाता है।


public class OracleDriver implements Driver {

    static {
        defaultDriver = null;
        Timestamp timestamp = Timestamp.valueOf("2000-01-01 00:00:00.0");
        try {
            if (defaultDriver == null) {
                defaultDriver = new OracleDriver();
                DriverManager.registerDriver(defaultDriver); // OracleDriver पंजीकरण
            }
        } catch (RuntimeException runtimeexception) {
        } catch (SQLException sqlexception) {
        }
    }

    ...


वास्तव में, OracleDriver को देखते हुए, हम देख सकते हैं किDriverManager.registerDriver() का उपयोग करके स्टैटिक ब्लॉक मेंOracleDriver जैसे ड्राइवर कार्यान्वयन पंजीकृत है।


DriverManager वर्ग विश्लेषण

public class DriverManager {

    private DriverManager() {
    }

    private static final Map drivers = new ConcurrentHashMap();
    public static final String DEFAULT_DRIVER_NAME = "default";

    public static void registerDefaultPrivider(Driver d) {
        System.out.println("ड्राइवर पंजीकरण");
        registerDriver(DEFAULT_DRIVER_NAME, d);
    }

    public static void registerDriver(String name, Driver d) {
        drivers.put(name, d);
    }

    public static Connection getConnection() {
        return getConnection(DEFAULT_DRIVER_NAME);
    }

    public static Connection getConnection(String name) {
        Driver d = drivers.get(name);
        if (d == null) throw new IllegalArgumentException();
        return d.getConnection();
    }


हालांकि DriverManager वास्तव में बहुत अधिक जटिल है, यह एक सरलीकृत संस्करण है यदि आपके पास गहन नहीं है। उपरोक्त explanation के अनुसार, यह registerDriver() को OracleDriver के स्टैटिक ब्लॉक में कहता है और OracleDriver को पंजीकृत करता है, और उपयोगकर्ताgetConnection() को कॉल करके कनेक्शन कार्यान्वयन प्राप्त कर सकता है।


यदि आप ड्राइवर इंटरफ़ेस से Connection प्राप्त कर रहे हैं, तो अधिक विस्तार से देखें, आप पाएंगे कि कनेक्शन कार्यान्वयन ड्राइवर इंटरफ़ेस से प्राप्त होता है। यदि कोई सेवा प्रदाता इंटरफ़ेस, ड्राइवर जैसा मौजूद नहीं है, तो आपको Class.forName() जैसे रिफ्लेक्शन का उपयोग करके कनेक्शन कार्यान्वयन वापस करने की आवश्यकता हो सकती है जिसे आप चाहते हैं। इस समय, आपके द्वारा उस समय Connection कार्यान्वयन नहीं बनाया जाएगा जिसके बारे में आपने स्थिर फैक्ट्री लिखी थी।


इसके बजाय, हम ड्राइवर इंटरफ़ेस का उपयोग करके गतिशील रूप से ड्राइवर कार्यान्वयन पंजीकृत करते हैं और ड्राइवर के अनुसार Connection कार्यान्वयन आसानी से प्राप्त कर सकते हैं।


संदर्भ के लिए, मैं DriverManager के getConnection() विधि का वास्तविक JDK कोड देखता हूं, लेकिन आप इसे छोड़ सकते हैं जब तक कि आपके पास इसमें कोई विशेष रुचि न हो।


@CallerSensitive
public static Connection getConnection(String url,
    String user, String password) throws SQLException {
    java.util.Properties info = new java.util.Properties();

    if (user != null) {
        info.put("user", user);
    }
    if (password != null) {
        info.put("password", password);
    }

    return (getConnection(url, info, Reflection.getCallerClass()));


सर्वप्रथम, सार्वजनिक static विधि getConnection() को कॉल किया जाता है, और url, Properties और CallerClass निजी स्थिर विधि getConnection() के इनपुट के रूप में पारित किए जाते हैं। इस समय, Reflection.getCallerClass() वह वर्ग प्राप्त करने की भूमिका निभाता है जिसने public static विधि getConnection() को कॉल किया है। यदि Car वर्ग ने getConnection() को कॉल किया है, तो आप CallerClass द्वारा वर्ग ऑब्जेक्ट प्राप्त कर सकते हैं।


private static Connection getConnection(String url, java.util.Properties info, Class caller) throws SQLException {
    ClassLoader callerCL = caller != null ? caller.getClassLoader() : null;
    synchronized(DriverManager.class) {
        if (callerCL == null) {
            callerCL = Thread.currentThread().getContextClassLoader();
        }
    }

    if(url == null) {
        throw new SQLException("The url cannot be null", "08001");
    }

    SQLException reason = null;
    for(DriverInfo aDriver : registeredDrivers) {
        if(isDriverAllowed(aDriver.driver, callerCL)) {
            try {
                Connection con = aDriver.driver.connect(url, info);
                if (con != null) {
                    return (con);
                }
            } catch (SQLException ex) {
                if (reason == null) {
                    reason = ex;
                }
            }
        }
    }

    if (reason != null)    {
        throw reason;
    }
    throw new SQLException("No suitable driver found for "+ url, "08001");


callerCL एक क्लास लोडर ऑब्जेक्ट है और इसे caller's क्लास लोडर या वर्तमान थ्रेड के क्लास लोडर द्वारा बनाया जाता है। उसके बाद, वह वर्तमान एप्लिकेशन में पंजीकृत ड्राइवर सूची, registeredDrivers, एक-एक करके aDriver प्राप्त करता है। और यदि यह aDriver isDriverAllowed() द्वारा true के रूप में आता है, तो इस ड्राइवर द्वारा Connection ऑब्जेक्ट प्राप्त करें और इसे वापस करें। isDriverAllowed() caller की aDriver की अनुमति की जांच करने का काम करता है।


JDBC फ्रेमवर्क के लाभ

JDBC फ्रेमवर्क का मुख्य बिंदु यह है कि ड्राइवर, कनेक्शन इंटरफ़ेस और उनके संबंधित वास्तविक कार्यान्वयन वर्ग पूरी तरह से अलग और प्रदान किए जाते हैं। इंटरफ़ेस का उपयोग करके फ्रेमवर्क बनाएं और प्रत्येक फ्रेमवर्क के अनुसार कार्यान्वयन वर्ग बनाएं। यह बहुत लचीला है क्योंकि यह बहुत लचीला है।


इसलिए, भले ही एक और डीबीएमएस सामने आए, विक्रेता ड्राइवर और कनेक्शन इंटरफ़ेस को लागू करके और प्रदान करके जावा का उपयोग कर रहे डेवलपर्स को उसी एपीआई का उपयोग करने देगा।


स्थिर कारखाने विधियों के नुकसान

जेनरिक निर्माण विधियों के माध्यम से उपवर्ग नहीं बनाए जा सकते क्योंकि उन्हें सार्वजनिक या संरक्षित निर्माणकर्ताओं की आवश्यकता होती है।


제이온
제이온
제이온
제이온
[इफेक्टिव जावा] आइटम 4. इंस्टेंटिएशन को रोकने के लिए प्राइवेट कंस्ट्रक्टर का उपयोग करें केवल स्थिर विधियों और क्षेत्रों वाले उपयोगिता वर्गों के लिए, इंस्टेंटिएशन को रोकने के लिए कंस्ट्रक्टर को निजी रूप से घोषित करना सबसे अच्छा है। यह कम्पाइलर द्वारा स्वचालित रूप से उत्पन्न डिफ़ॉल्ट कंस्ट्रक्टर को नियंत्रित करने और कक्षा के बाहर इंस्टेंटिएशन

28 अप्रैल 2024

[स्प्रिंग] फ़िल्टर, इंटरसेप्टर, आर्ग्यूमेंट रिसॉल्वर क्या हैं? स्प्रिंग वेब एप्लीकेशन में अनुरोधों को संसाधित करने वाले फ़िल्टर, इंटरसेप्टर, आर्ग्यूमेंट रिसॉल्वर की अवधारणा और अंतर को जानें। प्रत्येक फ़ंक्शन को कैसे लागू किया जाए, इसका उपयोग कब करें, फायदे और नुकसान की तुलना करें और वास्तविक उदाहरण कोड के माध्यम से स

27 अप्रैल 2024

[इफ़ेक्टिव जावा] आइटम 5. संसाधनों का उल्लेख न करें, डिपेंडेंसी इंजेक्शन का उपयोग करें यदि कोई वर्ग आंतरिक रूप से एक से अधिक संसाधनों पर निर्भर करता है, तो सिंगलटन और स्टैटिक उपयोगिता वर्गों के बजाय डिपेंडेंसी इंजेक्शन का उपयोग करना बेहतर होता है। डिपेंडेंसी इंजेक्शन के माध्यम से, आप वर्ग की लचीलापन, पुन: उपयोग और परीक्षण क्षमता में सुधार क

28 अप्रैल 2024

[Javascript] ऑब्जेक्ट की संरचना (V8) JavaScript का Object V8 इंजन में स्थिति के अनुसार संरचना की तरह अनुकूलित Fast मोड और हैशमैप में काम करने वाले Dictionary मोड में परिवर्तित हो जाता है। Fast मोड लगभग स्थिर रूप में कुंजी और मान के साथ तेज़ होता है, लेकिन, नए कुंजी जोड़े जाने या तत्वों को हट
곽경직
곽경직
곽경직
곽경직
곽경직

18 मार्च 2024

[धातु सामग्री कार्यकारी] 35वाँ हल धातु सामग्री माइक्रोस्कोपिक संरचना परीक्षण, फेराइट ग्रेन आकार निर्धारण विधि, बीसीसी का पैकिंग घनत्व, आदि धातु सामग्री से संबंधित विभिन्न शब्दों और अवधारणाओं को संक्षेपित और समझाया गया है। सीमेंटेड स्टील के लिए आवश्यक शर्तें, ठंडे काम किए गए धातु की एनीलिं
blog.naver.com/gksmftordldi
blog.naver.com/gksmftordldi
blog.naver.com/gksmftordldi
blog.naver.com/gksmftordldi
blog.naver.com/gksmftordldi

23 अप्रैल 2024

[गैर-प्रमुख, डेवलपर के रूप में जीवित रहना] 14. नौसिखिए डेवलपर द्वारा अक्सर पूछे जाने वाले तकनीकी साक्षात्कार सामग्री का सारांश नौसिखिए डेवलपर के लिए तकनीकी साक्षात्कार की तैयारी के लिए एक मार्गदर्शिका। मुख्य मेमोरी क्षेत्र, डेटा संरचना, RDBMS और NoSQL, प्रक्रियात्मक और ऑब्जेक्ट-ओरिएंटेड, ओवरराइडिंग और ओवरलोडिंग, पेज रिप्लेसमेंट एल्गोरिदम, प्रक्रिया और थ्रेड, OSI 7 लेयर, TCP और UD
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자

3 अप्रैल 2024

वाटरफॉल विकास पद्धति क्या है? वाटरफॉल विकास पद्धति एक पारंपरिक पद्धति है जो सॉफ़्टवेयर विकास प्रक्रिया को आवश्यकता विश्लेषण, डिज़ाइन, कार्यान्वयन, परीक्षण, परिनियोजन और रखरखाव चरणों में विभाजित करती है और उन्हें क्रमिक रूप से आगे बढ़ाती है। इस पद्धति में स्पष्ट संरचना और प्रलेखन का ला
꿈많은청년들
꿈많은청년들
꿈많은청년들
꿈많은청년들
꿈많은청년들

14 मई 2024

[गैर-मुख्य, डेवलपर के रूप में जीवित रहना] 16. नौसिखिए डेवलपर पोर्टफोलियो निर्माण युक्तियाँ नौसिखिए डेवलपर (विशेष रूप से गैर-मुख्य) को पोर्टफोलियो बनाते समय तकनीक के साथ-साथ विकसित सेवाओं या कार्यों को स्पष्ट रूप से बताना चाहिए। उदाहरण के लिए, "रोजगार खोजने वालों के लिए समुदाय" परियोजना के लिए, प्रश्नोत्तर बोर्ड, चयन प्रणाली, क्रॉलिंग बॉट विकास
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자

3 अप्रैल 2024

[धातु सामग्री कार्यकारी वास्तविक] 38वां समाधान यह पाठ गर्मी उपचार, सामग्री विज्ञान, धातुकर्म से संबंधित शब्दावली और अवधारणाओं की व्याख्या करता है, साथ ही साथ डिकर्बोनाइजेशन परत मापन विधि, गर्मी उपचार सख्त करने में विफलता के कारण, क्रिप घटना आदि जैसे विभिन्न विषयों को शामिल करता है। विशेष रूप से, डिकर्
blog.naver.com/gksmftordldi
blog.naver.com/gksmftordldi
blog.naver.com/gksmftordldi
blog.naver.com/gksmftordldi

24 अप्रैल 2024