नमस्ते! आज हम एक महत्वपूर्ण नए विषय पर बात करेंगे: डिज़ाइन पैटर्न । ये पैटर्न क्या हैं? मुझे लगता है कि आपको " पहिए का पुन: आविष्कार न करें " अभिव्यक्ति को जानना चाहिए । प्रोग्रामिंग में, कई अन्य क्षेत्रों की तरह, बड़ी संख्या में सामान्य स्थितियाँ हैं। जैसा कि सॉफ्टवेयर विकास विकसित हुआ है, उनमें से प्रत्येक के लिए काम करने वाले तैयार समाधान तैयार किए गए हैं। इन समाधानों को डिज़ाइन पैटर्न कहा जाता है। सम्मेलन द्वारा, एक पैटर्न कुछ समाधान तैयार किया गया है: "यदि आपको अपने कार्यक्रम में एक्स करने की ज़रूरत है, तो यह करने का यह सबसे अच्छा तरीका है"। बहुत सारे पैटर्न हैं। उत्कृष्ट पुस्तक "हेड फर्स्ट डिज़ाइन पैटर्न", जिसे आपको निश्चित रूप से परिचित होना चाहिए, उन्हें समर्पित है। संक्षेप में, एक पैटर्न में एक सामान्य समस्या और एक संबंधित समाधान होता है जिसे एक प्रकार का मानक माना जा सकता है। आज के पाठ में, हम इनमें से एक पैटर्न से मिलेंगे: एडेप्टर। इसका नाम ही सब कुछ कह देता है, और आपने वास्तविक जीवन में कई बार एडॉप्टर का सामना किया है। कुछ सबसे आम एडेप्टर कार्ड रीडर हैं जो कई कंप्यूटर और लैपटॉप में होते हैं। मान लीजिए हमारे पास किसी प्रकार का मेमोरी कार्ड है। तो समस्या क्या है? यह नहीं जानता कि कंप्यूटर के साथ कैसे इंटरैक्ट करना है। वे एक सामान्य इंटरफ़ेस साझा नहीं करते हैं। कंप्यूटर में USB पोर्ट है, लेकिन हम उसमें मेमोरी कार्ड नहीं डाल सकते। कार्ड को कंप्यूटर में प्लग नहीं किया जा सकता है, इसलिए हम अपने फोटो, वीडियो और अन्य डेटा को सेव नहीं कर सकते हैं। एक कार्ड रीडर एक एडॉप्टर है जो इस समस्या को हल करता है। आखिरकार, इसमें एक यूएसबी केबल है! कार्ड के विपरीत, कार्ड रीडर को कंप्यूटर में प्लग किया जा सकता है। वे कंप्यूटर के साथ एक सामान्य इंटरफ़ेस साझा करते हैं: USB। आइए देखें कि यह व्यवहार में कैसा दिखता है:
public interface USB {
void connectWithUsbCable();
}
यह हमारा USB इंटरफ़ेस है जिसमें USB के माध्यम से जुड़ने का सिर्फ एक तरीका है।
public class MemoryCard {
public void insert() {
System.out.println("Memory card successfully inserted!");
}
public void copyData() {
System.out.println("The data has been copied to the computer!");
}
}
यह हमारी कक्षा है जो मेमोरी कार्ड का प्रतिनिधित्व करती है। इसमें पहले से ही 2 विधियाँ हैं जिनकी हमें आवश्यकता है, लेकिन यहाँ समस्या है: यह USB इंटरफ़ेस को लागू नहीं करता है। कार्ड को USB पोर्ट में नहीं डाला जा सकता है।
public class CardReader implements USB {
private MemoryCard memoryCard;
public CardReader(MemoryCard memoryCard) {
this.memoryCard = memoryCard;
}
@Override
public void connectWithUsbCable() {
this.memoryCard.insert();
this.memoryCard.copyData();
}
}
और यहाँ हमारा एडॉप्टर है! क्या करता हैCardReader
क्लास क्या करता है और वास्तव में यह एडॉप्टर क्या बनाता है? यह सब सरल है। अनुकूलित किया जा रहा वर्ग (मेमोरीकार्ड) एडॉप्टर के क्षेत्रों में से एक बन जाता है। यह समझ में आता है। जब हम असल जिंदगी में कार्ड रीडर के अंदर मेमोरी कार्ड डालते हैं तो वह भी उसका हिस्सा बन जाता है। मेमोरी कार्ड के विपरीत, एडॉप्टर कंप्यूटर के साथ एक इंटरफ़ेस साझा करता है। इसमें USB केबल लगी होती है, यानी इसे USB के जरिए दूसरे डिवाइस से कनेक्ट किया जा सकता है। इसलिए हमारा कार्डरीडर वर्ग USB इंटरफ़ेस को लागू करता है। लेकिन इस पद्धति के अंदर वास्तव में क्या होता है? ठीक वही जो हमें होना चाहिए! एडॉप्टर हमारे मेमोरी कार्ड को काम सौंपता है। दरअसल, एडॉप्टर खुद कुछ नहीं करता है। कार्ड रीडर की कोई स्वतंत्र कार्यक्षमता नहीं होती है। इसका काम केवल कंप्यूटर और मेमोरी कार्ड को कनेक्ट करना है ताकि कार्ड अपना काम कर सके - फ़ाइलों की प्रतिलिपि बनाना!connectWithUsbCable()
विधि) मेमोरी कार्ड की "जरूरतों" को पूरा करने के लिए। चलिए कुछ क्लाइंट प्रोग्राम बनाते हैं जो एक ऐसे व्यक्ति का अनुकरण करेगा जो मेमोरी कार्ड से डेटा कॉपी करना चाहता है:
public class Main {
public static void main(String[] args) {
USB cardReader = new CardReader(new MemoryCard());
cardReader.connectWithUsbCable();
}
}
तो हमें क्या मिला? कंसोल आउटपुट:
Memory card successfully inserted!
The data has been copied to the computer!
उत्कृष्ट। हमने अपना लक्ष्य हासिल कर लिया! एडेप्टर पैटर्न के बारे में जानकारी के साथ वीडियो का लिंक यहां दिया गया है:
पाठक और लेखक सार वर्ग
अब हम अपनी पसंदीदा गतिविधि पर लौटेंगे: इनपुट और आउटपुट के साथ काम करने के लिए कुछ नई कक्षाओं के बारे में सीखना :) मुझे आश्चर्य है कि हम कितने के बारे में पहले ही सीख चुके हैं। आज हमReader
और Writer
कक्षाओं के बारे में बात करेंगे। विशेष रूप से वे वर्ग क्यों? क्योंकि वे एडेप्टर के बारे में हमारे पिछले भाग से संबंधित हैं। आइए उनकी अधिक विस्तार से जांच करें। हम साथ शुरू करेंगे Reader
। Reader
एक सार वर्ग है, इसलिए हम वस्तुओं को स्पष्ट रूप से बनाने में सक्षम नहीं होंगे। लेकिन आप वास्तव में इससे पहले ही परिचित हैं! आखिरकार, आप BufferedReader
और InputStreamReader
कक्षाओं से अच्छी तरह परिचित हैं, जो इसके वंशज हैं :)
public class BufferedReader extends Reader {
…
}
public class InputStreamReader extends Reader {
…
}
क्लास InputStreamReader
एक क्लासिक एडॉप्टर है। जैसा कि आपको शायद याद होगा, हम किसी InputStream
वस्तु को उसके कंस्ट्रक्टर को पास कर सकते हैं। ऐसा करने के लिए, हम आमतौर पर System.in
चर का उपयोग करते हैं:
public static void main(String[] args) {
InputStreamReader inputStreamReader = new InputStreamReader(System.in);
}
लेकिन InputStreamReader
करता क्या है? प्रत्येक एडॉप्टर की तरह, यह एक इंटरफ़ेस को दूसरे में परिवर्तित करता है। इस मामले में, इंटरफ़ेस InputStream
के लिए इंटरफ़ेस Reader
। प्रारंभ में, हमारे पास InputStream
कक्षा है। यह अच्छी तरह से काम करता है, लेकिन आप इसे केवल व्यक्तिगत बाइट पढ़ने के लिए उपयोग कर सकते हैं। इसके अलावा, हमारे पास एक Reader
सार वर्ग है। इसकी कुछ बहुत उपयोगी कार्यक्षमता है - यह जानता है कि पात्रों को कैसे पढ़ना है! हमें निश्चित रूप से इस क्षमता की जरूरत है। लेकिन यहां हम आमतौर पर एडेप्टर - असंगत इंटरफेस द्वारा हल की जाने वाली क्लासिक समस्या का सामना करते हैं। इसका क्या मतलब है? आइए Oracle प्रलेखन पर एक नज़र डालें। यहाँ वर्ग के तरीके हैं InputStream
। विधियों का एक सेट ठीक वही है जो एक इंटरफ़ेस है। जैसा कि आप देख सकते हैं, इस वर्ग में एकread()
विधि (कुछ प्रकार, वास्तव में), लेकिन यह केवल बाइट्स पढ़ सकता है: या तो व्यक्तिगत बाइट्स, या बफर का उपयोग करके कई बाइट्स। लेकिन यह विकल्प हमें शोभा नहीं देता - हम पात्रों को पढ़ना चाहते हैं। हमें उस कार्यक्षमता की आवश्यकता है जो पहले से ही सार वर्ग में लागूReader
है । हम इसे दस्तावेज़ीकरण में भी देख सकते हैं। हालांकि, InputStream
और Reader
इंटरफेस असंगत हैं! जैसा कि आप देख सकते हैं, read()
विधि के प्रत्येक कार्यान्वयन में अलग-अलग पैरामीटर और वापसी मूल्य हैं। और यहीं हमें चाहिए InputStreamReader
! यह हमारी कक्षाओं के बीच अनुकूलक के रूप में कार्य करेगा ।जैसा कि कार्ड रीडर के उदाहरण में, जिसे हमने ऊपर माना था, हम एडॉप्टर क्लास के "अंदर" अनुकूलित किए जा रहे वर्ग का उदाहरण देते हैं, यानी हम इसके कंस्ट्रक्टर को पास करते हैं। पिछले उदाहरण में, हमने एक MemoryCard
वस्तु को अंदर रखा CardReader
। अब हम कन्स्ट्रक्टर InputStream
को ऑब्जेक्ट पास कर रहे हैं InputStreamReader
! हम अपने परिचित System.in
चर का उपयोग इस प्रकार करते हैं InputStream
:
public static void main(String[] args) {
InputStreamReader inputStreamReader = new InputStreamReader(System.in);
}
और वास्तव में, के लिए प्रलेखन को देखते हुए InputStreamReader
, हम देख सकते हैं कि अनुकूलन सफल हुआ :) अब हमारे पास अपने निपटान में पात्रों को पढ़ने के तरीके हैं। और यद्यपि हमारी System.in
वस्तु (कीबोर्ड से बंधी धारा) ने शुरू में इसकी अनुमति नहीं दी थी, भाषा के रचनाकारों ने एडेप्टर पैटर्न को लागू करके इस समस्या को हल किया। अमूर्त Reader
वर्ग, अधिकांश I/O वर्गों की तरह, एक जुड़वाँ भाई है - Writer
. इसका उतना ही बड़ा फायदा है Reader
- यह पात्रों के साथ काम करने के लिए एक सुविधाजनक इंटरफ़ेस प्रदान करता है। आउटपुट स्ट्रीम के साथ, समस्या और इसका समाधान इनपुट स्ट्रीम के समान ही दिखता है। एक वर्ग है OutputStream
जो केवल बाइट लिख सकता है, एक हैWriter
अमूर्त वर्ग जो पात्रों के साथ काम करना जानता है, और दो असंगत इंटरफेस हैं। यह समस्या एक बार फिर एडॉप्टर पैटर्न द्वारा हल हो गई है। हम कक्षा का उपयोग आसानी से और कक्षाओं OutputStreamWriter
के दो इंटरफेस को एक दूसरे के अनुकूल बनाने के लिए करते हैं। कन्स्ट्रक्टर को बाइट स्ट्रीम पास करने के बाद , हम बाइट्स के बजाए वर्ण लिखने के लिए उपयोग कर सकते हैं! Writer
OutputStream
OutputStream
OutputStreamWriter
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
OutputStreamWriter streamWriter = new OutputStreamWriter(new FileOutputStream("C:\\Users\\Username\\Desktop\\test.txt"));
streamWriter.write(32144);
streamWriter.close();
}
}
हमने बाइट्स के साथ काम करने की आवश्यकता को समाप्त करते हुए, अपनी फ़ाइल में कोड 32144 (綐) के साथ वर्ण लिखा :) आज के लिए बस इतना ही। अगले पाठों में मिलते हैं! :)
GO TO FULL VERSION