हाय! आज आपण एका महत्त्वाच्या नवीन विषयाला स्पर्श करू: डिझाइन नमुने . हे नमुने काय आहेत? मला वाटते की तुम्हाला " चाक पुन्हा शोधू नका " हे वाक्य माहित असले पाहिजे . प्रोग्रामिंगमध्ये, इतर अनेक क्षेत्रांप्रमाणे, मोठ्या संख्येने सामान्य परिस्थिती आहेत. सॉफ्टवेअर डेव्हलपमेंट जसजसे विकसित होत गेले, तसतसे त्या प्रत्येकासाठी कार्य करणारे तयार समाधान तयार केले गेले. या उपायांना डिझाइन पॅटर्न म्हणतात. नियमानुसार, पॅटर्न हे असे काही उपाय तयार केले जातात: "तुम्हाला तुमच्या प्रोग्राममध्ये X करायचे असल्यास, ते करण्याचा हा सर्वोत्तम मार्ग आहे". बरेच नमुने आहेत. "हेड फर्स्ट डिझाईन पॅटर्न" हे उत्कृष्ट पुस्तक, जे तुम्हाला नक्कीच परिचित झाले पाहिजे, त्यांना समर्पित आहे. थोडक्यात सांगायचे तर, पॅटर्नमध्ये एक सामान्य समस्या आणि संबंधित समाधान असते जे एक प्रकारचे मानक मानले जाऊ शकते. आजच्या धड्यात, आपण यापैकी एक नमुना भेटू: अडॅप्टर. त्याचे नाव हे सर्व सांगते आणि तुम्हाला वास्तविक जीवनात अनेक वेळा अडॅप्टरचा सामना करावा लागला आहे. काही सर्वात सामान्य अडॅप्टर हे कार्ड रीडर आहेत जे अनेक संगणक आणि लॅपटॉपमध्ये असतात. समजा आपल्याकडे काही प्रकारचे मेमरी कार्ड आहे. मग अडचण काय आहे? संगणकाशी संवाद कसा साधावा हे कळत नाही. ते सामान्य इंटरफेस सामायिक करत नाहीत. संगणकाला 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 इंटरफेस लागू करतो. पण या पद्धतीत नेमके काय होते? नक्की काय व्हायला हवे! अडॅप्टर आमच्या मेमरी कार्डला काम सोपवतो. खरंच, अडॅप्टर स्वतः काहीही करत नाही. कार्ड रीडरमध्ये कोणतीही स्वतंत्र कार्यक्षमता नसते. त्याचे काम फक्त संगणक आणि मेमरी कार्डला जोडणे आहे जेणेकरून कार्डला त्याचे कार्य करू द्या - फायली कॉपी करणे!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
अमूर्त वर्ग आहे. यात काही अतिशय उपयुक्त कार्यक्षमता आहे — अक्षरे कशी वाचायची हे माहीत आहे! आपल्याला ही क्षमता नक्कीच हवी आहे. परंतु येथे आम्हाला अॅडॉप्टर - विसंगत इंटरफेसद्वारे सोडवलेल्या क्लासिक समस्येचा सामना करावा लागतो. याचा अर्थ काय? चला ओरॅकल दस्तऐवजीकरण पाहू. येथे वर्गाच्या पद्धती आहेत 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
दोन इंटरफेस एकमेकांशी सहजपणे जुळवून घेण्यासाठी आम्ही वर्ग वापरतो . कन्स्ट्रक्टरला बाइट स्ट्रीम दिल्यानंतर , आम्ही बाइट्सऐवजी अक्षरे लिहिण्यासाठी an वापरू शकतो! 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