Iterator Pattern – Đôi điều thú vị

1. Mở đầu

Lời đầu tiên, image câu view ngoài bài viết có liên quan mật thiết tới nội dung bài viết. Ngoài mục đích giúp anh em đọc bài đỡ chán, nhìn lâu vào hình có thể ngộ được cái vẻ đẹp của Iterator Boobs, lộn Iterator Pattern.

Note: Anh em đọc đến cuối bài mà chưa hiểu gì, thì cứ kéo lên nhìn hình cô em xinh đẹp, nhìn ngắm một hồi rồi đọc lại là sẽ hiểu. =)))

iterator-pattern-if-you-don't-understand

2. Tại sao tao cần biết về cái Pattern củ l*z này?

Xin thưa là do cái Iterator Pattern này nằm trong nhóm các pattern cơ bản, cực kì hữu dụng khi hiểu về nó.

Đầu tiên, ta có rất nhiều cách để lưu trữ một collection các objects. Kiểu sử dụng có thể là: List, Dictionaries và Sets.

Ví dụ, lưu trữ một array đồ uống có thể thực hiện như sau:

// Java
// Lưu trữ danh sách menu
String[] menuItems = new String[MAX_ITEMS];
menuItem[0] = "Bạc sỉu nóng nhiều đá";
menuItem[1] = "Đen đá không lạnh";

Ngoài ra, Java cũng cung cấp ArrayList, lưu trữ mảng Object.

// Java
// Lưu trữ danh sách menu
ArrayList<String> menuItems = new ArrayList<String>();
menuItem.add("Bạc sỉu nóng nhiều đá");
menuItem.add("Đen đá không lạnh");

Ngon lành cành đào. Tiếp theo, ta cần hiện thực một method in ra tất cả những item trong menu đồ uống. Một đoạn code bình thường sẽ là:

// Java
// In danh sách các item trong menu
for (int i; i < items.length; i++) {
  String item = items[i];
  // Print the item
}

Đệt, lỡ thằng nào dở chứng. Nó không lưu menu trong cái array mà chuyển qua ArrayList? -> Khá đau thương nhưng phải sửa code:

// Java
// In danh sách các item trong menu
// Đm thằng shrimp head nào rảnh đổi kiểu từ array sang ArrayList nhé!.
for (int i; i < items.size; i++) {
  String item = items.get(i);
  // Print the item
}

Chà, đây chính là lý do Iterator Pattern ra đời.

Iterator Pattern cung cấp một thiết kế (pattern) cho phép hoạt động trên nhiều loại Collections. Trường hợp input đầu vào là Set -> work, trường hợp là Vector -> work nốt. Chà, đấy chính là lý do cái Iterator Pattern này ra đời.

3. Hiện thực dư lào?

Đầu tiên, Iterator:

The Iterator interface declares the operations required for traversing a collection: fetching the next element, retrieving the current position, restarting iteration, etc

Iterator interface khái báo các thao tác cần thiết để duyệt qua Collection: Tìm nạp phần tử kế tiếp, nhận về vị trí hiện tại, khởi động lại iteration, …
iterator-pattern-design
// Java
// Khởi tạo interface Iterator
// Interator.java
public interface Iterator {
}
// Java
// Khởi tạo interface Iterator
// Container.java
public interface Container {
  public Iterator getIterator();
}
// Java
// Class menu implement Container
public class Menu implements Container {
   public String menu[] = {"Cà phê" , "Nước cam" ,"Bò Húc" , "Sting"};

   @Overrides
   public Iterator getIterator() {
      return new MenuIterator();
   }
  
   private class MenuIterator implements Iterator {

      int index;

      // Return boolean.
      // True - Collection còn phần tử 
      // False - Cuối collection 
      @Override
      public boolean hasNext() {
      
         if(index < menu.length){
            return true;
         }
         return false;
      }

      // Return object
      // Trả về phần tử kế tiếp
      @Override
      public Object next() {
      
         if(this.hasNext()){
            return menu[index++];
         }
         return null;
      }		
   }
}
// Java
// Call interator and print item in menu
public class IteratorPatternMenu {
	
   public static void main(String[] args) {
      MenuIterator menuIterator = new MenuIterator();

      for(Iterator iter = menuIterator.getIterator(); iter.hasNext();){
         String menuItem = (String)iter.next();
         System.out.println("Menu item : " + menuItem);
      } 	
   }
}

4. Sử dụng khi nào?

Use the Iterator Pattern when you want your code to be able to traverse different data structures or when types of these structures are unknown beforehand.

Sử dụng Iterator khi chúng ta muốn của mình sẵn sàng cho các kiểu dữ liệu khác nhau HOẶC khi kiểu dữ liệu đầu vào không được biết trước.

Use the Iterator Pattern when your collection has a complex data structure under the hood, but you want to hide its complexity from clients (either for convenience or security reasons).

Sử dụng Interator pattern khi collection của chúng ta có kiểu dữ liệu phức tạp. Nhưng ta lại muốn giấu sự phức tạp đó (không có client biết). Có thể là vì lý do thuận tiện hoặc bảo mật).
Biết – nhưng không phải lúc nào cũng dùng đâu nhé =))).

5. Điểm lợi, điểm hại của Iterator Pattern

[LỢI]: Open/Closed Principle – Sử dụng Iterator giúp ta có thể implement các kiểu collections và interator khác nhau. Đưa chúng vào các lớp đã triển khai. Hạn chế sửa code.

[LỢI]: Sử dụng Iterator Pattern giúp ta iterate các collection giống nhau theo hình thức đa luồng. Mỗi collection sẽ có một object iterator riêng của nó.

[HẠI]: Sẽ là hơi QUÁ CMN ĐÀ nếu ta chỉ có một collection đơn giản nhưng lại triển khai iterator pattern. Dùng dao mổ trâu đi làm thịt chim sẻ. =))). Nên dùng đúng lúc.

[HẠI]: Sử dụng Iterator Pattern đôi khi làm giảm hiệu suất của việc lặp Collections.

6. Tham khảo

Anh em nào có hứng có thể tìm hiểu thêm về Strategy Pattern (một pattern khá hay).

Iterator Pattern – Nguồn: Lynda.com


Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *