CodeGym /Java Blog /சீரற்ற /எதிர்ப்பு வடிவங்கள் என்றால் என்ன? சில உதாரணங்களைப் பார்ப்...
John Squirrels
நிலை 41
San Francisco

எதிர்ப்பு வடிவங்கள் என்றால் என்ன? சில உதாரணங்களைப் பார்ப்போம் (பகுதி 1)

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

1. பகுப்பாய்வு முடக்கம்

பகுப்பாய்வு முடக்கம்ஒரு உன்னதமான மேலாண்மை எதிர்ப்பு வடிவமாகக் கருதப்படுகிறது. இது திட்டமிடலின் போது நிலைமையை அதிகமாக பகுப்பாய்வு செய்வதை உள்ளடக்குகிறது, இதனால் எந்த முடிவும் அல்லது நடவடிக்கையும் எடுக்கப்படாது, அடிப்படையில் வளர்ச்சி செயல்முறையை முடக்குகிறது. பகுப்பாய்வின் போது முழுமையை அடைவதற்கும், எல்லாவற்றையும் கருத்தில் கொள்வதற்கும் இலக்காக இருக்கும்போது இது அடிக்கடி நிகழ்கிறது. இந்த எதிர்ப்பு முறையானது வட்டங்களில் நடப்பதன் மூலம் வகைப்படுத்தப்படுகிறது. எடுத்துக்காட்டாக, நீங்கள் ஒரு மட்டத்தில் விஷயங்களைக் கணிக்க முயற்சிக்கிறீர்கள்: ஆனால் ஒரு பயனர் திடீரென்று தனது பெயரின் நான்காவது மற்றும் ஐந்தாவது எழுத்துக்களின் அடிப்படையில் பணியாளர்களின் பட்டியலை உருவாக்க விரும்பினால் என்ன செய்வது கடந்த நான்கு ஆண்டுகளில் புத்தாண்டு மற்றும் சர்வதேச மகளிர் தினத்திற்கு இடையில்? சாராம்சத்தில், அது' மிக அதிகமான பகுப்பாய்வு. பகுப்பாய்வு முடக்குதலை எதிர்த்துப் போராடுவதற்கான சில குறிப்புகள் இங்கே:
  1. முடிவெடுப்பதற்கான ஒரு கலங்கரை விளக்கமாக நீண்ட கால இலக்கை நீங்கள் வரையறுக்க வேண்டும், இதனால் உங்கள் ஒவ்வொரு முடிவும் உங்களைத் தேக்கமடையச் செய்வதற்குப் பதிலாக இலக்கை நோக்கி உங்களை நெருக்கமாக நகர்த்துகிறது.
  2. அற்ப விஷயங்களில் கவனம் செலுத்த வேண்டாம் (உங்கள் வாழ்க்கையின் மிக முக்கியமான முடிவு போல் ஒரு முக்கியமற்ற விவரத்தை ஏன் எடுக்க வேண்டும்?)
  3. முடிவெடுப்பதற்கான காலக்கெடுவை அமைக்கவும்.
  4. ஒரு பணியைச் சரியாக முடிக்க முயற்சிக்காதீர்கள் - அதை மிகச் சிறப்பாகச் செய்வது நல்லது.
இங்கே மிகவும் ஆழமாக செல்ல வேண்டிய அவசியமில்லை, எனவே மற்ற நிர்வாக எதிர்ப்பு வடிவங்களை நாங்கள் கருத்தில் கொள்ள மாட்டோம். எனவே, எந்த அறிமுகமும் இல்லாமல், சில கட்டடக்கலை எதிர்ப்பு வடிவங்களுக்குச் செல்வோம், ஏனெனில் இந்தக் கட்டுரையை மேலாளர்களை விட எதிர்கால டெவலப்பர்கள் படிக்க வாய்ப்புள்ளது.

2. கடவுள் பொருள்

கடவுள் பொருள் என்பது அனைத்து வகையான செயல்பாடுகளின் அதிகப்படியான செறிவு மற்றும் பெரிய அளவிலான வேறுபட்ட தரவு (பயன்பாட்டைச் சுற்றி வரும் ஒரு பொருள்) ஆகியவற்றை விவரிக்கிறது. ஒரு சிறிய உதாரணத்தை எடுத்துக் கொள்ளுங்கள்:

public class SomeUserGodObject {
   private static final String FIND_ALL_USERS_EN = "SELECT id, email, phone, first_name_en, access_counter, middle_name_en, last_name_en, created_date FROM users;
   private static final String FIND_BY_ID = "SELECT id, email, phone, first_name_en, access_counter, middle_name_en, last_name_en, created_date FROM users WHERE id = ?";
   private static final String FIND_ALL_CUSTOMERS = "SELECT id, u.email, u.phone, u.first_name_en, u.middle_name_en, u.last_name_en, u.created_date" +
           "  WHERE u.id IN (SELECT up.user_id FROM user_permissions up WHERE up.permission_id = ?)";
   private static final String FIND_BY_EMAIL = "SELECT id, email, phone, first_name_en, access_counter, middle_name_en, last_name_en, created_dateFROM users WHERE email = ?";
   private static final String LIMIT_OFFSET = " LIMIT ? OFFSET ?";
   private static final String ORDER = " ORDER BY ISNULL(last_name_en), last_name_en, ISNULL(first_name_en), first_name_en, ISNULL(last_name_ru), " +
           "last_name_ru, ISNULL(first_name_ru), first_name_ru";
   private static final String CREATE_USER_EN = "INSERT INTO users(id, phone, email, first_name_en, middle_name_en, last_name_en, created_date) " +
           "VALUES (?, ?, ?, ?, ?, ?, ?)";
   private static final String FIND_ID_BY_LANG_CODE = "SELECT id FROM languages WHERE lang_code = ?";
                                  ........
   private final JdbcTemplate jdbcTemplate;
   private Map<String, String> firstName;
   private Map<String, String> middleName;
   private Map<String, String> lastName;
   private List<Long> permission;
                                   ........
   @Override
   public List<User> findAllEnCustomers(Long permissionId) {
       return jdbcTemplate.query( FIND_ALL_CUSTOMERS + ORDER, userRowMapper(), permissionId);
   }
   @Override
   public List<User> findAllEn() {
       return jdbcTemplate.query(FIND_ALL_USERS_EN + ORDER, userRowMapper());
   }
   @Override
   public Optional<List<User>> findAllEnByEmail(String email) {
       var query = FIND_ALL_USERS_EN + FIND_BY_EMAIL + ORDER;
       return Optional.ofNullable(jdbcTemplate.query(query, userRowMapper(), email));
   }
                              .............
   private List<User> findAllWithoutPageEn(Long permissionId, Type type) {
       switch (type) {
           case USERS:
               return findAllEnUsers(permissionId);
           case CUSTOMERS:
               return findAllEnCustomers(permissionId);
           default:
               return findAllEn();
       }
   }
                              ..............…

   private RowMapper<User> userRowMapperEn() {
       return (rs, rowNum) ->
               User.builder()
                       .id(rs.getLong("id"))
                       .email(rs.getString("email"))
                       .accessFailed(rs.getInt("access_counter"))
                       .createdDate(rs.getObject("created_date", LocalDateTime.class))
                       .firstName(rs.getString("first_name_en"))
                       .middleName(rs.getString("middle_name_en"))
                       .lastName(rs.getString("last_name_en"))
                       .phone(rs.getString("phone"))
                       .build();
   }
}
எல்லாவற்றையும் செய்யும் ஒரு பெரிய வகுப்பை இங்கே காண்கிறோம். இதில் தரவுத்தள வினவல்கள் மற்றும் சில தரவுகள் உள்ளன. நாங்கள் findAllWithoutPageEn முகப்பு முறையையும் பார்க்கிறோம், இதில் வணிக தர்க்கம் அடங்கும். அத்தகைய கடவுள் பொருள் மகத்தானதாகவும், ஒழுங்காக பராமரிப்பதற்கு அருவருப்பாகவும் மாறும். ஒவ்வொரு குறியீட்டிலும் நாம் அதைக் குழப்ப வேண்டும். பல கணினி கூறுகள் அதை நம்பியுள்ளன மற்றும் அதனுடன் இறுக்கமாக இணைக்கப்பட்டுள்ளன. அத்தகைய குறியீட்டை பராமரிப்பது கடினமாகவும் கடினமாகவும் மாறும். இதுபோன்ற சந்தர்ப்பங்களில், குறியீடு தனித்தனி வகுப்புகளாகப் பிரிக்கப்பட வேண்டும், ஒவ்வொன்றும் ஒரே ஒரு நோக்கத்தைக் கொண்டிருக்கும். இந்த எடுத்துக்காட்டில், கடவுள் பொருளை ஒரு டாவோ வகுப்பாகப் பிரிக்கலாம்:

public class UserDaoImpl {
   private static final String FIND_ALL_USERS_EN = "SELECT id, email, phone, first_name_en, access_counter, middle_name_en, last_name_en, created_date FROM users;
   private static final String FIND_BY_ID = "SELECT id, email, phone, first_name_en, access_counter, middle_name_en, last_name_en, created_date FROM users WHERE id = ?";
  
                                   ........
   private final JdbcTemplate jdbcTemplate;
                                                        
                                   ........
   @Override
   public List<User> findAllEnCustomers(Long permissionId) {
       return jdbcTemplate.query(FIND_ALL_CUSTOMERS + ORDER, userRowMapper(), permissionId);
   }
   @Override
   public List<User> findAllEn() {
       return jdbcTemplate.query(FIND_ALL_USERS_EN + ORDER, userRowMapper());
   }
  
                               ........
}
தரவை அணுகுவதற்கான தரவு மற்றும் முறைகளைக் கொண்ட ஒரு வகுப்பு:

public class UserInfo {
   private Map<String, String> firstName;
                     …..
   public Map<String, String> getFirstName() {
       return firstName;
   }
   public void setFirstName(Map<String, String> firstName) {
       this.firstName = firstName;
   }
                    ....
வணிக தர்க்கத்துடன் கூடிய முறையை ஒரு சேவைக்கு நகர்த்துவது மிகவும் பொருத்தமானதாக இருக்கும்:

private List<User> findAllWithoutPageEn(Long permissionId, Type type) {
   switch (type) {
       case USERS:
           return findAllEnUsers(permissionId);
       case CUSTOMERS:
           return findAllEnCustomers(permissionId);
       default:
           return findAllEn();
   }
}

3. சிங்கிள்டன்

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

  2. ஒரு சிங்கிள்டன் SOLID கொள்கைகளை மீறுகிறது - ஒற்றை பொறுப்புக் கொள்கை: அதன் நேரடி கடமைகளுக்கு கூடுதலாக, சிங்கிள்டன் வகுப்பு நிகழ்வுகளின் எண்ணிக்கையையும் கட்டுப்படுத்துகிறது.

  3. ஒரு சாதாரண வகுப்பின் சிங்கிள்டனை சார்ந்திருப்பது வகுப்பின் இடைமுகத்தில் தெரிவதில்லை. ஒரு சிங்கிள்டன் நிகழ்வு பொதுவாக ஒரு முறை வாதமாக அனுப்பப்படுவதில்லை, மாறாக getInstance() மூலம் நேரடியாகப் பெறப்படுவதால், வகுப்பின் சிங்கிள்டனைச் சார்ந்திருப்பதைக் கண்டறிய நீங்கள் ஒவ்வொரு முறையையும் செயல்படுத்த வேண்டும். ஒப்பந்தம் போதாது.

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

    வேறு வார்த்தைகளில் கூறுவதானால், ஒரு சிங்கிள்டன் இணைப்பதை அதிகரிக்கிறது, மேலும் மேலே குறிப்பிட்டுள்ள அனைத்தும் அதிகரித்த இணைப்பின் விளைவைத் தவிர வேறில்லை.

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

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

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

    நாங்கள் அதில் தாமதிக்க மாட்டோம். அதற்கு பதிலாக, இன்றைய கடைசி வடிவமைப்பு முறைக்கு செல்வோம் - பொல்டெர்ஜிஸ்ட்.

4. போல்டர்ஜிஸ்ட்

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

public class UserManager {
   private UserService service;
   public UserManager(UserService userService) {
       service = userService;
   }
   User createUser(User user) {
       return service.create(user);
   }
   Long findAllUsers(){
       return service.findAll().size();
   }
   String findEmailById(Long id) {
       return service.findById(id).getEmail();}
   User findUserByEmail(String email) {
       return service.findByEmail(email);
   }
   User deleteUserById(Long id) {
       return service.delete(id);
   }
}
ஒரு இடைத்தரகர் மற்றும் அதன் வேலையை வேறொருவருக்கு வழங்கும் ஒரு பொருள் நமக்கு ஏன் தேவை? நாங்கள் அதை அகற்றிவிட்டு, அதில் உள்ள சிறிய செயல்பாட்டை நீண்ட காலம் வாழும் பொருட்களுக்கு மாற்றுவோம். அடுத்து, நமக்கு மிகவும் ஆர்வமாக இருக்கும் (சாதாரண டெவலப்பர்களாக), அதாவது வளர்ச்சிக்கு எதிரான வடிவங்களுக்குச் செல்கிறோம் .

5. கடின குறியீட்டு முறை

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

public Connection buildConnection() throws Exception {
   Class.forName("com.mysql.cj.jdbc.Driver");
   connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/someDb?characterEncoding=UTF-8&characterSetResults=UTF-8&serverTimezone=UTC", "user01", "12345qwert");
   return connection;
}
வலிக்கிறது, இல்லையா? இங்கே நாங்கள் எங்கள் இணைப்பு அமைப்புகளை கடுமையாகக் குறியீடு செய்கிறோம். இதன் விளைவாக, குறியீடு MySQL உடன் மட்டுமே சரியாக வேலை செய்யும். தரவுத்தளத்தை மாற்ற, நாம் குறியீட்டிற்குள் நுழைந்து எல்லாவற்றையும் கைமுறையாக மாற்ற வேண்டும். ஒரு தனி கோப்பில் உள்ளமைவை வைப்பது ஒரு நல்ல தீர்வாக இருக்கும்:

spring:
  datasource:
    jdbc-url:jdbc:mysql://localhost:3306/someDb?characterEncoding=UTF-8
    driver-class-name: com.mysql.cj.jdbc.Driver
    username:  user01
    password:  12345qwert
மற்றொரு விருப்பம் மாறிலிகளைப் பயன்படுத்துவது.

6. படகு நங்கூரம்

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

public User update(Long id, User request) {
   User user = mergeUser(findById(id), request);
   return userDAO.update(user);
}
private User mergeUser(User findUser, User requestUser) {
   return new User(
           findUser.getId(),
           requestUser.getEmail() != null ? requestUser.getEmail() : findUser.getEmail(),
           requestUser.getFirstName() != null ? requestUser.getFirstName() : findUser.getFirstNameRu(),
           requestUser.getMiddleName() != null ? requestUser.getMiddleName() : findUser.getMiddleNameRu(),
           requestUser.getLastName() != null ? requestUser.getLastName() : findUser.getLastNameEn(),
           requestUser.getPhone() != null ? requestUser.getPhone() : findUser.getPhone());
}
தரவுத்தளத்திலிருந்து பயனர் தரவை முறைக்கு அனுப்பிய பயனர் தரவுடன் ஒன்றிணைக்க ஒரு தனி முறையைப் பயன்படுத்தும் புதுப்பிப்பு முறை எங்களிடம் உள்ளது (புதுப்பிப்பு முறைக்கு அனுப்பப்பட்ட பயனர் பூஜ்ய புலத்தைக் கொண்டிருந்தால், பழைய புல மதிப்பு தரவுத்தளத்திலிருந்து எடுக்கப்படும்) . பதிவுகளை பழையவற்றுடன் இணைக்கக்கூடாது என்ற புதிய தேவை இருப்பதாக வைத்துக்கொள்வோம், மாறாக, பூஜ்ய புலங்கள் இருந்தாலும், அவை பழையவற்றை மேலெழுதப் பயன்படுத்தப்படுகின்றன:

public User update(Long id, User request) {
   return userDAO.update(user);
}
இதன் பொருள் mergeUser இனி பயன்படுத்தப்படாது, ஆனால் அதை நீக்குவது பரிதாபமாக இருக்கும் - இந்த முறை (அல்லது இந்த முறையின் யோசனை) எப்போதாவது கைக்கு வந்தால் என்ன செய்வது? அத்தகைய குறியீடு அமைப்புகளை சிக்கலாக்குகிறது மற்றும் குழப்பத்தை அறிமுகப்படுத்துகிறது, அடிப்படையில் நடைமுறை மதிப்பு இல்லை. நீங்கள் வேறொரு திட்டத்திற்குச் செல்லும்போது "இறந்த துண்டுகள்" கொண்ட அத்தகைய குறியீடு சக ஊழியருக்கு அனுப்ப கடினமாக இருக்கும் என்பதை நாம் மறந்துவிடக் கூடாது. படகு நங்கூரர்களைக் கையாள்வதற்கான சிறந்த வழி, குறியீட்டை மறுசீரமைப்பதாகும், அதாவது குறியீட்டின் பிரிவுகளை நீக்குதல் (இதயத்தை உடைக்கிறது, எனக்குத் தெரியும்). கூடுதலாக, மேம்பாட்டு அட்டவணையைத் தயாரிக்கும் போது, ​​அத்தகைய அறிவிப்பாளர்களைக் கணக்கிடுவது அவசியம் (சுத்தப்படுத்துவதற்கு நேரத்தை ஒதுக்குவதற்கு).

7. பொருள் கழிவுநீர்

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

class ReusablePool {
   private static ReusablePool pool;
   private List<Resource> list = new LinkedList<>();
   private ReusablePool() {
       for (int i = 0; i < 3; i++)
           list.add(new Resource());
   }
   public static ReusablePool getInstance() {
       if (pool == null) {
           pool = new ReusablePool();
       }
       return pool;
   }
   public Resource acquireResource() {
       if (list.size() == 0) {
           return new Resource();
       } else {
           Resource r = list.get(0);
           list.remove(r);
           return r;
       }
   }
   public void releaseResource(Resource r) {
       list.add(r);
   }
}
இந்த வகுப்பு மேலே உள்ள சிங்கிள்டன் பேட்டர்ன்/ஆண்டி-பேட்டர்ன் வடிவத்தில் வழங்கப்படுகிறது , அதாவது இந்த வகையின் ஒரே ஒரு பொருள் மட்டுமே இருக்க முடியும். Resourceஇது சில பொருட்களைப் பயன்படுத்துகிறது . இயல்பாக, கட்டமைப்பாளர் குளத்தை 4 நிகழ்வுகளுடன் நிரப்புகிறார். நீங்கள் ஒரு பொருளைப் பெற்றால், அது குளத்திலிருந்து அகற்றப்படும் (கிடைக்கக்கூடிய பொருள் இல்லை என்றால், ஒன்று உருவாக்கப்பட்டு உடனடியாகத் திரும்பும்). இறுதியில், பொருளை மீண்டும் வைக்க ஒரு முறை உள்ளது. ஆதார பொருள்கள் இப்படி இருக்கும்:

public class Resource {
   private Map<String, String> patterns;
   public Resource() {
       patterns = new HashMap<>();
       patterns.put("proxy", "https://en.wikipedia.org/wiki/Proxy_pattern");
       patterns.put("bridge", "https://en.wikipedia.org/wiki/Bridge_pattern");
       patterns.put("facade", "https://en.wikipedia.org/wiki/Facade_pattern");
       patterns.put("builder", "https://en.wikipedia.org/wiki/Builder_pattern");
   }
   public Map<String, String> getPatterns() {
       return patterns;
   }
   public void setPatterns(Map<String, String> patterns) {
       this.patterns = patterns;
   }
}
வடிவமைப்பு வடிவப் பெயர்கள் முக்கிய மற்றும் தொடர்புடைய விக்கிபீடியா இணைப்புகளை மதிப்பாகக் கொண்ட வரைபடத்தைக் கொண்ட ஒரு சிறிய பொருள் இங்கே உள்ளது, அத்துடன் வரைபடத்தை அணுகுவதற்கான முறைகள். முக்கியமாகப் பார்ப்போம்:

class SomeMain {
   public static void main(String[] args) {
       ReusablePool pool = ReusablePool.getInstance();

       Resource firstResource = pool.acquireResource();
       Map<String, String> firstPatterns = firstResource.getPatterns();
       // use our map somehow...
       pool.releaseResource(firstResource);

       Resource secondResource = pool.acquireResource();
       Map<String, String> secondPatterns = firstResource.getPatterns();
       // use our map somehow...
       pool.releaseResource(secondResource);

       Resource thirdResource = pool.acquireResource();
       Map<String, String> thirdPatterns = firstResource.getPatterns();
       // use our map somehow...
       pool.releaseResource(thirdResource);
   }
}
இங்கே எல்லாம் போதுமான அளவு தெளிவாக உள்ளது: நாங்கள் ஒரு பூல் பொருளைப் பெறுகிறோம், குளத்திலிருந்து வளங்களைக் கொண்ட ஒரு பொருளைப் பெறுகிறோம், ஆதாரப் பொருளிலிருந்து வரைபடத்தைப் பெறுகிறோம், அதைக் கொண்டு ஏதாவது செய்யுங்கள், மேலும் மறுபயன்பாட்டிற்காக இதையெல்லாம் குளத்தில் அதன் இடத்தில் வைக்கிறோம். Voila, இது ஆப்ஜெக்ட் பூல் டிசைன் பேட்டர்ன். ஆனால் நாங்கள் எதிர்ப்பு வடிவங்களைப் பற்றி பேசிக்கொண்டிருந்தோம், இல்லையா? முக்கிய முறையில் பின்வரும் வழக்கைக் கருத்தில் கொள்வோம்:

Resource fourthResource = pool.acquireResource();
   Map<String, String> fourthPatterns = firstResource.getPatterns();
// use our map somehow...
fourthPatterns.clear();
firstPatterns.put("first","blablabla");
firstPatterns.put("second","blablabla");
firstPatterns.put("third","blablabla");
firstPatterns.put("fourth","blablabla");
pool.releaseResource(fourthResource);
இங்கே, மீண்டும், ஒரு ஆதாரப் பொருளைப் பெறுகிறோம், அதன் வடிவங்களின் வரைபடத்தைப் பெறுகிறோம், மேலும் வரைபடத்தைக் கொண்டு ஏதாவது செய்கிறோம். ஆனால் வரைபடத்தை மீண்டும் பொருள்களின் தொகுப்பில் சேமிப்பதற்கு முன், அது அழிக்கப்பட்டு, சிதைந்த தரவுகளால் நிரப்பப்பட்டு, ஆதாரப் பொருளை மறுபயன்பாட்டிற்குப் பொருத்தமற்றதாக ஆக்குகிறது. ஒரு பொருள் குளத்தின் முக்கிய விவரங்களில் ஒன்று, ஒரு பொருள் திரும்பப் பெறப்பட்டால், அது மீண்டும் பயன்படுத்துவதற்கு ஏற்ற நிலைக்கு மீட்டமைக்க வேண்டும். குளத்திற்குத் திரும்பிய பொருள்கள் தவறான அல்லது வரையறுக்கப்படாத நிலையில் இருந்தால், எங்கள் வடிவமைப்பு ஒரு பொருள் செஸ்பூல் என்று அழைக்கப்படுகிறது. மறுபயன்பாட்டிற்குப் பொருந்தாத பொருட்களைச் சேமிப்பதில் ஏதேனும் அர்த்தமிருக்கிறதா? இந்த சூழ்நிலையில், கட்டமைப்பாளரில் உள்ளக வரைபடத்தை மாற்ற முடியாததாக மாற்றலாம்:

public Resource() {
   patterns = new HashMap<>();
   patterns.put("proxy", "https://en.wikipedia.org/wiki/Proxy_pattern");
   patterns.put("bridge", "https://en.wikipedia.org/wiki/Bridge_pattern");
   patterns.put("facade", "https://en.wikipedia.org/wiki/Facade_pattern");
   patterns.put("builder", "https://en.wikipedia.org/wiki/Builder_pattern");
   patterns = Collections.unmodifiableMap(patterns);
}
வரைபடத்தின் உள்ளடக்கங்களை மாற்றுவதற்கான முயற்சிகளும் விருப்பமும் அவை உருவாக்கும் ஆதரிக்கப்படாத ஆபரேஷன்எக்செப்ஷனுக்கு நன்றி மறைந்துவிடும். நேரமின்மை, கவனக்குறைவு, அனுபவமின்மை அல்லது திட்ட மேலாளர்களின் அழுத்தம் ஆகியவற்றின் காரணமாக டெவலப்பர்கள் அடிக்கடி சந்திக்கும் பொறிகள் எதிர்ப்பு வடிவங்கள் ஆகும். அவசரமானது, இது எதிர்காலத்தில் பயன்பாட்டிற்கு பெரிய சிக்கல்களுக்கு வழிவகுக்கும், எனவே நீங்கள் இந்த பிழைகளைப் பற்றி அறிந்து அவற்றை முன்கூட்டியே தவிர்க்க வேண்டும். இத்துடன் கட்டுரையின் முதல் பகுதி முடிவடைகிறது. தொடரும்...
கருத்துக்கள்
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION