హాయ్! ఈ రోజు మనం ఒక ముఖ్యమైన కొత్త అంశంపై తాకుతాము: డిజైన్ నమూనాలు . ఈ నమూనాలు ఏమిటి? " చక్రాన్ని తిరిగి ఆవిష్కరించవద్దు " అనే వ్యక్తీకరణ మీకు తప్పక తెలిసి ఉంటుందని నేను భావిస్తున్నాను . ప్రోగ్రామింగ్లో, అనేక ఇతర ప్రాంతాలలో వలె, పెద్ద సంఖ్యలో సాధారణ పరిస్థితులు ఉన్నాయి. సాఫ్ట్వేర్ అభివృద్ధి అభివృద్ధి చెందడంతో, వాటిలో ప్రతిదానికి పని చేసే రెడీమేడ్ పరిష్కారాలు సృష్టించబడ్డాయి. ఈ పరిష్కారాలను డిజైన్ నమూనాలు అంటారు. సంప్రదాయం ప్రకారం, ఒక నమూనా అనేది ఈ విధంగా రూపొందించబడిన కొన్ని పరిష్కారం: "మీరు మీ ప్రోగ్రామ్లో X చేయవలసి వస్తే, దీన్ని చేయడానికి ఇదే ఉత్తమ మార్గం". చాలా నమూనాలు ఉన్నాయి. మీరు ఖచ్చితంగా తెలిసి ఉండవలసిన అద్భుతమైన పుస్తకం "హెడ్ ఫస్ట్ డిజైన్ ప్యాటర్న్స్" వారికి అంకితం చేయబడింది.
సంక్షిప్తంగా చెప్పాలంటే, ఒక నమూనా సాధారణ సమస్య మరియు ఒక రకమైన ప్రమాణంగా పరిగణించబడే సంబంధిత పరిష్కారాన్ని కలిగి ఉంటుంది. నేటి పాఠంలో, మేము ఈ నమూనాలలో ఒకదానిని కలుస్తాము: అడాప్టర్. దీని పేరు అన్నింటినీ చెబుతుంది మరియు మీరు నిజ జీవితంలో చాలా సార్లు అడాప్టర్లను ఎదుర్కొన్నారు. చాలా కంప్యూటర్లు మరియు ల్యాప్టాప్లు కలిగి ఉండే కార్డ్ రీడర్లు అత్యంత సాధారణ అడాప్టర్లలో కొన్ని.
మన దగ్గర ఏదో ఒక మెమరీ కార్డ్ ఉంది అనుకుందాం. కాబట్టి సమస్య ఏమిటి? కంప్యూటర్తో ఎలా ఇంటరాక్ట్ అవ్వాలో దానికి తెలియదు. వారు సాధారణ ఇంటర్ఫేస్ని పంచుకోరు. కంప్యూటర్లో USB పోర్ట్ ఉంది, కానీ మేము దానిలో మెమరీ కార్డ్ని చొప్పించలేము. కార్డ్ని కంప్యూటర్లో ప్లగ్ చేయడం సాధ్యం కాదు, కాబట్టి మేము మా ఫోటోలు, వీడియోలు మరియు ఇతర డేటాను సేవ్ చేయలేము. కార్డ్ రీడర్ అనేది ఈ సమస్యను పరిష్కరించే అడాప్టర్. అన్నింటికంటే, దీనికి USB కేబుల్ ఉంది! కార్డ్లా కాకుండా, కార్డ్ రీడర్ను కంప్యూటర్లోకి ప్లగ్ చేయవచ్చు. వారు కంప్యూటర్తో ఒక సాధారణ ఇంటర్ఫేస్ను పంచుకుంటారు: USB. ఇది ఆచరణలో ఎలా కనిపిస్తుందో చూద్దాం:
పద్ధతుల సమితి ఖచ్చితంగా ఇంటర్ఫేస్ అంటే ఏమిటి. మీరు గమనిస్తే, ఈ తరగతికి ఒక ఉంది
అయితే,
మరియు మా
![అడాప్టర్ డిజైన్ నమూనా - 2](https://cdn.codegym.cc/images/article/6594b8f4-4388-480b-b09f-ad56d99661ba/512.jpeg)
![అడాప్టర్ డిజైన్ నమూనా - 3](https://cdn.codegym.cc/images/article/18ae3c86-996a-4263-af73-993c26442b76/800.jpeg)
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
వియుక్త తరగతి ఉంది. ఇది చాలా ఉపయోగకరమైన కార్యాచరణను కలిగి ఉంది - ఇది అక్షరాలను ఎలా చదవాలో తెలుసు! మాకు ఖచ్చితంగా ఈ సామర్థ్యం అవసరం. కానీ ఇక్కడ మేము సాధారణంగా అడాప్టర్ల ద్వారా పరిష్కరించబడే క్లాసిక్ సమస్యను ఎదుర్కొంటాము - అననుకూల ఇంటర్ఫేస్లు. అంటే ఏమిటి? ఒరాకిల్ డాక్యుమెంటేషన్ను పరిశీలిద్దాం. ఇక్కడ తరగతి పద్ధతులు ఉన్నాయి InputStream
. ![అడాప్టర్ డిజైన్ నమూనా - 4](https://cdn.codegym.cc/images/article/51cb5c89-3ef3-4789-b4fd-1832bfea16ee/800.jpeg)
read()
పద్ధతి (వాస్తవానికి కొన్ని రకాలు), కానీ ఇది బైట్లను మాత్రమే చదవగలదు: వ్యక్తిగత బైట్లు లేదా బఫర్ని ఉపయోగించి అనేక బైట్లు. కానీ ఈ ఎంపిక మాకు సరిపోదు — మేము అక్షరాలను చదవాలనుకుంటున్నాము. వియుక్త తరగతిలో ఇప్పటికే అమలు చేయబడినReader
కార్యాచరణ మాకు అవసరం . మనం దీనిని డాక్యుమెంటేషన్లో కూడా చూడవచ్చు. ![అడాప్టర్ డిజైన్ నమూనా - 5](https://cdn.codegym.cc/images/article/90d6b757-f59b-4bbc-9a7e-90ebe9a0d302/800.jpeg)
InputStream
మరియు Reader
ఇంటర్ఫేస్లు అననుకూలంగా ఉన్నాయి! మీరు గమనిస్తే, read()
పద్ధతి యొక్క ప్రతి అమలు వేర్వేరు పారామితులు మరియు రిటర్న్ విలువలను కలిగి ఉంటుంది. మరియు ఇక్కడే మనకు కావాలి InputStreamReader
! ఇది మా తరగతుల మధ్య అడాప్టర్గా పని చేస్తుంది .మేము పైన పరిగణించిన కార్డ్ రీడర్తో ఉదాహరణలో వలె, మేము అడాప్టర్ క్లాస్లో "లోపల" తరగతిని స్వీకరించడానికి ఒక ఉదాహరణను ఉంచాము, అనగా మేము దాని కన్స్ట్రక్టర్కు ఒకదానిని పాస్ చేస్తాము. మునుపటి ఉదాహరణలో, మేము ఒక MemoryCard
వస్తువును లోపల ఉంచాము CardReader
. InputStream
ఇప్పుడు మేము ఒక వస్తువును కన్స్ట్రక్టర్కి పంపుతున్నాము InputStreamReader
! మేము మనకు తెలిసిన System.in
వేరియబుల్ని ఇలా ఉపయోగిస్తాము InputStream
:
public static void main(String[] args) {
InputStreamReader inputStreamReader = new InputStreamReader(System.in);
}
మరియు నిజానికి, కోసం డాక్యుమెంటేషన్ని చూస్తే InputStreamReader
, అనుసరణ విజయవంతమైందని మనం చూడవచ్చు :) ఇప్పుడు మన వద్ద అక్షరాలను చదవడానికి పద్ధతులు ఉన్నాయి. ![అడాప్టర్ డిజైన్ నమూనా - 6](https://cdn.codegym.cc/images/article/12ebb20e-96ec-43b9-b5cf-2fdc3ffcb0cb/800.jpeg)
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 (綐) కోడ్తో అక్షరాన్ని వ్రాసాము :) అంతే. తదుపరి పాఠాలలో కలుద్దాం! :)