"வணக்கம், நண்பரே!"

"வணக்கம், பிலாபோ!"

"எங்களுக்கு இன்னும் சிறிது நேரம் உள்ளது, எனவே இன்னும் மூன்று வடிவங்களைப் பற்றி நான் உங்களுக்குச் சொல்கிறேன்."

"இன்னும் மூணு? மொத்தம் எத்தனை இருக்கு?"

"தற்போது டஜன் கணக்கான பிரபலமான வடிவங்கள் உள்ளன, ஆனால் "வெற்றிகரமான தீர்வுகளின்" எண்ணிக்கை வரம்பற்றது."

"நான் பார்க்கிறேன். அதனால் நான் பல டஜன் வடிவங்களைக் கற்றுக்கொள்ள வேண்டுமா?"

"உங்களுக்கு உண்மையான நிரலாக்க அனுபவம் இருக்கும் வரை, அவர்கள் உங்களுக்கு அதிகம் கொடுக்க மாட்டார்கள்."

"நீங்கள் இன்னும் கொஞ்சம் அனுபவத்தைப் பெறுவது நல்லது, பின்னர், ஒரு வருடத்தில், இந்தத் தலைப்புக்குத் திரும்பி, அவற்றை இன்னும் ஆழமாகப் புரிந்துகொள்ள முயற்சிக்கவும். மிகவும் பிரபலமான வடிவமைப்பு வடிவங்களில் குறைந்தது இரண்டு டஜன் வடிவங்கள்."

"மற்றொருவரின் அனுபவத்தைப் பயன்படுத்தாமல், 110 வது முறையாக ஏதாவது ஒன்றைக் கண்டுபிடிப்பது பாவம்."

"நான் ஒப்புக்கொள்கிறேன்."

"அப்படியானால் ஆரம்பிக்கலாம்."

அடாப்டர் (அல்லது ரேப்பர்) முறை

வடிவங்கள்: அடாப்டர், ப்ராக்ஸி, பிரிட்ஜ் - 1

"நீங்கள் சீனாவிற்கு வந்து, மின் நிலையங்கள் வேறுபட்ட தரநிலையைப் பின்பற்றுவதைக் கற்பனை செய்து பாருங்கள். துளைகள் வட்டமானவை அல்ல, ஆனால் தட்டையானவை. இந்த விஷயத்தில், உங்களுக்கு ஒரு அடாப்டர் தேவைப்படும்."

"புரோகிராமிங்கிலும் இதே போன்ற ஏதாவது நடக்கலாம். வகுப்புகள் ஒரே மாதிரியான ஆனால் வெவ்வேறு இடைமுகங்களில் இயங்குகின்றன. எனவே அவற்றுக்கிடையே ஒரு அடாப்டரை உருவாக்க வேண்டும்."

"இது எப்படி இருக்கிறது:"

உதாரணமாக
interface Time
{
 int getSeconds();
 int getMinutes();
 int getHours();
}

interface TotalTime
{
 int getTotalSeconds();
}

"எங்களிடம் இரண்டு இடைமுகங்கள் இருப்பதாக வைத்துக்கொள்வோம்: நேரம்  மற்றும்  மொத்த நேரம் ."

"நேர இடைமுகமானது getSeconds (),  getMinutes () மற்றும்  getHours () முறைகளைப் பயன்படுத்தி தற்போதைய நேரத்தைப் பெற உங்களை அனுமதிக்கிறது ."

" மொத்த நேர இடைமுகம், நள்ளிரவில் இருந்து தற்போதைய தருணம் வரை கடந்த வினாடிகளின் எண்ணிக்கையைப் பெற உங்களை அனுமதிக்கிறது."

"எங்களிடம் மொத்த நேரப் பொருள் இருந்தால் நாம் என்ன செய்ய வேண்டும், ஆனால் நமக்கு நேரப் பொருள் தேவை அல்லது நேர்மாறாக?"

"இதற்கு நாம் அடாப்டர் வகுப்புகளை எழுதலாம். உதாரணமாக:"

உதாரணமாக
class TotalTimeAdapter implements Time
{
 private TotalTime totalTime;
 public TotalTimeAdapter(TotalTime totalTime)
 {
  this.totalTime = totalTime;
 }

 int getSeconds()
 {
  return totalTime.getTotalSeconds() % 60; // seconds
 }

 int getMinutes()
 {
  return totalTime.getTotalSeconds() / 60; // minutes
 }

 int getHours()
 {
  return totalTime.getTotalSeconds() / (60 * 60); // hours
 }
}
பயன்பாடு
TotalTime totalTime = TimeManager.getCurrentTime();
Time time = new TotalTimeAdapter(totalTime);
System.out.println(time.getHours() + " : " + time.getMinutes () + " : " +time.getSeconds());

"மற்றும் மற்ற திசையில் ஒரு அடாப்டர்:"

உதாரணமாக
class TimeAdapter implements TotalTime
{
 private Time time;
 public TimeAdapter(Time time)
 {
  this.time = time;
 }

 int getTotalSeconds()
 {
  return time.getHours() * 60 * 60 + time.getMinutes() * 60 + time.getSeconds();
 }
}
பயன்பாடு
Time time = new Time();
TotalTime totalTime = new TimeAdapter(time);
System.out.println(time.getTotalSeconds());

"அட. எனக்குப் பிடிக்கும். ஆனால் எதாவது உதாரணங்கள் உண்டா?"

"நிச்சயமாக! உதாரணமாக, InputStreamReader என்பது ஒரு உன்னதமான அடாப்டர். இது InputStream ஐ ரீடராக மாற்றுகிறது."

"சில நேரங்களில் இந்த முறை ரேப்பர் என்றும் அழைக்கப்படுகிறது, ஏனெனில் புதிய வகுப்பு மற்றொரு பொருளை 'முடக்குகிறது'."

"நீங்கள் வேறு சில சுவாரஸ்யமான விஷயங்களை இங்கே படிக்கலாம் ."

ப்ராக்ஸி பேட்டர்ன்

"ப்ராக்ஸி பேட்டர்ன் ரேப்பர் பேட்டர்னைப் போலவே உள்ளது. ஆனால் அதன் நோக்கம் இடைமுகங்களை மாற்றுவது அல்ல, மாறாக ப்ராக்ஸி வகுப்பிற்குள் சேமிக்கப்பட்ட அசல் பொருளுக்கான அணுகலைக் கட்டுப்படுத்துவது. மேலும், அசல் வகுப்பு மற்றும் ப்ராக்ஸி இரண்டும் பொதுவாக ஒரே இடைமுகத்தைக் கொண்டுள்ளன, இது அசல் வகுப்பின் ஒரு பொருளை ப்ராக்ஸி பொருளுடன் மாற்றுவதை எளிதாக்குகிறது."

"உதாரணத்திற்கு:"

உண்மையான வகுப்பின் இடைமுகம்
interface Bank
{
 public void setUserMoney(User user, double money);
 public int getUserMoney(User user);
}
அசல் வகுப்பை செயல்படுத்துதல்
class CitiBank implements Bank
{
 public void setUserMoney(User user, double money)
 {
  UserDAO.updateMoney(user, money);
 }

 public int getUserMoney(User user)
 {
  return UserDAO.getMoney(user);
 }
}
ப்ராக்ஸி வகுப்பை செயல்படுத்துதல்
class BankSecurityProxy implements Bank
{
 private Bank bank;
 public BankSecurityProxy(Bank bank)
 {
  this.bank = bank;
 }
 public void setUserMoney(User user, double money)
 {
  if (!SecurityManager.authorize(user, BankAccounts.Manager))
  throw new SecurityException("User can’t change money value");

  bank.setUserMoney(user, money);
 }

 public int getUserMoney(User user)
 {
  if (!SecurityManager.authorize(user, BankAccounts.Manager))
  throw new SecurityException("User can’t get money value");

  return bank.getUserMoney(user);
 }
}

"மேலே உள்ள எடுத்துக்காட்டில், வங்கி இடைமுகம் மற்றும் இந்த இடைமுகத்தின் செயலாக்கமான CitiBank வகுப்பை நாங்கள் விவரித்தோம்."

"பயனரின் கணக்கு இருப்பைப் பெற அல்லது மாற்ற இடைமுகம் உங்களை அனுமதிக்கிறது."

பின்னர் நாங்கள் BankSecurityProxy ஐ உருவாக்கினோம், இது வங்கி இடைமுகத்தையும் செயல்படுத்துகிறது மற்றும் வேறு வங்கி இடைமுகத்திற்கான குறிப்பைச் சேமிக்கிறது. இந்த வகுப்பின் முறைகள் பயனர் கணக்கு உரிமையாளரா அல்லது வங்கி மேலாளரா என்பதைச் சரிபார்க்கிறது. அது இல்லையென்றால், பாதுகாப்பு விதிவிலக்கு போடப்படும்."

"நடைமுறையில் இது எவ்வாறு செயல்படுகிறது என்பது இங்கே:"

பாதுகாப்பு சோதனைகள் இல்லாத குறியீடு :
User user = AuthManager.authorize(login, password);
Bank bank = BankFactory.createUserBank(user);
bank.setUserMoney(user, 1000000);
பாதுகாப்பு சோதனைகளுடன் குறியீடு :
User user = AuthManager.authorize(login, password);
Bank bank = BankFactory.createUserBank(user);
bank = new BankSecurityProxy(bank);
bank.setUserMoney(user, 1000000);

"முதல் எடுத்துக்காட்டில், நாங்கள் ஒரு வங்கி பொருளை உருவாக்கி அதன் setUserMoney முறையை அழைக்கிறோம்.

"இரண்டாவது எடுத்துக்காட்டில், அசல் வங்கிப் பொருளை BankSecurityProxy பொருளில் போர்த்திவிடுகிறோம். அதே இடைமுகத்தைக் கொண்டிருப்பதால், அடுத்தடுத்த குறியீடுகள் தொடர்ந்து செயல்படும். ஆனால் இப்போது ஒவ்வொரு முறை முறை அழைக்கப்படும்போதும் பாதுகாப்புச் சோதனை செய்யப்படும்."

"கூல்!"

ஆம் ."

"மேலும் என்ன... இந்த அனைத்து பொருள்களின் சங்கிலிகளின் உருவாக்கம் ஒரு BankFactory வகுப்பில் சேர்க்கப்படலாம் , அங்கு உங்களுக்குத் தேவையானவற்றை இயக்கலாம்/முடக்கலாம்."

" BufferedReader இதே கொள்கையைப் பயன்படுத்தி செயல்படுகிறது. இது ஒரு ரீடர் , ஆனால் அது கூடுதல் வேலை செய்கிறது."

"இந்த அணுகுமுறை பல்வேறு "துண்டுகளிலிருந்து" தேவையான செயல்பாட்டுடன் ஒரு பொருளை "அசெம்பிள்" செய்ய உங்களை அனுமதிக்கிறது."

"ஓ, நான் கிட்டத்தட்ட மறந்துவிட்டேன். நான் உங்களுக்குக் காட்டியதை விட ப்ராக்ஸிகள் மிகவும் பரவலாகப் பயன்படுத்தப்படுகின்றன. மற்ற பயன்பாடுகளைப் பற்றி நீங்கள் இங்கே படிக்கலாம் ."

பாலம் முறை

வடிவங்கள்: அடாப்டர், ப்ராக்ஸி, பிரிட்ஜ் - 2

"சில நேரங்களில் ஒரு நிரல் இயங்கும் போது ஒரு பொருளின் செயல்பாட்டை கணிசமாக மாற்றுவது அவசியம். உதாரணமாக, நீங்கள் ஒரு கழுதை பாத்திரத்துடன் விளையாடுகிறீர்கள் என்று வைத்துக்கொள்வோம், பின்னர் அது ஒரு மந்திரவாதியால் டிராகனாக மாறியது. டிராகன் முற்றிலும் மாறுபட்ட நடத்தை மற்றும் பண்புகளைக் கொண்டுள்ளது, ஆனால் அது அதே பொருள்!"

"நாம் ஒரு புதிய பொருளை உருவாக்கி அதை முடிக்க முடியாதா?"

"எப்போதும் இல்லை. உங்கள் கழுதை பல கதாபாத்திரங்களுடன் நண்பர்களாக இருக்கலாம் அல்லது ஒருவேளை அது பல மந்திரங்களின் செல்வாக்கின் கீழ் இருந்திருக்கலாம் அல்லது சில தேடல்களில் ஈடுபட்டிருக்கலாம். வேறுவிதமாகக் கூறினால், பொருள் ஏற்கனவே பல இடங்களில் பயன்பாட்டில் இருக்கலாம் - மேலும் பல பொருள்களுடன் இணைக்கப்பட்டுள்ளது. எனவே இந்த விஷயத்தில், ஒரு புதிய பொருளை உருவாக்குவது ஒரு விருப்பமல்ல."

"சரி, அப்புறம் என்ன செய்யலாம்?"

"பாலம் முறை மிகவும் வெற்றிகரமான தீர்வுகளில் ஒன்றாகும்."

"இந்த முறை ஒரு பொருளை இரண்டு பொருள்களாகப் பிரிக்கிறது: ஒரு "இடைமுகப் பொருள்" மற்றும் "செயல்படுத்தும் பொருள்"."

"இடைமுகத்திற்கும் அதைச் செயல்படுத்தும் வகுப்பிற்கும் என்ன வித்தியாசம்?"

"ஒரு இடைமுகம் மற்றும் ஒரு வகுப்பில், நாம் ஒரு பொருளுடன் முடிவடைகிறோம். ஆனால் இங்கே - நமக்கு இரண்டு உள்ளது. இந்த உதாரணத்தைப் பாருங்கள்:"

உதாரணமாக
class User
{
 private UserImpl realUser;

 public User(UserImpl impl)
 {
  realUser = impl;
 }

 public void run() //Run
 {
  realUser.run();
 }

 public void fly() //Fly
 {
  realUser.fly();
 }
}

class UserImpl
{
 public void run()
 {
 }

 public void fly()
 {
 }
}

"பின்னர் நீங்கள் UserImpl இன் பல துணைப்பிரிவுகளை அறிவிக்கலாம், எடுத்துக்காட்டாக UserDonkey (கழுதை) மற்றும் UserDragon (டிராகன்)."

"அதே போல், இது எப்படி வேலை செய்யும் என்று எனக்கு உண்மையில் புரியவில்லை."

"சரி, இது போன்ற ஒன்று:"

உதாரணமாக
class User
{
 private UserImpl realUser;

 public User(UserImpl impl)
 {
  realUser = impl;
 }

 public void transformToDonkey()
 {
  realUser = new UserDonkeyImpl();
 }

 public void transformToDragon()
 {
  realUser = new UserDragonImpl();
 }
}
எப்படி இது செயல்படுகிறது
User user = new User(new UserDonkey()); // Internally, we're a donkey
user.transformToDragon(); // Now we're a dragon internally

"எனவே இது ப்ராக்ஸி போன்ற ஒன்று."

"ஆமாம், ஆனால் ஒரு ப்ராக்ஸியில் முக்கிய பொருள் எங்காவது தனித்தனியாக சேமிக்கப்படும், அதற்கு பதிலாக குறியீடு ப்ராக்ஸிகளுடன் வேலை செய்கிறது. இங்கே நாம் அனைவரும் முக்கிய பொருளுடன் வேலை செய்கிறோம் என்று கூறுகிறோம், ஆனால் அதன் பாகங்கள் உள்நாட்டில் மாறுகின்றன."

"ஆ. தேங்க்ஸ். இதைப் பற்றி மேலும் படிக்க லிங்க் தருவீர்களா?"

"நிச்சயமாக, அமிகோ, என் நண்பன். இதோ: பாலம் மாதிரி ."