Iterator Pattern

问题:

面对多个集合对象(不一定使用相同集合容器)时, 如何设置使其 遍历和操作统一化

public class AMenu
{
    ArrayList menuItems;

    public AMenu()
    {
        menuItems = new ArrayList();

        addItem("a");
        addItem("b");
        addItem("c");
        // ......
    }

    public void addItem(string s){}
    public ArrayList getMenuItems()
    {
        return menuItems;
    }
}
public class BMenu
{
    int index = 0;
    MenuItem[] menuItems;

    public BMenu()
    {
        menuItems = new MenuItem[MAX_ITEMS];

        addItem("a");
        addItem("b");
        addItem("c");
        // ......
    }

    public void addItem(string s){}
    public MenuItem[] getMenuItems()
    {
        return menuItems;
    }
}
public class Waitree
{
    AMenu aMenu = new AMenu();
    BMenu bMenu = new BMenu();

    void printMenu()
    {
        ArrayList AItems = aMenu.getMenuItems();
        MenuItem[] BItems = bMenu.getMenuItems();

        printMenu(AItems);
        printMenu(BItems);
    }

    void printMenu(ArrayList array)
    {
        foreach(var a in AItems)
        {
            MenuItem item = (MenuItem)AItems.get(i);
        }
    }

    void printMenu(MenuItem[] list)
    {
        foreach(var b in BItems)
        {
            MenuItem item = BItems[i];
            // do something
        }
    }
}

这里可以看出 Waitree 对每个对象都使用了不同的遍历方式, 针对不同类型需要有不同类型的实现,

但就抽象意义来说, 都是遍历, 所以需要抽象

 所以:

先针对不同的 集合类型设置不同的迭代器

public interface Iterator
{
    bool hasNext();
    object Next();
}
public class AMenuIterator : Iterator
{
    ArrayList items;
    public AMenuIterator(ArrayList){
        this.items = items;
    }
    bool hasNext(){};
    object Next(){};
}
public class BMenuIterator : Iterator
{
    MenuItem[] items;
    int index = 0;
    public BMenuIterator(MenuItem[] items){
        this.items = items;
    }
    bool hasNext(){}
    object Next(){}
}

然后修改实现的类

public class AMenu
{
    ArrayList menuItems;
    public AMenu()
    {
        menuItems = new ArrayList();

        addItem("a");
        addItem("b");
        addItem("c");
        // ......
    }
    public void addItem(string s){}
    public Iterator getMenuItems()
    {
        return new AMenuIterator(menuItems);
    }
}
public class BMenu
{
    int index = 0;
    MenuItem[] menuItems;
    public BMenu()
    {
        menuItems = new MenuItem[MAX_ITEMS];

        addItem("a");
        addItem("b");
        addItem("c");
        // ......
    }
    public void addItem(string s){}
    public Iterator getMenuItems()
    {
        return new BMenuIterator(menuItems);
    }
}
public class Waitree()
{
    AMenu aMenu = new AMenu();
    BMenu bMenu = new BMenu();

    void printMenu()
    {
        Iterator AItems = aMenu.getMenuItems();
        Iterator BItems = bMenu.getMenuItems();

        printMenu(AItems);
        printMenu(BItems);
    }

    void printMenu(Iterator iterator)
    {
        while(iterator.hasNext()){
            show(iterator.next());
        }
    }
}

这样就可以吧不同类型的集合封装成一个抽象, 针对这个抽象操作达到对所有(几乎所有)的集合容器的操作

 

问题:

现在还是需要实例化两个不同的菜单类, 是否可以将不同的 Menu 抽象

所以:

public interface Menu
{
    Iterator getMenuItems();
}
public class Waitree()
{
    Menu aMenu = new AMenu();
    Menu bMenu = new BMenu();

    void printMenu()
    {
        Iterator AItems = aMenu.getMenuItems();
        Iterator BItems = bMenu.getMenuItems();

        printMenu(AItems);
        printMenu(BItems);
    }

    void printMenu(Iterator iterator)
    {
        while(iterator.hasNext()){
            show(iterator.next());
        }
    }
}

 

问题:

现在需要再增加多个相同的 菜单, 如果不进行重构 在 Waitree 中会出现十分多的相同的类

public class CMenu : Menu
{
    LinkList menuItems;
    public CMenu()
    {
        menuItems = new LinkList();

        addItem("a");
        addItem("b");
        addItem("c");
        // ......
    }
    public void addItem(string s){}
    public Iterator getMenuItems()
    {
        return new AMenuIterator(menuItems);
    }
}
public class DMenu : Menu
{
    LinkList menuItems;
    public DMenu()
    {
        menuItems = new LinkList();

        addItem("a");
        addItem("b");
        addItem("c");
        // ......
    }
    public void addItem(string s){}
    public Iterator getMenuItems()
    {
        return new AMenuIterator(menuItems);
    }
}
public class EMenu : Menu
{
    LinkList menuItems;
    public EMenu()
    {
        menuItems = new LinkList();

        addItem("a");
        addItem("b");
        addItem("c");
        // ......
    }
    public void addItem(string s){}
    public Iterator getMenuItems()
    {
        return new AMenuIterator(menuItems);
    }
}
public class FMenu : Menu
{
    LinkList menuItems;
    public FMenu()
    {
        menuItems = new LinkList();

        addItem("a");
        addItem("b");
        addItem("c");
        // ......
    }
    public void addItem(string s){}
    public Iterator getMenuItems()
    {
        return new AMenuIterator(menuItems);
    }
}
public class Waitree
{
    Menu aMenu = new AMenu();
    Menu bMenu = new BMenu();
    Menu cMenu = new CMenu();
    // .........

    void printMenu()
    {
        Iterator AItems = aMenu.getMenuItems();
        Iterator BItems = bMenu.getMenuItems();
        Iterator CItems = cMenu.getMenuItems();
        // ...................

        printMenu(AItems);
        printMenu(BItems);
        printMenu(CItems);
        // ....................
    }

    void printMenu(Iterator iterator)
    {
        while(iterator.hasNext()){
            show(iterator.next());
        }
    }
}

所以:

需要将重复的部分封装成一个集合

public class Waitree()
{
    ArrayList menus;

    void printMenu()
    {
        Iterator menuIterator = menus.iterator();

        while(menuIterator.hasNext()){
            Menu menu = (Menu)menuIterator.next();
            printMenu(menu.getMenuItems());
        }
    }

    void printMenu(Iterator iterator)
    {
        while(iterator.hasNext()){
            show(iterator.next());
        }
    }
}

 

 

问题:

这样一来, 可能在菜单中会存在子菜单.

 

所以:

将菜单的结构调整为树形结构....

posted @ 2015-11-29 11:23  `Laimic  阅读(120)  评论(0)    收藏  举报