设计模式--迭代器模式

      与君共勉:作为菜鸟,恃才傲物的人不可怕,可怕的是你的信心被打碎!所以请坚持梦想,勇敢的走下去,技术可以提高,心境的磨练同样重要,技术卓尔不群了,是一把普通锋利的宝剑,心境磨练好了再加上技术的强硬,那就可以御气于剑,翱翔九天,所向披靡!不信可以看看技术经理之类的上层人物,多数不但技术过硬,为人处事也让你佩服。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
     最近开始学习设计模式,买了一本书叫《headfirst 设计模式》,看了以后发现原来代码可以写的这么清晰有条理,看了以后感觉自己之前写的代码都只是“不择手段”的实现了功能,仅此而已,和书中的思想、代码一对比,我的代码简直不忍直视,每每此时,应该开心才对,因为这意味着即将就会有新的收获。
     我也许没有找到什么合适的学习方法,暂时只是按照书本写代码,慢慢加以理解。下面是具体情况:
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

服务员要打印菜单,目前有两种菜单,菜单项都使用同一种数据结构,但菜单一使用arraylist存储菜单项,菜单二使用数组存储。菜单项的实体类如下:

public class MenuItem{
    private String name;
    private String description;
    private boolean vegetarian;
    private  double price;
    public MenuItem(String name,String description,boolean vegetarian,double price){
        this.name =name;
        this.description = description;
        this.vegetarian = vegetarian;
        this.price = price;
    }
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public boolean isVegetarian() {
        return vegetarian;
    }

    public void setVegetarian(boolean vegetarian) {
        this.vegetarian = vegetarian;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }
}
在没有看书之前,如果要我做,我会直接构造两个菜单,打印菜单的时候遍历两次打印出菜单一(arraylist)及 菜单二(数组)。但书中提出的问题是:

1.如果增加一个菜单,那么以后打印菜单,就要加一个遍历,再增加菜单,再遍历。

2.而且必须知道新增菜单如何表达内部的菜单集合,否则你不知道怎么去遍历。

3.存在重复的代码。


事实上应该这么做:

--------定义接口--------

public interface Itereator {
    boolean hasNext();
    Object next();
}

-------定义菜单1---------

public class MenuBreakfast {
    private ArrayList menuItems;
    private int position = 0;
    public MenuBreakfast() {
        menuItems = new ArrayList();
        addItem("name12", "description1", true, 1100);
        addItem("name12", "description2", true, 1200);
        addItem("name13", "description3", true, 1300);
        addItem("name14", "description4", true, 1400);
        addItem("name15", "description5", true, 1500);
        addItem("name16", "description6", true, 1600);
        addItem("name17", "description7", true, 1700);
        addItem("name18", "description8", true, 1800);
        addItem("name19", "description9", true, 1900);
        addItem("name10", "description0", true, 1000);

    }

    private void addItem(String name, String description, boolean vegetarian, double price) {
        MenuItem menuItem = new MenuItem(name, description, vegetarian, price);
        menuItems.add(menuItem);
    }

    public ArrayList getMenuItems() {
        return menuItems;
    }

    public Itereator getItereator(){
        return new BreakfastItereator(menuItems);
    }
   
}
--------定义菜单2-------

public class MenuLunch  {
    private MenuItem[] menuItems;
    private int index = 0;
    private final int MAX_ITEMS = 10;
    private int position = 0;

    public MenuLunch() {
        menuItems = new MenuItem[MAX_ITEMS];
        addItem("name21", "description1", true, 1100);
        addItem("name22", "description2", true, 1200);
        addItem("name23", "description3", true, 1300);
        addItem("name24", "description4", true, 1400);
        addItem("name25", "description5", true, 1500);
        addItem("name26", "description6", true, 1600);
        addItem("name27", "description7", true, 1700);
        addItem("name28", "description8", true, 1800);
        addItem("name29", "description9", true, 1900);
        addItem("name20", "description0", true, 1000);

    }

    private void addItem(String name, String description, boolean vegetarian, double price) {
        MenuItem menuItem = new MenuItem(name, description, vegetarian, price);
        if (index >= MAX_ITEMS) {
            System.err.println("LIST FULL");
        } else {
            menuItems[index] = menuItem;
            index++;
        }

    }

    public Itereator getItereator() {
        return new LunchItereator(menuItems);
    }

    public MenuItem[] getMenuItems() {
        return menuItems;
    }

}
-------构造菜单1的迭代器------

public class BreakfastItereator implements Itereator {
    private ArrayList menuItems;
    private int position = 0;

    public BreakfastItereator(ArrayList menuItems) {
        this.menuItems = menuItems;
    }

    @Override
    public boolean hasNext() {
        if (position >= menuItems.size() || menuItems.get(position) == null) {
            return false;
        }
        return true;
    }

    @Override
    public Object next() {
        MenuItem menuItem = (MenuItem) menuItems.get(position);
        position++;
        return menuItem;

    }

}
-------构造菜单2的迭代器------

public class LunchItereator implements Itereator {
    private MenuItem[] menuItems;
    private int position = 0;

    public LunchItereator(MenuItem[] menuItems){
        this.menuItems = menuItems;
    }
    @Override
    public boolean hasNext() {
        if(position>=menuItems.length||menuItems[position]==null){
            return false;
        }
        return true;
    }

    @Override
    public Object next() {
        MenuItem menuItem = (MenuItem)menuItems[position];
        position++;
        return menuItem;

    }

}

----------服务员类-------

public class Waitress {
    private MenuLunch menuLunch;
    private MenuBreakfast menuBreakfast;

    public Waitress(MenuLunch menuLunch, MenuBreakfast menuBreakfast) {
        this.menuBreakfast = menuBreakfast;
        this.menuLunch = menuLunch;
        printMenu();
    }

    public void printMenu(){
        printMenu(menuBreakfast.getItereator());
        printMenu(menuLunch.getItereator());
    }
   private void printMenu(Itereator itereator){
       while(itereator.hasNext()){
           MenuItem menuItem = (MenuItem)itereator.next();
           Log.d("huitest",""+menuItem.getName());
           Log.d("huitest",""+menuItem.getDescription());
           Log.d("huitest",""+menuItem.isVegetarian());
           Log.d("huitest",""+menuItem.getPrice());
       }
   }
}

----------MainActivity--------

public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        printMenu();

    }

    private void printMenu(){
       Waitress waitress = new Waitress(new MenuLunch(),new MenuBreakfast());
    }


}
--------运行结果---------

03-30 23:22:30.434  13366-13366/? D/huitest﹕ name10
03-30 23:22:30.434  13366-13366/? D/huitest﹕ description1
03-30 23:22:30.434  13366-13366/? D/huitest﹕ true
03-30 23:22:30.435  13366-13366/? D/huitest﹕ 1000.0
03-30 23:22:30.435  13366-13366/? D/huitest﹕ name11
03-30 23:22:30.435  13366-13366/? D/huitest﹕ description2
03-30 23:22:30.435  13366-13366/? D/huitest﹕ true
03-30 23:22:30.435  13366-13366/? D/huitest﹕ 1100.0
03-30 23:22:30.435  13366-13366/? D/huitest﹕ name12
03-30 23:22:30.435  13366-13366/? D/huitest﹕ description3
03-30 23:22:30.435  13366-13366/? D/huitest﹕ true
03-30 23:22:30.435  13366-13366/? D/huitest﹕ 1200.0
03-30 23:22:30.435  13366-13366/? D/huitest﹕ name13
03-30 23:22:30.435  13366-13366/? D/huitest﹕ description4
03-30 23:22:30.435  13366-13366/? D/huitest﹕ true
03-30 23:22:30.435  13366-13366/? D/huitest﹕ 1300.0
03-30 23:22:30.435  13366-13366/? D/huitest﹕ name14
03-30 23:22:30.435  13366-13366/? D/huitest﹕ description5
03-30 23:22:30.435  13366-13366/? D/huitest﹕ true
03-30 23:22:30.435  13366-13366/? D/huitest﹕ 1400.0
03-30 23:22:30.435  13366-13366/? D/huitest﹕ name15
03-30 23:22:30.436  13366-13366/? D/huitest﹕ description6
03-30 23:22:30.436  13366-13366/? D/huitest﹕ true
03-30 23:22:30.436  13366-13366/? D/huitest﹕ 1500.0
03-30 23:22:30.436  13366-13366/? D/huitest﹕ name16
03-30 23:22:30.436  13366-13366/? D/huitest﹕ description7
03-30 23:22:30.436  13366-13366/? D/huitest﹕ true
03-30 23:22:30.436  13366-13366/? D/huitest﹕ 1600.0
03-30 23:22:30.436  13366-13366/? D/huitest﹕ name17
03-30 23:22:30.436  13366-13366/? D/huitest﹕ description8
03-30 23:22:30.436  13366-13366/? D/huitest﹕ true
03-30 23:22:30.436  13366-13366/? D/huitest﹕ 1700.0
03-30 23:22:30.436  13366-13366/? D/huitest﹕ name18
03-30 23:22:30.436  13366-13366/? D/huitest﹕ description9
03-30 23:22:30.436  13366-13366/? D/huitest﹕ true
03-30 23:22:30.436  13366-13366/? D/huitest﹕ 1800.0
03-30 23:22:30.436  13366-13366/? D/huitest﹕ name19
03-30 23:22:30.436  13366-13366/? D/huitest﹕ description0
03-30 23:22:30.437  13366-13366/? D/huitest﹕ true
03-30 23:22:30.437  13366-13366/? D/huitest﹕ 1900.0
03-30 23:22:30.437  13366-13366/? D/huitest﹕ name20
03-30 23:22:30.437  13366-13366/? D/huitest﹕ description1
03-30 23:22:30.437  13366-13366/? D/huitest﹕ true
03-30 23:22:30.437  13366-13366/? D/huitest﹕ 2000.0
03-30 23:22:30.437  13366-13366/? D/huitest﹕ name21
03-30 23:22:30.437  13366-13366/? D/huitest﹕ description2
03-30 23:22:30.438  13366-13366/? D/huitest﹕ true
03-30 23:22:30.438  13366-13366/? D/huitest﹕ 2100.0
03-30 23:22:30.438  13366-13366/? D/huitest﹕ name22
03-30 23:22:30.438  13366-13366/? D/huitest﹕ description3
03-30 23:22:30.438  13366-13366/? D/huitest﹕ true
03-30 23:22:30.438  13366-13366/? D/huitest﹕ 2200.0
03-30 23:22:30.438  13366-13366/? D/huitest﹕ name23
03-30 23:22:30.438  13366-13366/? D/huitest﹕ description4
03-30 23:22:30.438  13366-13366/? D/huitest﹕ true
03-30 23:22:30.438  13366-13366/? D/huitest﹕ 2300.0
03-30 23:22:30.438  13366-13366/? D/huitest﹕ name24
03-30 23:22:30.438  13366-13366/? D/huitest﹕ description5
03-30 23:22:30.438  13366-13366/? D/huitest﹕ true
03-30 23:22:30.438  13366-13366/? D/huitest﹕ 2400.0
03-30 23:22:30.438  13366-13366/? D/huitest﹕ name25
03-30 23:22:30.438  13366-13366/? D/huitest﹕ description6
03-30 23:22:30.438  13366-13366/? D/huitest﹕ true
03-30 23:22:30.438  13366-13366/? D/huitest﹕ 2500.0
03-30 23:22:30.438  13366-13366/? D/huitest﹕ name26
03-30 23:22:30.439  13366-13366/? D/huitest﹕ description7
03-30 23:22:30.439  13366-13366/? D/huitest﹕ true
03-30 23:22:30.439  13366-13366/? D/huitest﹕ 2600.0
03-30 23:22:30.439  13366-13366/? D/huitest﹕ name27
03-30 23:22:30.439  13366-13366/? D/huitest﹕ description8
03-30 23:22:30.439  13366-13366/? D/huitest﹕ true
03-30 23:22:30.439  13366-13366/? D/huitest﹕ 2700.0
03-30 23:22:30.439  13366-13366/? D/huitest﹕ name28
03-30 23:22:30.439  13366-13366/? D/huitest﹕ description9
03-30 23:22:30.439  13366-13366/? D/huitest﹕ true
03-30 23:22:30.440  13366-13366/? D/huitest﹕ 2800.0
03-30 23:22:30.440  13366-13366/? D/huitest﹕ name29
03-30 23:22:30.440  13366-13366/? D/huitest﹕ description0
03-30 23:22:30.440  13366-13366/? D/huitest﹕ true
03-30 23:22:30.440  13366-13366/? D/huitest﹕ 2900.0


这样做,菜单的实现被封装起来,Waitress不知道菜单如何实现,不需要重复写for循环了,printMenu(Itereator itereator)方法可以多态的处理集合。但还有问题,Waitress类仍然和两个菜单类紧紧相关,他的构造方法里,是指定了菜单类型的,只能是MenuLunch和MenuBreakfast。再做一些改进:

---------新的接口------

public interface Menu {
    public Itereator getItereator();
}

--------菜单2---------

public class MenuLunch implements Menu {
    private MenuItem[] menuItems;
    private int index = 0;
    private final int MAX_ITEMS = 10;
    private int position = 0;

    public MenuLunch() {
        menuItems = new MenuItem[MAX_ITEMS];
        addItem("name20", "description1", true, 2000);
        addItem("name21", "description2", true, 2100);
        addItem("name22", "description3", true, 2200);
        addItem("name23", "description4", true, 2300);
        addItem("name24", "description5", true, 2400);
        addItem("name25", "description6", true, 2500);
        addItem("name26", "description7", true, 2600);
        addItem("name27", "description8", true, 2700);
        addItem("name28", "description9", true, 2800);
        addItem("name29", "description0", true, 2900);

    }

    private void addItem(String name, String description, boolean vegetarian, double price) {
        MenuItem menuItem = new MenuItem(name, description, vegetarian, price);
        if (index >= MAX_ITEMS) {
            System.err.println("LIST FULL");
        } else {
            menuItems[index] = menuItem;
            index++;
        }

    }

//    public Itereator getItereator() {
//        return new LunchItereator(menuItems);
//    }

    @Override
    public Itereator getItereator() {
        return new LunchItereator(menuItems);
    }

    public MenuItem[] getMenuItems() {
        return menuItems;
    }

}
--------菜单1---------
public class MenuBreakfast implements Menu {
    private ArrayList menuItems;
    private int position = 0;
    public MenuBreakfast() {
        menuItems = new ArrayList();
        addItem("name10", "description1", true, 1000);
        addItem("name11", "description2", true, 1100);
        addItem("name12", "description3", true, 1200);
        addItem("name13", "description4", true, 1300);
        addItem("name14", "description5", true, 1400);
        addItem("name15", "description6", true, 1500);
        addItem("name16", "description7", true, 1600);
        addItem("name17", "description8", true, 1700);
        addItem("name18", "description9", true, 1800);
        addItem("name19", "description0", true, 1900);

    }

    private void addItem(String name, String description, boolean vegetarian, double price) {
        MenuItem menuItem = new MenuItem(name, description, vegetarian, price);
        menuItems.add(menuItem);
    }

    public ArrayList getMenuItems() {
        return menuItems;
    }

//    public Itereator getItereator(){
//        return new BreakfastItereator(menuItems);
//    }

    @Override
    public Itereator getItereator() {
        return new BreakfastItereator(menuItems);
    }


}

--------Waitress类-------

public class Waitress {
    private Menu menuLunch;
    private Menu menuBreakfast;

    public Waitress(Menu menuLunch, Menu menuBreakfast) {
        this.menuBreakfast = menuBreakfast;
        this.menuLunch = menuLunch;
        printMenu();
    }

    public void printMenu(){
        printMenu(menuBreakfast.getItereator());
        printMenu(menuLunch.getItereator());
    }
   private void printMenu( Iterator itereator){
       while(itereator.hasNext()){
           MenuItem menuItem = (MenuItem)itereator.next();
           Log.d("huitest",""+menuItem.getName());
           Log.d("huitest",""+menuItem.getDescription());
           Log.d("huitest",""+menuItem.isVegetarian());
           Log.d("huitest",""+menuItem.getPrice());
       }
   }
}


这样,Waitress与各个菜单解绑了。事实上我们自己写的迭代器接口可以使用java.util.Iterator代替,将代码中的自己定义的迭代器接口全部替换为java.util.Iterator之后,代码如下:

---------菜单1-------

public class MenuBreakfast implements Iterator, Menu {
    private ArrayList menuItems;
    private int position = 0;

    public MenuBreakfast() {
        menuItems = new ArrayList();
        addItem("name10", "description1", true, 1000);
        addItem("name11", "description2", true, 1100);
        addItem("name12", "description3", true, 1200);
        addItem("name13", "description4", true, 1300);
        addItem("name14", "description5", true, 1400);
        addItem("name15", "description6", true, 1500);
        addItem("name16", "description7", true, 1600);
        addItem("name17", "description8", true, 1700);
        addItem("name18", "description9", true, 1800);
        addItem("name19", "description0", true, 1900);

    }

    private void addItem(String name, String description, boolean vegetarian, double price) {
        MenuItem menuItem = new MenuItem(name, description, vegetarian, price);
        menuItems.add(menuItem);
    }


    public ArrayList getMenuItems() {
        return menuItems;
    }

    @Override
    public  Iterator getItereator() {
        return this;
    }
    @Override
    public boolean hasNext() {
        if (position >= menuItems.size() || menuItems.get(position) == null) {
            return false;
        }
        return true;
    }

    @Override
    public Object next() {
        MenuItem menuItem = (MenuItem) menuItems.get(position);
        position++;
        return menuItem;

    }

    @Override
    public void remove() {

    }
}

------------菜单2-----------

public class MenuLunch implements Iterator, Menu {
    private MenuItem[] menuItems;
    private int index = 0;
    private final int MAX_ITEMS = 10;
    private int position = 0;

    public MenuLunch() {
        menuItems = new MenuItem[MAX_ITEMS];
        addItem("name20", "description1", true, 2000);
        addItem("name21", "description2", true, 2100);
        addItem("name22", "description3", true, 2200);
        addItem("name23", "description4", true, 2300);
        addItem("name24", "description5", true, 2400);
        addItem("name25", "description6", true, 2500);
        addItem("name26", "description7", true, 2600);
        addItem("name27", "description8", true, 2700);
        addItem("name28", "description9", true, 2800);
        addItem("name29", "description0", true, 2900);

    }

    private void addItem(String name, String description, boolean vegetarian, double price) {
        MenuItem menuItem = new MenuItem(name, description, vegetarian, price);
        if (index >= MAX_ITEMS) {
            System.err.println("LIST FULL");
        } else {
            menuItems[index] = menuItem;
            index++;
        }

    }

    @Override
    public  Iterator getItereator() {
        return this;
    }


    public MenuItem[] getMenuItems() {
        return menuItems;
    }


    @Override
    public boolean hasNext() {
        if (position >= menuItems.length || menuItems[position] == null) {
            return false;
        }
        return true;
    }


    @Override
    public Object next() {
        MenuItem menuItem = (MenuItem) menuItems[position];
        position++;
        return menuItem;
    }

    @Override
    public void remove() {

    }
}

menu接口与Waitress类仅仅替换了所import的迭代器(java.util.Iterator),代码几乎无改动,我们也不再需要LunchItereator类与BreakfastItereator类了。经过一番工作,标准得到统一。










评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值