CodeGym /జావా బ్లాగ్ /యాదృచ్ఛికంగా /వ్యూహ రూపకల్పన నమూనా
John Squirrels
స్థాయి
San Francisco

వ్యూహ రూపకల్పన నమూనా

సమూహంలో ప్రచురించబడింది
హాయ్! నేటి పాఠంలో, మేము వ్యూహ నమూనా గురించి మాట్లాడుతాము. మునుపటి పాఠాలలో, మేము ఇప్పటికే వారసత్వ భావనతో క్లుప్తంగా పరిచయం చేసుకున్నాము. మీరు మరచిపోయినట్లయితే, ఈ పదం సాధారణ ప్రోగ్రామింగ్ టాస్క్‌కి ప్రామాణిక పరిష్కారాన్ని సూచిస్తుందని నేను మీకు గుర్తు చేస్తాను. కోడ్‌జిమ్‌లో, మీరు దాదాపు ఏ ప్రశ్నకైనా గూగుల్‌లో సమాధానం ఇవ్వవచ్చని మేము తరచుగా చెబుతాము. ఎందుకంటే మీ పని, అది ఏమైనా, బహుశా ఇప్పటికే ఎవరైనా విజయవంతంగా పరిష్కరించారు. నమూనాలు అత్యంత సాధారణ పనులకు ప్రయత్నించిన మరియు నిజమైన పరిష్కారాలు లేదా సమస్యాత్మక పరిస్థితులను పరిష్కరించడానికి పద్ధతులు. ఇవి "చక్రాలు" లాగా ఉంటాయి, వీటిని మీరు మీ స్వంతంగా మళ్లీ ఆవిష్కరించాల్సిన అవసరం లేదు, కానీ వాటిని ఎలా మరియు ఎప్పుడు ఉపయోగించాలో మీరు తెలుసుకోవాలి :) నమూనాల కోసం మరొక ప్రయోజనం ఏకరీతి నిర్మాణాన్ని ప్రోత్సహించడం. వేరొకరి కోడ్ చదవడం అంత తేలికైన పని కాదు! ప్రతి ఒక్కరూ వేర్వేరు కోడ్‌లను వ్రాస్తారు, ఎందుకంటే ఒకే పనిని అనేక విధాలుగా పరిష్కరించవచ్చు. కానీ నమూనాల ఉపయోగం వివిధ ప్రోగ్రామర్‌లు ప్రోగ్రామింగ్ లాజిక్‌ను అర్థం చేసుకోవడంలో ప్రతి కోడ్‌ను (మొదటిసారి చూసినప్పుడు కూడా!) ఈరోజు మనం "స్ట్రాటజీ" అని పిలవబడే అత్యంత సాధారణ డిజైన్ నమూనాలను పరిశీలిస్తాము. డిజైన్ నమూనా: వ్యూహం - 2మేము ఒక ప్రోగ్రామ్‌ని వ్రాస్తున్నామని ఊహించుకోండి, అది యాక్టివ్‌గా రవాణా చేసే వస్తువులతో పని చేస్తుంది. మా ప్రోగ్రామ్ సరిగ్గా ఏమి చేస్తుందనేది నిజంగా పట్టింపు లేదు. మేము ఒక రవాణా పేరెంట్ క్లాస్ మరియు మూడు చైల్డ్ క్లాస్‌లతో క్లాస్ హైరార్కీని సృష్టించాము : సెడాన్ , ట్రక్ మరియు F1Car .

public class Conveyance {

   public void go() {
       System.out.println("Moving forward");
   }

   public void stop() {

       System.out.println("Braking!");
   }
}

public class Sedan extends Conveyance {
}

public class Truck extends Conveyance {
}

public class F1Car extends Conveyance {
}
మూడు పిల్లల తరగతులు తల్లిదండ్రుల నుండి రెండు ప్రామాణిక పద్ధతులను వారసత్వంగా పొందుతాయి: go() మరియు stop() . మా ప్రోగ్రామ్ చాలా సులభం: మా కార్లు మాత్రమే ముందుకు కదులుతాయి మరియు బ్రేక్‌లను వర్తింపజేయగలవు. మా పనిని కొనసాగిస్తూ, మేము కార్లకు కొత్త పద్ధతిని ఇవ్వాలని నిర్ణయించుకున్నాము: పూరించండి () (అంటే, "గ్యాస్ ట్యాంక్ నింపండి"). మేము దానిని రవాణా మాతృ తరగతికి జోడించాము :

public class Conveyance {

   public void go() {
       System.out.println("Moving forward");
   }

   public void stop() {

       System.out.println("Braking!");
   }
  
   public void fill() {
       System.out.println("Refueling!");
   }
}
అటువంటి సాధారణ పరిస్థితిలో సమస్యలు నిజంగా తలెత్తగలవా? నిజానికి, వారు ఇప్పటికే... డిజైన్ నమూనా: వ్యూహం - 3

public class Stroller extends Conveyance {

   public void fill() {
      
       // Hmm... This is a stroller for children. It doesn't need to be refueled :/
   }
}
మా ప్రోగ్రామ్‌లో ఇప్పుడు సాధారణ కాన్సెప్ట్‌కి సరిగ్గా సరిపోని రవాణా (బేబీ స్త్రోలర్) ఉంది. ఇది పెడల్‌లను కలిగి ఉండవచ్చు లేదా రేడియో-నియంత్రితంగా ఉండవచ్చు, కానీ ఒక విషయం ఖచ్చితంగా చెప్పవచ్చు - దీనికి గ్యాస్‌ను పోయడానికి స్థలం ఉండదు. మా తరగతి సోపానక్రమం సాధారణ పద్ధతులను అవసరం లేని తరగతుల ద్వారా వారసత్వంగా పొందేలా చేసింది. ఈ పరిస్థితిలో మనం ఏమి చేయాలి? సరే, మేము Stroller క్లాస్‌లో ఫిల్() పద్ధతిని భర్తీ చేయగలము , తద్వారా మీరు స్త్రోలర్‌కి ఇంధనం నింపడానికి ప్రయత్నించినప్పుడు ఏమీ జరగదు:

public class Stroller extends Conveyance {

   @Override
   public void fill() {
       System.out.println("A stroller cannot be refueled!");
   }
}
డూప్లికేట్ కోడ్ తప్ప మరే ఇతర కారణం లేకుండా ఇది విజయవంతమైన పరిష్కారం అని పిలవబడదు. ఉదాహరణకు, చాలా తరగతులు పేరెంట్ క్లాస్ పద్ధతిని ఉపయోగిస్తాయి, కానీ మిగిలినవి దానిని భర్తీ చేయవలసి వస్తుంది. మనకు 15 తరగతులు ఉంటే మరియు వాటిలో 5-6లో ప్రవర్తనను తప్పక భర్తీ చేస్తే, కోడ్ డూప్లికేషన్ చాలా విస్తృతంగా మారుతుంది. బహుశా ఇంటర్‌ఫేస్‌లు మనకు సహాయపడగలవా? ఉదాహరణకు, ఇలా:

public interface Fillable {
  
   public void fill();
}
మేము ఒక పూరకం() పద్ధతితో పూరించదగిన ఇంటర్‌ఫేస్‌ని సృష్టిస్తాము . అప్పుడు, ఇంధనం నింపాల్సిన రవాణాలు ఈ ఇంటర్‌ఫేస్‌ను అమలు చేస్తాయి, అయితే ఇతర రవాణాలు (ఉదాహరణకు, మా బేబీ స్త్రోలర్) అమలు చేయవు. కానీ ఈ ఎంపిక మాకు సరిపోదు. భవిష్యత్తులో, మన తరగతి సోపానక్రమం చాలా పెద్దదిగా మారవచ్చు (ప్రపంచంలో ఎన్ని రకాల రవాణాలు ఉన్నాయో ఊహించుకోండి). మేము పూరక() ని భర్తీ చేయకూడదనుకుంటున్నందున, వారసత్వంతో కూడిన మునుపటి సంస్కరణను మేము వదిలివేసాముపద్ధతి చాలా, చాలా సార్లు. ఇప్పుడు మనం ప్రతి తరగతిలో అమలు చేయాలి! మరియు మనకు 50 ఉంటే? మరియు మా ప్రోగ్రామ్‌లో తరచుగా మార్పులు చేయబడితే (మరియు ఇది నిజమైన ప్రోగ్రామ్‌లకు దాదాపు ఎల్లప్పుడూ వర్తిస్తుంది!), మేము మొత్తం 50 తరగతులను పరుగెత్తాలి మరియు వాటిలో ప్రతి ప్రవర్తనను మాన్యువల్‌గా మార్చాలి. కాబట్టి, చివరికి, ఈ పరిస్థితిలో మనం ఏమి చేయాలి? మా సమస్యను పరిష్కరించడానికి, మేము వేరే మార్గాన్ని ఎంచుకుంటాము. అవి, మేము మా తరగతి ప్రవర్తనను తరగతి నుండి వేరు చేస్తాము. అంటే ఏమిటి? మీకు తెలిసినట్లుగా, ప్రతి వస్తువుకు స్థితి (డేటా సమితి) మరియు ప్రవర్తన (పద్ధతుల సమితి) ఉంటాయి. మా రవాణా తరగతి ప్రవర్తన మూడు పద్ధతులను కలిగి ఉంటుంది: go() , stop() మరియు fill() . మొదటి రెండు పద్ధతులు వాటిలాగే బాగున్నాయి. కానీ మేము మూడవ పద్ధతిని బయటకు తరలిస్తామురవాణా తరగతి. ఇది ప్రవర్తనను తరగతి నుండి వేరు చేస్తుంది (మరింత ఖచ్చితంగా, ఇది ప్రవర్తనలో కొంత భాగాన్ని మాత్రమే వేరు చేస్తుంది, ఎందుకంటే మొదటి రెండు పద్ధతులు అవి ఉన్న చోటనే ఉంటాయి). కాబట్టి మనం మన పూరక () పద్ధతిని ఎక్కడ ఉంచాలి ? ఏదీ గుర్తుకు రావడం లేదు :/ ఇది ఖచ్చితంగా ఎక్కడ ఉండాలో అనిపిస్తుంది. మేము దానిని ప్రత్యేక ఇంటర్‌ఫేస్‌కి తరలిస్తాము: FillStrategy !

public interface FillStrategy {

   public void fill();
}
మనకు అలాంటి ఇంటర్‌ఫేస్ ఎందుకు అవసరం? అంతా సూటిగా ఉంటుంది. ఇప్పుడు మనం ఈ ఇంటర్‌ఫేస్‌ని అమలు చేసే అనేక తరగతులను సృష్టించవచ్చు:

public class HybridFillStrategy implements FillStrategy {
  
   @Override
   public void fill() {
       System.out.println("Refuel with gas or electricity — your choice!");
   }
}

public class F1PitstopStrategy implements FillStrategy {
  
   @Override
   public void fill() {
       System.out.println("Refuel with gas only after all other pit stop procedures are complete!");
   }
}

public class StandardFillStrategy implements FillStrategy {
   @Override
   public void fill() {
       System.out.println("Just refuel with gas!");
   }
}
మేము మూడు ప్రవర్తనా వ్యూహాలను రూపొందించాము: ఒకటి సాధారణ కార్ల కోసం, ఒకటి హైబ్రిడ్‌ల కోసం మరియు ఒకటి ఫార్ములా 1 రేస్ కార్ల కోసం. ప్రతి వ్యూహం విభిన్న రీఫ్యూయలింగ్ అల్గారిథమ్‌ను అమలు చేస్తుంది. మా విషయంలో, మేము కన్సోల్‌లో స్ట్రింగ్‌ను ప్రదర్శిస్తాము, కానీ ప్రతి పద్ధతిలో కొన్ని సంక్లిష్ట తర్కం ఉండవచ్చు. తర్వాత ఏం చేస్తాం?

public class Conveyance {

   FillStrategy fillStrategy;

   public void fill() {
       fillStrategy.fill();
   }

   public void go() {
       System.out.println("Moving forward");
   }

   public void stop() {
       System.out.println("Braking!");
   }
  
}
మేము మా FillStrategy ఇంటర్‌ఫేస్‌ని కన్వేయన్స్ పేరెంట్ క్లాస్‌లో ఫీల్డ్‌గా ఉపయోగిస్తాము. మేము నిర్దిష్ట అమలును సూచించడం లేదని గమనించండి — మేము ఇంటర్‌ఫేస్‌ని ఉపయోగిస్తున్నాము. కార్ క్లాస్‌లకు ఫిల్‌స్ట్రాటజీ ఇంటర్‌ఫేస్ యొక్క నిర్దిష్ట అమలులు అవసరం :

public class F1Car extends Conveyance {

   public F1Car() {
       this.fillStrategy = new F1PitstopStrategy();
   }
}

public class HybridCar extends Conveyance {

   public HybridCar() {
       this.fillStrategy = new HybridFillStrategy();
   }
}

public class Sedan extends Conveyance {

   public Sedan() {
       this.fillStrategy = new StandardFillStrategy();
   }
}

మనకు లభించిన వాటిని చూద్దాం!

public class Main {

   public static void main(String[] args) {

       Conveyance sedan = new Sedan();
       Conveyance hybrid = new HybridCar();
       Conveyance f1car = new F1Car();

       sedan.fill();
       hybrid.fill();
       f1car.fill();
   }
}
కన్సోల్ అవుట్‌పుట్:

Just refuel with gas! 
Refuel with gas or electricity — your choice! 
Refuel with gas only after all other pit stop procedures are complete!
గొప్ప! ఇంధనం నింపే ప్రక్రియ తప్పక పనిచేస్తుంది! మార్గం ద్వారా, కన్స్ట్రక్టర్‌లో వ్యూహాన్ని పారామీటర్‌గా ఉపయోగించకుండా ఏమీ నిరోధించదు! ఉదాహరణకు, ఇలా:

public class Conveyance {

   private FillStrategy fillStrategy;

   public Conveyance(FillStrategy fillStrategy) {
       this.fillStrategy = fillStrategy;
   }

   public void fill() {
       this.fillStrategy.fill();
   }

   public void go() {
       System.out.println("Moving forward");
   }

   public void stop() {
       System.out.println("Braking!");
   }
}

public class Sedan extends Conveyance {

   public Sedan() {
       super(new StandardFillStrategy());
   }
}



public class HybridCar extends Conveyance {

   public HybridCar() {
       super(new HybridFillStrategy());
   }
}

public class F1Car extends Conveyance {

   public F1Car() {
       super(new F1PitstopStrategy());
   }
}
మన ప్రధాన() పద్ధతిని అమలు చేద్దాం (ఇది మారదు). మేము అదే ఫలితాన్ని పొందుతాము! కన్సోల్ అవుట్‌పుట్:

Just refuel with gas! 
Refuel with gas or electricity — your choice! 
Refuel with gas only after all other pit stop procedures are complete!
వ్యూహ రూపకల్పన నమూనా అల్గారిథమ్‌ల కుటుంబాన్ని నిర్వచిస్తుంది, వాటిలో ప్రతి ఒక్కటి సంగ్రహిస్తుంది మరియు అవి పరస్పరం మార్చుకోగలవని నిర్ధారిస్తుంది. క్లయింట్ ద్వారా అల్గారిథమ్‌లు ఎలా ఉపయోగించబడుతున్నాయనే దానితో సంబంధం లేకుండా వాటిని సవరించడానికి ఇది మిమ్మల్ని అనుమతిస్తుంది (ఈ నిర్వచనం, "హెడ్ ఫస్ట్ డిజైన్ ప్యాటర్న్స్" పుస్తకం నుండి తీసుకోబడింది, ఇది నాకు అద్భుతమైనదిగా అనిపిస్తుంది). డిజైన్ నమూనా: వ్యూహం - 4మేము ఇప్పటికే వివిధ అమలులతో ప్రత్యేక ఇంటర్‌ఫేస్‌లలో ఆసక్తి ఉన్న అల్గారిథమ్‌ల కుటుంబాన్ని (కార్లకు ఇంధనం నింపే మార్గాలు) పేర్కొన్నాము. మేము వారిని కారు నుండి వేరు చేసాము. ఇప్పుడు మనం నిర్దిష్ట రీఫ్యూయలింగ్ అల్గారిథమ్‌లో ఏవైనా మార్పులు చేయవలసి వస్తే, అది మా కారు తరగతులను ఏ విధంగానూ ప్రభావితం చేయదు. మరియు పరస్పర మార్పిడిని సాధించడానికి, మేము మా రవాణా తరగతికి ఒకే సెట్టర్ పద్ధతిని జోడించాలి :

public class Conveyance {

   FillStrategy fillStrategy;

   public void fill() {
       fillStrategy.fill();
   }

   public void go() {
       System.out.println("Moving forward");
   }

   public void stop() {
       System.out.println("Braking!");
   }

   public void setFillStrategy(FillStrategy fillStrategy) {
       this.fillStrategy = fillStrategy;
   }
}
ఇప్పుడు మనం ఫ్లైలో వ్యూహాలను మార్చవచ్చు:

public class Main {

   public static void main(String[] args) {

       Stroller stroller= new Stroller();
       stroller.setFillStrategy(new StandardFillStrategy());

       stroller.fill();
   }
}
బేబీ స్త్రోల్లెర్స్ అకస్మాత్తుగా గ్యాసోలిన్‌తో నడుస్తుంటే, మా ప్రోగ్రామ్ ఈ దృష్టాంతాన్ని నిర్వహించడానికి సిద్ధంగా ఉంటుంది :) మరియు దాని గురించి! మీరు మరొక డిజైన్ నమూనాను నేర్చుకున్నారు, అది నిస్సందేహంగా అవసరం మరియు నిజమైన ప్రాజెక్ట్‌లపై పని చేస్తున్నప్పుడు సహాయకరంగా ఉంటుంది :) తదుపరి సమయం వరకు!
వ్యాఖ్యలు
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION