16.    The Iterator Pattern

Iterator는 디자인 패턴에서 가장 간단하고 가장 빈번하게 사용되는 패턴들 중의 하나이다. Iterator패턴은 데이터의 내부적인 표현을 자세하게 아는 것 없이 표준적인 인터페이스를 이용한 데이터의 리스트나 컬렉션을 통하여 이동하는 것을 허용한다.게다가 어떤 특별한 프로세싱과 데이터 컬렉션의 특정한 원소를 반환을 하는 특별한Iterator를 정의할 수 있다.

 

구조

사용자 삽입 이미지

 

역할

  • Iterator –요소를 차례로 스캔할 인터페이스(API)를 결정한다.
  • ConcreteIterator – Iterator에서 정한 인터페이스(API)를 실제로 구현한다.
  • Aggregate – Iterator역할을 만들어내는 인터페이스(API)를 제공한다.
  • ConcreteAggregate – Aggregate역할이 정한 인터페이스(API)를 실제로 구현한다.

 

의도

집합object의 원소들의 내부형태를 알필요없이 해당 원소에 접근 가능하게 해준다.

 

적용시기

결론

l        테이터 수정– Iterator사용에 따른 가장 중요한 질문은 수정할 때 데이터의 반복을 고려한다는 것이다.만약 코드가 광범위하고 경우에 따라서 다음 요소로 이동한다면,요소는 이동하는 동안 기본적인 컬렉션에서 추가되거나 삭제된다.또한 또 다른 쓰레드가 그 컬렉션을 바꿀 수 있다.이 문제에 대한 간단한 솔루션은 없다.루프를 선언해서 안전한Enumeration쓰레드를 만들어 동기화할 수 있다.그러나Enumeration을 사용해서 루프로 이동하거나 특정 아이템을 삭제하려고 한다면 유념해야 한다.요소를 삭제하거나 추가하는 것은 사용하고 있는 저장 메커니즘에 따라서 특정 요소를 건너뛰거나 두 번 액세스한다는 것을 의미한다.

l        허가된 접근(Privileged access) – Enumeration클래스는 원래의 컨테이너 클래스의 기본적인 구조에 일종의 허가된 접근을 할 필요가 있다.따라서Enumeration클래스는 데이터로 이동할 수 있다.만약 데이터가vectorHashtable에 저장 되어있다면,이렇게 실행하는 것은 아주 쉽다.그러나 데이터가 클래스 안에 다른 컬렉션 구조라면,아마도get연산으로 그 구조를 실행 할 수 있도록 해야 할 것 이다.

l        외부Iterator와 내부Iterator –디자인 패턴은 두 가지 종류의Iterator를 설명한다.하나는 외부Iterator이고,다른 하나는 내부Iterator이다.지금가지는 외부Iterator에 대해서만 이야기 하였다.내부Iterator는 사용자의 특별 요청없이 각각의 요소에 직접적으로 연산을 샐행하면서 전체 컬렉션으로 이동하는 메소드이다.내부Iteratorjava에서 외부Iterator보다 일반적이지 못하다.그러나0에서1사이에 놓는 데이터값의 컬렉션을 정규화하거나 모든 문자열을 특정 활자로 변환하는 메소드가 가능하다.

 

자바 언어에서의Enumeration

Enumeration유현은VectorHashtable클래스로 구현된다.이들은Enumeration유형의 두가지 메소드를 직접적으로 구현하는 클래스라기 보다는 해당 클래스의 데이터에 대한Enumeration을 반환하는elements메소드를 포함하는 클래스라 할 수 있다.

 

예제소스

사용자 삽입 이미지

이 프로그램은 왼쪽에(50free.txt)파일에 등록된 모든 아이들을 표시하고,클럽 리스트로 콤보 박스를 체운다.그런 다음 사용자가 클럽을 선택하면 우측리스트에는 클럽에 소속된 아이들만 표시한다.

 

예제 소스

import java.util.*;

 

public class Kid {

   String frname, lname, club;

   int age;

   float time;

 

   public Kid(String line) {

       StringTokenizer tok = new StringTokenizer(line);

       

       String lnum = tok.nextToken();

       frname=tok.nextToken();

       lname = tok.nextToken();

       age = new Integer(tok.nextToken()).intValue();

       club = tok.nextToken();

       time = new Float(tok.nextToken()).floatValue();

   }

 

 

   public int getAge() { return age;}

   public float getTime() {return time;}

   public String getFrname() {return frname;}

   public String getLname(){return lname;}

   public String getClub() {return club;}

}

 

import java.util.*;

 

public class kidClub implements Enumeration {

   private String clubMask;

   private Kid kid;

   private Enumeration ke;

   private KidData kdata;

 

   public kidClub(KidData kd, String club) {

       clubMask = club;

       kdata = kd;

       kid = null;

       ke = kdata.elements();

   }

 

   public boolean hasMoreElements() {

       boolean found = false;

       while (ke.hasMoreElements() && ! found) {

           kid = (Kid)ke.nextElement();

           found = kid.getClub().equals(clubMask);

       }

       if (! found)

           kid = null;

       return found;

   }

 

   public Object nextElement() {

       if (kid != null)

           return kid;

       else

           throw new NoSuchElementException();

   }

}

 

 

import java.util.*;

public class KidData {

   private Vector kids;   

   private Hashtable clubs;

 

   public KidData(String filename) {

       kids = new Vector();

       clubs = new Hashtable();

       InputFile f = new InputFile(filename);

       String s = f.readLine();

       while (s != null) {

           if (s.trim().length() > 0) {

               Kid k = new Kid(s);

               kids.addElement(k);

               clubs.put (k.getClub (), k.getClub ());

           }

           s = f.readLine();

       }

   }

 

   public String[] getClubs() {

       String s[] = new String[clubs.size ()];

       Enumeration enum = clubs.elements ();

       int max = clubs.size();

   

       for (int i=0; i < max; i++)

           s[i] = (String)enum.nextElement ();

   

       for (int i=0; i<max; i++) {

           for (int j=i; j<max; j++) {

               if ((s[i].compareTo (s[j]) > 0)) {

                   String tmp = s[i];

                   s[i] = s[j];

                   s[j] = tmp;

               }

           }

       }

       return s;

   }

 

   public Kid[] getData() {

       Kid[] kd = new Kid[kids.size()];

       for (int i=0; i< kids.size(); i++)

           kd[i] = (Kid)kids.elementAt(i);

       return kd;

   }

 

   public Enumeration elements() {

       return kids.elements();

   }

 

   public Enumeration kidsInClub(String club) {

       return new kidClub(this, club);                                      

   }

   

   public int size() {

       return kids.size();

   }

 

   public Kid getKid(int i) {

       return(Kid)kids.elementAt(i);

   }

 

}

 

public interface awtList {

   public void add(String s);

   public void remove(String s);

   public String[] getSelectedItems();

}

 

 

import java.awt.*;

import java.io.*;

 

public class InputFile {

   RandomAccessFile f = null;

   boolean errflag;

   String s = null;

 

   public InputFile(String fname) {

   errflag = false;

   

       try {

           f = new RandomAccessFile(fname, "r");

       } catch (IOException e) {

           System.out.println("no file found");

           errflag = true;   //and set flag

       }

   }

 

   public boolean checkErr() {

       return errflag;

   }

 

   public String read() {

       String ret = "";

 

       if (s == null) {

           s = readLine();

       }

       

       if (s != null) {

           s.trim();

           int i = s.indexOf(",");

           

           if (i <= 0) {

               ret = s.trim();

               s = null;

           } else {

               ret = s.substring(0, i).trim();

               s = s.substring(i+1);

           }

       } else {

           ret = null;

       }

       return ret;

   }

   

   public String readLine() {

       s = null;

       try {

           s = f.readLine();

       } catch (IOException e) {

           errflag = true;

           System.out.println("File read error");

       }

       return s;

   }

 

   public void close() {

       try {

           f.close();

       } catch (IOException e) {

           System.out.println("File close error");

           errflag = true;

       }

   }

}

 

import java.awt.*;

import java.awt.event.*;

import java.util.*;

import javax.swing.text.*;

import javax.swing.*;

import javax.swing.event.*;

import javax.swing.tree.*;

import javax.swing.border.*;

 

 

public class JawtList extends JScrollPane

   implements ListSelectionListener, awtList {

   

   private JList listWindow;

   private JListData listContents;

   

   public JawtList(int rows) {

       listContents = new JListData();

       listWindow = new JList(listContents);

       listWindow.setPrototypeCellValue("Abcdefg Hijkmnop");

       getViewport().add(listWindow);

   }

 

   public void add(String s) {

       listContents.addElement(s);

   }

 

   public void remove(String s) {

       listContents.removeElement(s);

   }

 

   public void clear() {

       listContents.clear();

   }

 

   public String[] getSelectedItems() {

       Object[] obj = listWindow.getSelectedValues();

       String[] s = new String[obj.length];

       for (int i =0; i<obj.length; i++)

           s[i] = obj[i].toString();

       return s;

   }

 

   public void valueChanged(ListSelectionEvent e){}

   

}

 

class JListData extends AbstractListModel {

   private Vector data;

 

   public JListData() {

       data = new Vector();

   }

 

   public int getSize() {

       return data.size();

   }

 

   public Object getElementAt(int index) {

       return data.elementAt(index);

   }

 

   public void addElement(String s) {

       data.addElement(s);

       fireIntervalAdded(this, data.size()-1, data.size());

   }

 

   public void removeElement(String s) {

       data.removeElement(s);

       fireIntervalRemoved(this, 0, data.size());

   }

 

   public void clear() {

       int size= data.size();

       data = new Vector();

       fireIntervalRemoved(this, 0, size);

   }

}

 

import java.awt.*;

import java.awt.event.*;

import java.util.*;

import javax.swing.text.*;

import javax.swing.*;

import javax.swing.event.*;

 

 

public class JxFrame extends JFrame {

   

   public JxFrame(String title) {

       super(title);

       setCloseClick();

       setLF();

   }

 

   private void setCloseClick() {

       addWindowListener(

           new WindowAdapter() {

               public void windowClosing(WindowEvent e) {

                   System.exit(0);

               }

           }

       );

   }

   

   private void setLF() {

       String laf = UIManager.getSystemLookAndFeelClassName();

       try {

           UIManager.setLookAndFeel(laf);

       } catch (UnsupportedLookAndFeelException exc) {

           System.err.println("Warning: UnsupportedLookAndFeel: " + laf);

       } catch (Exception exc) {

           System.err.println("Error loading " + laf + ": " + exc);

       }

   }

}

 

import java.awt.BorderLayout;

import java.awt.Dimension;

import java.awt.GridLayout;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

 

import java.util.Enumeration;

 

import javax.swing.JButton;

import javax.swing.JComboBox;

import javax.swing.JPanel;

import javax.swing.border.EmptyBorder;

 

public class IterDemo extends JxFrame implements ActionListener {

   JawtList kidList, kidClubList;

   JComboBox clubs;

   JButton Get;

   KidData kdata;

   

   public IterDemo() {

       super("Iterator패턴 데모");

       JPanel jp = new JPanel();

       getContentPane().add(jp);

       jp.setLayout(new GridLayout(1,2));

       JPanel left = new JPanel();

       JPanel right = new JPanel();

       jp.add(left);

       jp.add(right);

       left.setBorder(new EmptyBorder(5,5,5,5));

       right.setBorder(new EmptyBorder(5,5,5,5));

       kidList = new JawtList(20);

       left.setLayout(new BorderLayout());

       left.add("Center", kidList);

       

       right.setLayout(new BorderLayout());

       

       Get = new JButton("Get");

       Get.addActionListener(this);

       JPanel rtop = new JPanel();

       right.add ("North", rtop);

       

       kdata = new KidData ("50free.txt");  

       fillKidList();

       clubs = new JComboBox(kdata.getClubs ());

       

       rtop.add(clubs);

       rtop.add(Get);

       kidClubList = new JawtList(20);

       right.add("Center",kidClubList);

       

       setSize(new Dimension(400,300));

       setVisible(true);

   }

 

   private void fillKidList() {

       Enumeration ekid = kdata.elements();

       

       while (ekid.hasMoreElements()) {

           Kid k =(Kid)ekid.nextElement();

           kidList.add(k.getFrname()+" "+k.getLname());

       }

   }

 

   public void actionPerformed(ActionEvent e) {

       String club = (String)clubs.getSelectedItem();

       kidClubList.clear ();

   

       if(club.trim().length() > 0) {

           Enumeration eclub = new kidClub(kdata, club);

           

           while(eclub.hasMoreElements()) {

               Kid k =(Kid)eclub.nextElement();

               kidClubList.add(k.getFrname()+" "+k.getLname());

           }

       }

   }

 

   static public void main(String argv[]) {

       new IterDemo();

   }

}

 

à50free.txt

1 Amanda McCarthy            12 WCA        29.28

2 Jamie Falco                12 HNHS       29.80

3 Meaghan O'Donnell          12 EDST       30.00

4 Greer Gibbs                12 CDEV       30.04

5 Rhiannon Jeffrey           11 WYW        30.04

6 Sophie Connolly            12 WAC        30.05

7 Dana Helyer                12 ARAC       30.18

8 Lindsay Marotto            12 OAK        30.23

9 Sarah Treichel             12 WYW        30.35

10 Ashley McEntee            12 RAC        30.47

11 Rachel Brookman           12 CAT        30.51

12 Michelle Ducharme         12 LEHY       30.51

13 Karleen Danais            12 NES        30.70

14 Megan Loock               12 WAC        30.90

15 Kaitlyn Ament             12 HNHS       30.93

16 Tara Schoen               12 WYW        31.01

17 Kate Olshefski            12 NCY        31.01

18 Emma Zuidema              12 HMST       31.07

19 Katie Persing             12 OAK        31.14

20 Christina Monsees         11 RAC        31.27

21 Kimberly Watcke           12 CDEV       31.50

22 Colleen Smith             12 AJSC       31.52

23 Chloe Osborne             12 GYWD       31.74

24 Natalia Fugate            12 WAC        31.75

25 Lisa McHale               11 RAC        31.76

26 Lindsay Cowles            11 NES        31.79

27 Jacquelyn Yavarone        12 HNHS       31.83

28 Molly Fenn                12 WRAT       31.84

29 Karin Brudvig             12 HMST       31.84

30 Annie Duffy               12 MGAT       31.90

31 Nicole Coia               11 WCA        31.94

32 Elizabeth Rice            12 WYW        31.96

33 Yvette Landwehr           12 WRAT       32.00

34 Ashley Recklet            12 SHEL       32.24

35 Lauren McKenna            11 PSDY       32.27

36 Kristen Fontaine          12 EDST       32.28

37 Diana Cooke               12 ZEUS       32.33

38 Kimberly Gambino          11 NES        32.43

39 Jenny Morgan              11 NES        32.49

40 Colleen Coelho            12 CDEV       32.50

41 Leigh Gordon              12 CDEV       32.62

42 Caitlin Gillen            12 WYW        32.75

43 Kristen Skroski           12 HNHS       32.91

44 Sarah Greenberg           11 CDEV       32.97

45 Kathy Collins             12 EHBB       33.11

46 Morgan Bullock            12 ICSC       33.33

47BrittanyMedlin           12 CAT        33.33

48 Haley Ottenbreit          12 HNHS       33.35

49 Laura Kunces              11 WAC        33.64

50 Hayley Wolfgruber         12 WYW        33.73

51 Katie Duffy               12 MGAT       34.24

 

사용자 삽입 이미지

 

관련패턴

  • Composite Pattern: Iterator는 종종Compositerecursive구조접근에 응용됨
  • FactoryMethod Pattern: Polymorphic Iterator들은 적절한Iterator subclassobject를 만드는 데 사용됨

 

'Programming > Design Pattern' 카테고리의 다른 글

[펌] The Memento Pattern  (0) 2006.01.21
[펌] The Interpreter Pattern  (0) 2006.01.21
[펌] The Mediator Pattern  (0) 2006.01.21
[펌] The Memento Pattern  (0) 2006.01.21
[펌] The Facade Pattern  (0) 2006.01.21

Posted by 영웅기삼
,