JavaRush /جاوا بلاگ /Random-SD /antipatterns ڇا آهن؟ اچو ته مثال ڏسو (حصو 1)

antipatterns ڇا آهن؟ اچو ته مثال ڏسو (حصو 1)

گروپ ۾ شايع ٿيل
antipatterns ڇا آهن؟  اچو ته مثال ڏسو (حصو 1) - 1سڀني لاء سٺو ڏينهن! ٻئي ڏينهن مون سان انٽرويو ڪيو ويو، ۽ مون کان antipatterns بابت هڪ سوال پڇيو ويو: هي ڪهڙي قسم جو جانور آهي، انهن جا قسم ۽ مثالن ۾ ڇا آهن. يقينن، مون سوال جو جواب ڏنو، پر تمام سطحي طور تي، ڇو ته مون هن مسئلي جي مطالعي ۾ تمام گهڻو نه ويو آهي. انٽرويو کان پوء، مون انٽرنيٽ کي ڇڪڻ شروع ڪيو، هن موضوع ۾ وڌيڪ ۽ وڌيڪ وسري ويو. اڄ آئون تمام مشهور اينٽي پيٽرن ۽ انهن جي مثالن جو مختصر جائزو وٺڻ چاهيان ٿو، جنهن کي پڙهڻ سان توهان کي هن مسئلي تي ضروري ڄاڻ حاصل ٿي سگهي ٿي. اچو ته شروع ڪريون! تنهن ڪري، بحث ڪرڻ کان اڳ هڪ اينٽي پيٽرن ڇا آهي، اچو ته ياد رکون ته هڪ نمونو ڇا آهي. ھڪڙو نمونو ھڪڙو ورجائي قابل تعميراتي ڊيزائن آھي جيڪو عام مسئلن يا حالتن کي حل ڪرڻ لاءِ جيڪو پيدا ٿئي ٿو ايپليڪيشن کي ڊزائين ڪرڻ وقت. پر اڄ اسان انهن جي باري ۾ نه ڳالهائي رهيا آهيون، پر انهن جي مخالف جي باري ۾ - antipatterns. هڪ مخالف نمونو عام طور تي سامهون ايندڙ مسئلن جي هڪ طبقي کي حل ڪرڻ لاء هڪ عام طريقو آهي جيڪو غير موثر، خطرناڪ، يا غير پيداوار آهي. ٻين لفظن ۾، اهو هڪ غلطي جو نمونو آهي (ڪڏهن ڪڏهن هڪ پيچرو پڻ سڏيو ويندو آهي). antipatterns ڇا آهن؟  اچو ته مثال ڏسو (حصو 1) - 2ضابطي جي طور تي، antipatterns هيٺين قسمن ۾ ورهايل آهن:
  1. آرڪيٽيڪچرل اينٽي پيٽرن - آرڪيٽيڪچرل اينٽي پيٽرن جيڪي پيدا ٿين ٿا جڏهن سسٽم جي جوڙجڪ کي ڊزائين ڪرڻ (عام طور تي هڪ معمار طرفان).
  2. مئنيجمينٽ اينٽي پيٽرن - انتظاميا جي ميدان ۾ مخالف نمونن، جيڪي عام طور تي مختلف مينيجرز (يا مينيجرز جي گروپن) جي سامھون آھن.
  3. ڊولپمينٽ اينٽي پيٽرن - اينٽي پيٽرن ترقي جا مسئلا آهن جيڪي پيدا ٿين ٿا جڏهن عام پروگرامر هڪ سسٽم لکندا آهن.
antipatterns جي exoticism تمام وسيع آهي، پر اسان اڄ انهن تي غور نه ڪنداسين، ڇو ته عام ڊولپرز لاء اهو تمام گهڻو هوندو. شروع ڪرڻ سان، اچو ته انتظام جي ميدان ۾ هڪ antipattern جو هڪ مثال وٺو.

1. تجزياتي فالج

تجزيي پارليس کي هڪ کلاسک تنظيمي مخالف نموني سمجهيو ويندو آهي. ان ۾ شامل آهي صورتحال جو وڌيڪ تجزيو ڪرڻ جڏهن منصوبابندي ڪئي وڃي ته جيئن ڪو به فيصلو يا عمل نه ڪيو وڃي، بنيادي طور تي ترقي کي مفلوج ڪري ٿو. اهو اڪثر ڪري ٿو جڏهن مقصد حاصل ڪرڻ آهي تڪميل ۽ تجزيو جي مدت جي مڪمل مڪمل ٿيڻ. هي مخالف نمونو حلقن ۾ هلڻ (هڪ قسم جو بند لوپ)، تفصيلي ماڊل کي نظرثاني ڪرڻ ۽ ٺاهڻ سان منسوب ڪيو ويو آهي، جنهن جي نتيجي ۾ ڪم جي فلو سان مداخلت ٿئي ٿي. مثال طور، توهان شين جي اڳڪٿي ڪرڻ جي ڪوشش ڪري رهيا آهيو جهڙوڪ: ڇا جيڪڏهن صارف اوچتو پنهنجي نالي جي چوٿين ۽ پنجين اکرن جي بنياد تي ملازمن جي هڪ فهرست ٺاهڻ چاهي ٿو، جنهن ۾ اهي منصوبا شامل آهن جن لاءِ هن نئين سال جي وچ ۾ سڀ کان وڌيڪ ڪم ڪندڙ ڪلاڪ وقف ڪيا. چار گذريل سالن ۾ مارچ جي اٺين؟ جوهر ۾، هي تجزيي جو هڪ تمام گهڻو آهي. هڪ سٺو حقيقي زندگي جو مثال اهو آهي ته ڪيئن تجزيي پارليسس ڪوڊڪ کي ڏيوالپڻي ڏانهن وٺي ويو . هتي تجزياتي فالج کي منهن ڏيڻ لاءِ ڪجهه تڪڙا طريقا آهن:
  1. توهان کي ضرورت آهي ته هڪ ڊگهي مدي واري مقصد کي فيصلو ڪرڻ لاءِ هڪ بيڪن جي طور تي، ته جيئن توهان جو هر فيصلو توهان کي پنهنجي مقصد جي ويجهو آڻي، ۽ توهان کي وقت جي نشاندهي ڪرڻ تي مجبور نه ڪري.
  2. ٿورين ڳالهين تي توجه نه ڏيو (ڇو ٿو هڪ معمولي نانءُ تي فيصلو ڪيو ڄڻ ته اهو توهان جي زندگي ۾ آخري هجي؟)
  3. فيصلو ڪرڻ لاء آخري وقت مقرر ڪريو.
  4. هڪ ڪم مڪمل طور تي ڪرڻ جي ڪوشش نه ڪريو: اهو تمام سٺو ڪرڻ بهتر آهي.
اسان تمام گهڻي اونهي نه وڃون ۽ ٻين انتظاميا جي مخالف نموني تي غور ڪنداسين. تنهن ڪري، تمثيل کان سواء، اچو ته ڪجهه تعميراتي اينٽي پيٽرن ڏانهن وڃو، ڇاڪاڻ ته گهڻو ڪري، هي مضمون مستقبل جي ڊولپرز طرفان پڙهيو ويو آهي، نه مينيجرز.

2. خدا جو اعتراض

Divine اعتراض هڪ مخالف نمونو آهي جيڪو بيان ڪري ٿو تمام گھڻن مختلف ڪمن جي اضافي ڪنسنٽريشن، وڏي مقدار ۾ متنوع ڊيٽا کي محفوظ ڪري ٿو (اها اعتراض جنهن جي چوڌاري ايپليڪيشن گردش ڪري ٿي). اچو ته هڪ ننڍڙو مثال وٺون:
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. سنگلٽن

سنگلٽن ھڪڙو آسان نمونو آھي جيڪو ضمانت ڏئي ٿو ته ھڪڙي ھڪڙي ٿريڊ ٿيل ايپليڪيشن ۾ ھڪڙي طبقي جو ھڪڙو مثال ھوندو ۽ ان اعتراض کي گلوبل رسائي پوائنٽ مهيا ڪري ٿو. توھان ان بابت وڌيڪ پڙھي سگھوٿا هتي . پر اھو ھڪڙو نمونو آھي يا ھڪڙو مخالف نمونو؟ antipatterns ڇا آهن؟  اچو ته مثال ڏسو (حصو 1) - 3اچو ته هن ٽيمپليٽ جي نقصانن تي نظر وجهون:
  1. عالمي رياست. جڏهن اسان ڪنهن طبقي جي مثال تائين رسائي حاصل ڪندا آهيون، اسان کي ان طبقي جي موجوده حالت جي خبر ناهي يا ڪنهن ان کي تبديل ڪيو يا ڪڏهن، ۽ اها حالت نه ٿي سگهي ٿي جيڪا اسان جي اميد آهي. ٻين لفظن ۾، هڪ سنگلٽن سان ڪم ڪرڻ جي درستگي ان تي ڪالن جي ترتيب تي منحصر آهي، جنهن جي ڪري سب سسٽم هڪ ٻئي تي ڀاڙي ٿو ۽ نتيجي طور، ترقي جي پيچيدگي کي سنجيده وڌائي ٿو.

  2. سنگلٽن SOLID اصولن مان ھڪڙي جي ڀڃڪڙي ڪري ٿو - اڪيلو ذميواري اصول - سنگلٽن ڪلاس، پنھنجي فوري ذميوارين کي انجام ڏيڻ کان علاوه، پنھنجي مثالن جي تعداد کي پڻ ڪنٽرول ڪري ٿو.

  3. سنگلٽن تي باقاعده طبقي جو انحصار ڪلاس انٽرفيس ۾ نظر نٿو اچي. جيئن ته عام طور تي سنگلٽن جو مثال ڪنهن طريقي جي پيرا ميٽرن ۾ منظور نه ڪيو ويندو آهي، پر سڌو سنئون حاصل ڪيو ويندو آهي، ذريعي، getInstance()سنگلٽن تي هڪ طبقي جي انحصار کي سڃاڻڻ لاء، توهان کي هر طريقي تي عمل ڪرڻ جي ضرورت آهي - صرف عوام کي ڏسڻ. اعتراض جو معاهدو ڪافي نه آهي.

    سنگلٽن جي موجودگي عام طور تي ايپليڪيشن جي قابليت کي گھٽائي ٿي ۽ طبقن جيڪي خاص طور تي سنگلٽن کي استعمال ڪن ٿا. پهرين، توهان سنگلٽن جي جاءِ تي هڪ موڪ اعتراض نٿا رکي سگهو، ۽ ٻيو، جيڪڏهن هڪ سنگلٽن وٽ ان جي حالت کي تبديل ڪرڻ لاءِ هڪ انٽرفيس آهي، ٽيسٽ هڪ ٻئي تي ڀاڙيندا.

    ٻين لفظن ۾، هڪ سنگلٽن رابطي کي وڌائي ٿو، ۽ مٿين سڀني کان وڌيڪ رابطي جي نتيجي کان وڌيڪ ناهي.

    ۽ جيڪڏھن توھان ان جي باري ۾ سوچيو، ھڪڙو سنگل استعمال ڪرڻ کان بچي سگھجي ٿو. مثال طور، ڪنهن شئي جي مثالن جي تعداد کي ڪنٽرول ڪرڻ لاءِ، مختلف قسمن جا ڪارخانا استعمال ڪرڻ بلڪل ممڪن (۽ ضروري) آهي.

    سڀ کان وڏو خطرو سنگلٽن جي بنياد تي پوري ايپليڪيشن آرڪيٽيڪچر ٺاهڻ جي ڪوشش ۾ آهي. هن طريقي سان ڪيترائي عظيم متبادل آهن. سڀ کان اهم مثال بهار آهي، يعني ان جي IoC ڪنٽينرز: اتي خدمتن جي تخليق کي ڪنٽرول ڪرڻ جو مسئلو قدرتي طور تي حل ڪيو ويو آهي، ڇاڪاڻ ته اهي، حقيقت ۾، "اسٽيرائڊس تي ڪارخانا" آهن.

    هاڻي هن موضوع تي تمام گهڻو هوليور آهي، تنهنڪري اهو توهان تي آهي فيصلو ڪرڻ لاء ته ڇا سنگلٽن هڪ نمونو آهي يا هڪ اينٽي پيٽرن.

    ۽ اسان ان تي نه رهنداسين ۽ اڄ جي آخري ڊيزائن جي نموني ڏانهن وڃو - poltergeist.

4. Poltergeist

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);
   }
}
اسان کي اهڙي شيءِ جي ضرورت ڇو آهي جيڪا صرف هڪ وچولي هجي ۽ پنهنجو ڪم ڪنهن ٻئي جي حوالي ڪري؟ اسان ان کي حذف ڪريون ٿا، ۽ ننڍي ڪارڪردگيءَ کي منتقل ڪريون ٿا، جيڪا ان کي ڊگھي زندگي جي شين ۾ لاڳو ڪري ٿي. اڳيون، اسان انهن نمونن ڏانهن وڃون ٿا جيڪي اسان لاءِ تمام گهڻي دلچسپي وارا آهن (جيئن عام ڊولپرز) - develop antipatterns .

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 سان صحيح طريقي سان ڪم ڪندو، ۽ ڊيٽابيس کي تبديل ڪرڻ لاء توهان کي ڪوڊ ۾ حاصل ڪرڻ ۽ هر شيء کي دستي طور تبديل ڪرڻو پوندو. هڪ سٺو حل هوندو configs کي الڳ فائل ۾ رکڻ لاءِ:
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. ٻيڙيءَ جو لنگر

اينٽي پيٽرن جي حوالي سان هڪ ٻيڙي جي لنگر جو مطلب آهي سسٽم جي غير استعمال ٿيل حصن کي ذخيرو ڪرڻ جيڪي ڪجهه اصلاح يا ريفڪٽرنگ کان پوء ڇڏي ويا آهن. انهي سان گڏ، ڪوڊ جا ڪجهه حصا ڇڏي سگهجن ٿا "مستقبل لاء"، صورت ۾ توهان کي انهن کي ٻيهر استعمال ڪرڻو پوندو. اهو لازمي طور تي ڪوڊ کي ردي جي ٽوڪري ۾ تبديل ڪري ٿو. antipatterns ڇا آهن؟  اچو ته مثال ڏسو (حصو 1) - 4مثال:
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.Object cesspool

هن antipattern کي بيان ڪرڻ لاء، توهان کي پهريان کان واقف ٿيڻ جي ضرورت آهي اعتراض پول جي نموني سان . هڪ آبجیکٹ پول (ريسورس پول) هڪ تخليقي ڊيزائن جو نمونو آهي ، شين جو هڪ سيٽ شروعاتي ۽ استعمال لاءِ تيار آهي. جڏهن هڪ ايپليڪيشن کي ڪنهن شئي جي ضرورت هوندي آهي، اهو نئون نه ٺاهيو ويندو آهي، پر هن پول مان ورتو ويندو آهي. جڏهن هڪ اعتراض وڌيڪ گهربل ناهي، اهو تباهه ناهي، پر تلاء ڏانهن موٽيو. عام طور تي ڳري شين لاءِ استعمال ڪيو ويندو آهي جيڪي هر وقت ٺاهڻ لاءِ وسيلا-گھڻي هوندا آهن، جهڙوڪ ڊيٽابيس ڪنيڪشن. اچو ته مثال خاطر هڪ ننڍڙو ۽ سادو مثال ڏسون. تنهنڪري اسان وٽ هڪ ڪلاس آهي جيڪو هن نموني جي نمائندگي ڪري ٿو:
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 ڪاپين سان ڀريو ويندو آهي؛ جڏهن اهڙي شئي ورتي وڃي ٿي، ان کي تلاءَ مان ڪڍيو ويندو آهي (جيڪڏهن اهو موجود نه هجي ته اهو ٺاهيو ويندو آهي ۽ فوري طور تي ڏنو ويندو آهي) ۽ آخر ۾ ان شيءِ کي واپس رکڻ جو طريقو هوندو آهي. شيون Resourceهن طرح نظر اچن ٿا:
public class Resource {
   private Map<String, String> patterns;
   public Resource() {
       patterns = new HashMap<>();
       patterns.put("заместитель", "https://studfile.net/preview/3676297/page:3/");
       patterns.put("мост", "https://studfile.net/preview/3676297/page:4/");
       patterns.put("фасад", "https://studfile.net/preview/3676297/page:5/");
       patterns.put("строитель", "https://studfile.net/preview/3676297/page:6/#16");
   }
   public Map<String, String> getPatterns() {
       return patterns;
   }
   public void setPatterns(Map<String, String> patterns) {
       this.patterns = patterns;
   }
}
هتي اسان وٽ هڪ ننڍڙي شئي آهي جنهن ۾ هڪ نقشو موجود آهي جنهن ۾ نمونن جي نالن سان ڪيجي ۽ انهن سان ڳنڍڻ جي قيمت آهي، انهي سان گڏ نقشي تائين رسائي جا طريقا. اچو ته ڏسون main:
class SomeMain {
   public static void main(String[] args) {
       ReusablePool pool = ReusablePool.getInstance();

       Resource firstResource = pool.acquireResource();
       Map<String, String> firstPatterns = firstResource.getPatterns();
       // ......Howим-то образом используем нашу мапу.....
       pool.releaseResource(firstResource);

       Resource secondResource = pool.acquireResource();
       Map<String, String> secondPatterns = firstResource.getPatterns();
       // ......Howим-то образом используем нашу мапу.....
       pool.releaseResource(secondResource);

       Resource thirdResource = pool.acquireResource();
       Map<String, String> thirdPatterns = firstResource.getPatterns();
       // ......Howим-то образом используем нашу мапу.....
       pool.releaseResource(thirdResource);
   }
}
هتي هر شيءِ به واضح آهي: اسان هڪ تلاءُ واري شئي وٺون ٿا، ان مان وسيلن سان ڪنهن شئي کي ڪڍون ٿا، ان مان هڪ نقشو وٺون ٿا، ان سان ڪجهه ڪريو ۽ اهو سڀ ڪجهه ٻيهر استعمال لاءِ تلاءَ ۾ رکون ٿا. Voila: هتي توهان وٽ اعتراض پول نمونو آهي. پر اسان antipatterns بابت ڳالهائي رهيا هئاسين، ڇا اسان نه هئا؟ اچو ته هن ڪيس کي ڏسو main:
Resource fourthResource = pool.acquireResource();
   Map<String, String> fourthPatterns = firstResource.getPatterns();
// ......Howим-то образом используем нашу мапу.....
fourthPatterns.clear();
firstPatterns.put("first","blablabla");
firstPatterns.put("second","blablabla");
firstPatterns.put("third","blablabla");
firstPatterns.put("fourth","blablabla");
pool.releaseResource(fourthResource);
هتي ٻيهر، هڪ وسيلا اعتراض ورتو وڃي ٿو، ان جو نقشو نمونن سان ورتو وڃي ٿو ۽ ان سان ڪجهه ڪيو وڃي ٿو، پر اعتراض پول ۾ واپس محفوظ ڪرڻ کان اڳ، نقشو صاف ڪيو ويندو آهي ۽ ناقابل معلومات ڊيٽا سان ڀريو ويندو آهي، جيڪو هن ريسورس اعتراض کي ٻيهر استعمال ڪرڻ لاء غير مناسب بڻائي ٿو. هڪ اعتراض جي تلاء جي مکيه nuances مان هڪ آهي ته هڪ اعتراض جي موٽڻ کان پوء، ان کي وڌيڪ ٻيهر استعمال لاء مناسب حالت ۾ واپس ڪرڻ گهرجي. جيڪڏھن شيون تلاءَ ڏانھن موٽڻ کان پوءِ غلط يا اڻ ٺھيل حالت ۾ آھن، ته ھن اڏاوت کي آبجیکٹ سيس پول چئبو آھي. شيون ذخيرو ڪرڻ جو ڪهڙو مقصد آهي جيڪو ٻيهر استعمال نه ڪيو وڃي؟ هن صورتحال ۾، توهان ٺاهي سگهو ٿا اندروني نقشي کي تعمير ڪندڙ ۾ ناقابل تبديلي:
public Resource() {
   patterns = new HashMap<>();
   patterns.put("заместитель", "https://studfile.net/preview/3676297/page:3/");
   patterns.put("мост", "https://studfile.net/preview/3676297/page:4/");
   patterns.put("фасад", "https://studfile.net/preview/3676297/page:5/");
   patterns.put("строитель", "https://studfile.net/preview/3676297/page:6/#16");
   patterns = Collections.unmodifiableMap(patterns);
}
(مواد کي تبديل ڪرڻ جي ڪوشش ۽ خواهش UnsupportedOperationException سان گڏ ٿيندي). اينٽي پيٽرن جا ڦڙا آھن جيڪي ڊولپر اڪثر وقت جي شديد کوٽ، بي ڌياني، ناتجربيڪاريءَ، يا مينيجرز جي ڪِڪ جي ڪري ڦھلندا آھن. وقت جي معمولي کوٽ ۽ جلدي مستقبل ۾ ايپليڪيشن لاء وڏي مسئلن جو نتيجو ٿي سگهي ٿو، تنهنڪري انهن غلطين کي ڄاڻڻ جي ضرورت آهي ۽ اڳ ۾ ئي بچڻ جي ضرورت آهي. antipatterns ڇا آهن؟  اچو ته مثال ڏسو (حصو 1) - 6ان سان گڏ مضمون جو پهريون حصو پڄاڻي تي پهتو آهي: جاري رکڻ لاءِ .
تبصرا
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION