CodeGym /Java Blog /சீரற்ற /உத்தி வடிவமைப்பு முறை
John Squirrels
நிலை 41
San Francisco

உத்தி வடிவமைப்பு முறை

சீரற்ற குழுவில் வெளியிடப்பட்டது
வணக்கம்! இன்றைய பாடத்தில், வியூக முறை பற்றி பேசுவோம். முந்தைய பாடங்களில், பரம்பரை பற்றிய கருத்தை நாங்கள் ஏற்கனவே சுருக்கமாக அறிந்திருக்கிறோம். நீங்கள் மறந்துவிட்டால், இந்த சொல் ஒரு பொதுவான நிரலாக்க பணிக்கான நிலையான தீர்வைக் குறிக்கிறது என்பதை நான் உங்களுக்கு நினைவூட்டுகிறேன். கோட்ஜிம்மில், எந்தக் கேள்விக்கும் கூகுள் மூலம் பதில் தேடலாம் என்று நாங்கள் அடிக்கடி கூறுகிறோம். ஏனென்றால், உங்கள் பணி, அது எதுவாக இருந்தாலும், ஏற்கனவே வேறொருவரால் வெற்றிகரமாக தீர்க்கப்பட்டிருக்கலாம். வடிவங்கள் மிகவும் பொதுவான பணிகளுக்கான முயற்சி மற்றும் உண்மையான தீர்வுகள் அல்லது சிக்கலான சூழ்நிலைகளைத் தீர்ப்பதற்கான முறைகள். இவை "சக்கரங்கள்" போன்றவை, நீங்கள் சொந்தமாக மீண்டும் கண்டுபிடிக்கத் தேவையில்லை, ஆனால் அவற்றை எப்படி எப்போது பயன்படுத்த வேண்டும் என்பதை நீங்கள் தெரிந்து கொள்ள வேண்டும் :) வடிவங்களுக்கான மற்றொரு நோக்கம் சீரான கட்டிடக்கலையை மேம்படுத்துவதாகும். வேறொருவரின் குறியீட்டைப் படிப்பது எளிதான காரியமல்ல! ஒவ்வொருவரும் வெவ்வேறு குறியீடுகளை எழுதுகிறார்கள், ஏனெனில் ஒரே பணியை பல வழிகளில் தீர்க்க முடியும். ஆனால் பேட்டர்ன்களின் பயன்பாடானது வெவ்வேறு புரோகிராமர்கள் நிரலாக்க தர்க்கத்தை ஒவ்வொரு கோட் கோட்டிலும் (முதல் முறையாகப் பார்க்கும்போது கூட!) ஆராயாமல் புரிந்துகொள்ள உதவுகிறது. வடிவமைப்பு முறை: உத்தி - 2நாங்கள் ஒரு நிரலை எழுதுகிறோம் என்று கற்பனை செய்து பாருங்கள், அது கடத்தல் பொருள்களுடன் தீவிரமாக வேலை செய்யும். எங்கள் திட்டம் சரியாக என்ன செய்கிறது என்பது முக்கியமல்ல. ஒரு கன்வேயன்ஸ் பெற்றோர் வகுப்பு மற்றும் மூன்று குழந்தை வகுப்புகள் கொண்ட வகுப்பு படிநிலையை உருவாக்கியுள்ளோம் : செடான் , டிரக் மற்றும் F1கார் .

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 :/
   }
}
எங்கள் திட்டத்தில் இப்போது ஒரு கடத்தல் (ஒரு குழந்தை இழுபெட்டி) உள்ளது, அது பொதுவான கருத்துடன் பொருந்தாது. இது பெடல்களைக் கொண்டிருக்கலாம் அல்லது ரேடியோ-கட்டுப்படுத்தப்பட்டதாக இருக்கலாம், ஆனால் ஒன்று நிச்சயம் - அதில் எரிவாயுவை ஊற்றுவதற்கு இடமில்லை. எங்கள் வகுப்பு வரிசைமுறையானது பொதுவான முறைகளை தேவையில்லாத வகுப்புகளால் மரபுரிமையாகப் பெறுவதற்கு காரணமாகியுள்ளது. இந்த நிலையில் நாம் என்ன செய்ய வேண்டும்? சரி, ஸ்ட்ரோலர் வகுப்பில் உள்ள ஃபில்() முறையை நாங்கள் மேலெழுதலாம் .

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 இடைமுகத்தை கன்வேயன்ஸ் பெற்றோர் வகுப்பில் ஒரு புலமாகப் பயன்படுத்துகிறோம் . நாங்கள் குறிப்பிட்ட செயலாக்கத்தைக் குறிப்பிடவில்லை என்பதை நினைவில் கொள்ளவும் — நாங்கள் ஒரு இடைமுகத்தைப் பயன்படுத்துகிறோம். கார் வகுப்புகளுக்கு 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