CodeGym /జావా బ్లాగ్ /యాదృచ్ఛికంగా /అడాప్టర్ డిజైన్ నమూనా ఏ సమస్యలను పరిష్కరిస్తుంది?
John Squirrels
స్థాయి
San Francisco

అడాప్టర్ డిజైన్ నమూనా ఏ సమస్యలను పరిష్కరిస్తుంది?

సమూహంలో ప్రచురించబడింది
కలిసి పని చేయాల్సిన అననుకూల భాగాల ద్వారా సాఫ్ట్‌వేర్ అభివృద్ధి మరింత కష్టతరం అవుతుంది. ఉదాహరణకు, మీరు జావా యొక్క మునుపటి సంస్కరణల్లో వ్రాసిన పాత ప్లాట్‌ఫారమ్‌తో కొత్త లైబ్రరీని ఏకీకృతం చేయవలసి వస్తే, మీరు అననుకూలమైన వస్తువులు లేదా అననుకూలమైన ఇంటర్‌ఫేస్‌లను ఎదుర్కోవచ్చు. అడాప్టర్ డిజైన్ నమూనా ఏ సమస్యలను పరిష్కరిస్తుంది?  - 1ఈ సందర్భంలో ఏమి చేయాలి? కోడ్‌ని మళ్లీ వ్రాయాలా? మేము అలా చేయలేము, ఎందుకంటే సిస్టమ్‌ను విశ్లేషించడానికి చాలా సమయం పడుతుంది లేదా అప్లికేషన్ యొక్క అంతర్గత తర్కం ఉల్లంఘించబడుతుంది. ఈ సమస్యను పరిష్కరించడానికి, అడాప్టర్ నమూనా సృష్టించబడింది. ఇది అననుకూలమైన ఇంటర్‌ఫేస్‌లను కలిగి ఉన్న వస్తువులు కలిసి పనిచేయడానికి సహాయపడుతుంది. దీన్ని ఎలా ఉపయోగించాలో చూద్దాం!

సమస్య గురించి మరింత

ముందుగా, మేము పాత సిస్టమ్ యొక్క ప్రవర్తనను అనుకరిస్తాము. పని చేయడానికి లేదా పాఠశాలకు ఆలస్యంగా వచ్చినందుకు ఇది సాకులు సృష్టిస్తుందని అనుకుందాం. దీన్ని చేయడానికి, ఇది , మరియు పద్ధతులను Excuseకలిగి ఉన్న ఇంటర్‌ఫేస్‌ను కలిగి ఉంది . generateExcuse()likeExcuse()dislikeExcuse()

public interface Excuse {
   String generateExcuse();
   void likeExcuse(String excuse);
   void dislikeExcuse(String excuse);
}
తరగతి WorkExcuseఈ ఇంటర్‌ఫేస్‌ని అమలు చేస్తుంది:

public class WorkExcuse implements Excuse {
   private String[] excuses = {"in an incredible confluence of circumstances, I ran out of hot water and had to wait until sunlight, focused using a magnifying glass, heated a mug of water so that I could wash.",
   "the artificial intelligence in my alarm clock failed me, waking me up an hour earlier than normal. Because it is winter, I thought it was still nighttime and I fell back asleep. Everything after that is a bit hazy.",
   "my pre-holiday mood slows metabolic processes in my body, leading to depression and insomnia."};
   private String [] apologies = {"This will not happen again, of course. I'm very sorry.", "I apologize for my unprofessional behavior.", "There is no excuse for my actions. I am not worthy of this position."};

   @Override
   public String generateExcuse() { // Randomly select an excuse from the array
       String result = "I was late today because " + excuses[(int) Math.round(Math.random() + 1)] + "\\n" +
               apologies[(int) Math.round(Math.random() + 1)];
       return result;
   }

   @Override
   public void likeExcuse(String excuse) {
       // Duplicate the element in the array so that its chances of being chosen are higher
   }

   @Override
   public void dislikeExcuse(String excuse) {
       // Remove the item from the array
   }
}
మన ఉదాహరణను పరీక్షిద్దాం:

Excuse excuse = new WorkExcuse();
System.out.println(excuse.generateExcuse());
అవుట్‌పుట్:

"I was late today because my pre-holiday mood slows metabolic processes in my body, leading to depression and insomnia.
I apologize for my unprofessional behavior.
ఇప్పుడు మీరు ఒక సాకు-ఉత్పత్తి సేవను ప్రారంభించారని, గణాంకాలను సేకరించారని మరియు మీ వినియోగదారులలో ఎక్కువ మంది యూనివర్శిటీ విద్యార్థులని గమనించారని ఊహించుకోండి. ఈ సమూహానికి మెరుగైన సేవలందించేందుకు, యూనివర్సిటీ విద్యార్థుల కోసం ప్రత్యేకంగా సాకులు చెప్పే వ్యవస్థను రూపొందించమని మీరు మరొక డెవలపర్‌ని కోరారు. డెవలప్‌మెంట్ బృందం మార్కెట్ పరిశోధనను నిర్వహించింది, సాకులను ర్యాంక్ చేసింది, కొంత కృత్రిమ మేధస్సును హుక్ అప్ చేసింది మరియు ట్రాఫిక్ నివేదికలు, వాతావరణ నివేదికలు మొదలైన వాటితో సేవను ఏకీకృతం చేసింది. ఇప్పుడు మీరు విశ్వవిద్యాలయ విద్యార్థుల కోసం సాకులను రూపొందించడానికి లైబ్రరీని కలిగి ఉన్నారు, కానీ దీనికి వేరే ఇంటర్‌ఫేస్ ఉంది: StudentExcuse.

public interface StudentExcuse {
   String generateExcuse();
   void dislikeExcuse(String excuse);
}
ఈ ఇంటర్‌ఫేస్‌కు రెండు పద్ధతులు ఉన్నాయి: generateExcuse, ఇది ఒక సాకును ఉత్పత్తి చేస్తుంది మరియు dislikeExcuse, భవిష్యత్తులో మళ్లీ కనిపించకుండా సాకును నిరోధిస్తుంది. మూడవ పక్షం లైబ్రరీని సవరించడం సాధ్యం కాదు, అంటే మీరు దాని సోర్స్ కోడ్‌ని మార్చలేరు. ఇప్పుడు మనకు ఉన్నది ఇంటర్‌ఫేస్‌ను అమలు చేసే రెండు తరగతులతో కూడిన సిస్టమ్ మరియు ఇంటర్‌ఫేస్‌ను అమలు చేసే తరగతితో Excuseలైబ్రరీ : SuperStudentExcuseStudentExcuse

public class SuperStudentExcuse implements StudentExcuse {
   @Override
   public String generateExcuse() {
       // Logic for the new functionality
       return "An incredible excuse adapted to the current weather conditions, traffic jams, or delays in public transport schedules.";
   }

   @Override
   public void dislikeExcuse(String excuse) {
       // Adds the reason to a blacklist
   }
}
కోడ్ మార్చబడదు. ప్రస్తుత తరగతి సోపానక్రమం ఇలా కనిపిస్తుంది: అడాప్టర్ డిజైన్ నమూనా ఏ సమస్యలను పరిష్కరిస్తుంది?  - 2సిస్టమ్ యొక్క ఈ సంస్కరణ కేవలం ఎక్స్‌క్యూస్ ఇంటర్‌ఫేస్‌తో మాత్రమే పని చేస్తుంది. మీరు కోడ్‌ను తిరిగి వ్రాయలేరు: పెద్ద అప్లికేషన్‌లో, అటువంటి మార్పులు చేయడం సుదీర్ఘ ప్రక్రియగా మారవచ్చు లేదా అప్లికేషన్ యొక్క తర్కాన్ని విచ్ఛిన్నం చేయవచ్చు. మేము బేస్ ఇంటర్‌ఫేస్‌ను పరిచయం చేయవచ్చు మరియు సోపానక్రమాన్ని విస్తరించవచ్చు: అడాప్టర్ డిజైన్ నమూనా ఏ సమస్యలను పరిష్కరిస్తుంది?  - 3దీన్ని చేయడానికి, మేము ఇంటర్‌ఫేస్ పేరు మార్చాలి Excuse. కానీ తీవ్రమైన అనువర్తనాల్లో అదనపు సోపానక్రమం అవాంఛనీయమైనది: సాధారణ మూల మూలకాన్ని పరిచయం చేయడం నిర్మాణాన్ని విచ్ఛిన్నం చేస్తుంది. మీరు తక్కువ నష్టాలతో కొత్త మరియు పాత ఫంక్షనాలిటీని ఉపయోగించడానికి అనుమతించే ఇంటర్మీడియట్ తరగతిని అమలు చేయాలి. సంక్షిప్తంగా, మీకు అడాప్టర్ అవసరం .

అడాప్టర్ నమూనా వెనుక సూత్రం

అడాప్టర్ అనేది ఇంటర్మీడియట్ వస్తువు, ఇది ఒక వస్తువు యొక్క పద్ధతి కాల్‌లను మరొకరికి అర్థం చేసుకోవడానికి అనుమతిస్తుంది. మన ఉదాహరణ కోసం అడాప్టర్‌ని అమలు చేసి, దానిని కాల్ చేద్దాం Middleware. మా అడాప్టర్ తప్పనిసరిగా ఆబ్జెక్ట్‌లలో ఒకదానికి అనుకూలంగా ఉండే ఇంటర్‌ఫేస్‌ను అమలు చేయాలి. అది ఉండనివ్వండి Excuse. ఇది Middlewareమొదటి వస్తువు యొక్క పద్ధతులను కాల్ చేయడానికి అనుమతిస్తుంది. Middlewareకాల్‌లను స్వీకరిస్తుంది మరియు వాటిని రెండవ ఆబ్జెక్ట్‌కు అనుకూల మార్గంలో ఫార్వార్డ్ చేస్తుంది. మరియు Middlewareపద్ధతులతో అమలు చేయడం ఇక్కడ ఉంది : generateExcusedislikeExcuse

public class Middleware implements Excuse { // 1. Middleware becomes compatible with WorkExcuse objects via the Excuse interface

   private StudentExcuse superStudentExcuse;

   public Middleware(StudentExcuse excuse) { // 2. Get a reference to the object being adapted
       this.superStudentExcuse = excuse;
   }

   @Override
   public String generateExcuse() {
       return superStudentExcuse.generateExcuse(); // 3. The adapter implements an interface method
   }

    @Override
    public void dislikeExcuse(String excuse) {
        // The method first adds the excuse to the blacklist,
        // Then passes it to the dislikeExcuse method of the superStudentExcuse object.
    }
   // The likeExcuse method will appear later
}
పరీక్ష (క్లయింట్ కోడ్‌లో):

public class Test {
   public static void main(String[] args) {
       Excuse excuse = new WorkExcuse(); // We create objects of the classes
       StudentExcuse newExcuse = new SuperStudentExcuse(); // that must be compatible.
       System.out.println("An ordinary excuse for an employee:");
       System.out.println(excuse.generateExcuse());
       System.out.println("\n");
       Excuse adaptedStudentExcuse = new Middleware(newExcuse); // Wrap the new functionality in the adapter object
       System.out.println("Using new functionality with the adapter:");
       System.out.println(adaptedStudentExcuse.generateExcuse()); // The adapter calls the adapted method
   }
}
అవుట్‌పుట్:

An ordinary excuse for an employee:
I was late today because my pre-holiday mood slows metabolic processes in my body, leading to depression and insomnia.
There is no excuse for my actions. I am not worthy of this position. Using new functionality with the adapter:
ప్రస్తుత వాతావరణ పరిస్థితులు, ట్రాఫిక్ జామ్‌లు లేదా ప్రజా రవాణా షెడ్యూల్‌లలో జాప్యాలకు అనుగుణంగా నమ్మశక్యం కాని సాకు. పద్ధతి generateExcuseఏ అదనపు మార్పులు లేకుండా, మరొక వస్తువుకు కాల్‌ను పంపుతుంది. పద్దతి dislikeExcuseమాకు ముందుగా సాకును బ్లాక్‌లిస్ట్ చేయాలి. ఇంటర్మీడియట్ డేటా ప్రాసెసింగ్ చేయగల సామర్థ్యం ప్రజలు అడాప్టర్ నమూనాను ఇష్టపడటానికి కారణం. కానీ ఇంటర్‌ఫేస్‌లో likeExcuseభాగం Excuseకాని ఇంటర్‌ఫేస్‌లో భాగం కాని పద్ధతి గురించి ఏమిటి StudentExcuse? కొత్త ఫంక్షనాలిటీ ఈ ఆపరేషన్‌కు మద్దతు ఇవ్వదు. UnsupportedOperationExceptionఈ పరిస్థితి కోసం కనుగొనబడింది . అభ్యర్థించిన ఆపరేషన్‌కు మద్దతు లేకుంటే అది విసిరివేయబడుతుంది. దాన్ని వాడుకుందాం. Middlewareతరగతి యొక్క కొత్త అమలు ఇలా కనిపిస్తుంది:

public class Middleware implements Excuse {

   private StudentExcuse superStudentExcuse;

   public Middleware(StudentExcuse excuse) {
       this.superStudentExcuse = excuse;
   }

   @Override
   public String generateExcuse() {
       return superStudentExcuse.generateExcuse();
   }

   @Override
   public void likeExcuse(String excuse) {
       throw new UnsupportedOperationException("The likeExcuse method is not supported by the new functionality");
   }

   @Override
   public void dislikeExcuse(String excuse) {
       // The method accesses a database to fetch additional information,
       // and then passes it to the superStudentExcuse object's dislikeExcuse method.
   }
}
మొదటి చూపులో, ఈ పరిష్కారం చాలా మంచిది కాదు, కానీ కార్యాచరణను అనుకరించడం పరిస్థితిని క్లిష్టతరం చేస్తుంది. క్లయింట్ శ్రద్ధ వహిస్తే, మరియు అడాప్టర్ చక్కగా నమోదు చేయబడితే, అటువంటి పరిష్కారం ఆమోదయోగ్యమైనది.

అడాప్టర్‌ను ఎప్పుడు ఉపయోగించాలి

  1. మీరు మూడవ పక్ష తరగతిని ఉపయోగించాల్సిన అవసరం వచ్చినప్పుడు, కానీ దాని ఇంటర్‌ఫేస్ ప్రధాన అనువర్తనానికి అనుకూలంగా ఉండదు. లక్ష్య వస్తువు అర్థం చేసుకోగలిగే ఫార్మాట్‌లో కాల్‌లను చుట్టే అడాప్టర్ ఆబ్జెక్ట్‌ను ఎలా సృష్టించాలో పై ఉదాహరణ చూపిస్తుంది.

  2. ఇప్పటికే ఉన్న అనేక సబ్‌క్లాస్‌లకు కొన్ని సాధారణ కార్యాచరణ అవసరమైనప్పుడు. అదనపు సబ్‌క్లాస్‌లను సృష్టించే బదులు (ఇది కోడ్ యొక్క నకిలీకి దారి తీస్తుంది), అడాప్టర్‌ను ఉపయోగించడం మంచిది.

ప్రయోజనాలు మరియు అప్రయోజనాలు

అడ్వాంటేజ్: అడాప్టర్ క్లయింట్ నుండి ఒక వస్తువు నుండి మరొక వస్తువుకు అభ్యర్థనలను ప్రాసెస్ చేసే వివరాలను దాచిపెడుతుంది. క్లయింట్ కోడ్ డేటాను ఫార్మాట్ చేయడం లేదా లక్ష్య పద్ధతికి కాల్‌లను నిర్వహించడం గురించి ఆలోచించదు. ఇది చాలా క్లిష్టంగా ఉంది మరియు ప్రోగ్రామర్లు సోమరితనం :) ప్రతికూలత: ప్రాజెక్ట్ యొక్క కోడ్ బేస్ అదనపు తరగతుల ద్వారా సంక్లిష్టంగా ఉంటుంది. మీకు చాలా అననుకూల ఇంటర్‌ఫేస్‌లు ఉంటే, అదనపు తరగతుల సంఖ్య నిర్వహించలేనిదిగా మారవచ్చు.

అడాప్టర్‌ను ముఖభాగం లేదా డెకరేటర్‌తో కంగారు పెట్టవద్దు

కేవలం ఉపరితల తనిఖీతో, అడాప్టర్ ముఖభాగం మరియు డెకరేటర్ నమూనాలతో గందరగోళం చెందుతుంది. అడాప్టర్ మరియు ముఖభాగం మధ్య వ్యత్యాసం ఏమిటంటే, ముఖభాగం కొత్త ఇంటర్‌ఫేస్‌ను పరిచయం చేస్తుంది మరియు మొత్తం సబ్‌సిస్టమ్‌ను చుట్టేస్తుంది. మరియు డెకరేటర్, అడాప్టర్‌లా కాకుండా, ఇంటర్‌ఫేస్ కాకుండా వస్తువును మారుస్తుంది.

దశల వారీ అల్గోరిథం

  1. ముందుగా, ఈ నమూనా పరిష్కరించగల సమస్య మీకు ఉందని నిర్ధారించుకోండి.

  2. అననుకూల వస్తువులతో పరోక్షంగా పరస్పర చర్య చేయడానికి ఉపయోగించే క్లయింట్ ఇంటర్‌ఫేస్‌ను నిర్వచించండి.

  3. మునుపటి దశలో నిర్వచించిన ఇంటర్‌ఫేస్‌ను అడాప్టర్ క్లాస్ వారసత్వంగా పొందేలా చేయండి.

  4. అడాప్టర్ క్లాస్‌లో, అడాప్టీ ఆబ్జెక్ట్‌కు సూచనను నిల్వ చేయడానికి ఫీల్డ్‌ను సృష్టించండి. ఈ సూచన కన్స్ట్రక్టర్‌కు పంపబడింది.

  5. అడాప్టర్‌లో అన్ని క్లయింట్ ఇంటర్‌ఫేస్ పద్ధతులను అమలు చేయండి. ఒక పద్ధతి ఉండవచ్చు:

    • ఎటువంటి మార్పులు చేయకుండా కాల్‌లను పాస్ చేయండి

    • డేటాను సవరించడం లేదా అనుబంధించడం, లక్ష్య పద్ధతికి కాల్‌ల సంఖ్యను పెంచడం/తగ్గించడం మొదలైనవి.

    • విపరీతమైన సందర్భాల్లో, ఒక నిర్దిష్ట పద్ధతి విరుద్ధంగా ఉంటే, మద్దతు లేని ఆపరేషన్ ఎక్సెప్షన్‌ను వేయండి. మద్దతు లేని కార్యకలాపాలు ఖచ్చితంగా డాక్యుమెంట్ చేయబడాలి.

  6. అప్లికేషన్ క్లయింట్ ఇంటర్‌ఫేస్ ద్వారా అడాప్టర్ క్లాస్‌ను మాత్రమే ఉపయోగిస్తే (పై ఉదాహరణలో వలె), అప్పుడు అడాప్టర్ భవిష్యత్తులో నొప్పిలేకుండా విస్తరించబడుతుంది.

వాస్తవానికి, ఈ డిజైన్ నమూనా అన్ని అనారోగ్యాలకు వినాశనం కాదు, కానీ విభిన్న ఇంటర్‌ఫేస్‌లతో వస్తువుల మధ్య అననుకూలత సమస్యను చక్కగా పరిష్కరించడంలో ఇది మీకు సహాయపడుతుంది. ప్రాథమిక నమూనాలను తెలిసిన డెవలపర్ అల్గారిథమ్‌లను ఎలా వ్రాయాలో మాత్రమే తెలిసిన వారి కంటే చాలా అడుగులు ముందుకు ఉంటాడు, ఎందుకంటే తీవ్రమైన అప్లికేషన్‌లను రూపొందించడానికి డిజైన్ నమూనాలు అవసరం. కోడ్ పునర్వినియోగం అంత కష్టం కాదు మరియు నిర్వహణ ఆనందదాయకంగా మారుతుంది. నేటికీ అంతే! కానీ మేము త్వరలో వివిధ డిజైన్ నమూనాలను తెలుసుకోవడం కొనసాగిస్తాము :)
వ్యాఖ్యలు
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION