java_iterator

introduction:

迭代器模式:
提供一个方法顺序访问一个聚合对象的各个元素,而又不暴露其内部的表示。
如果有一个统一的办法访问聚合中的每一个对象,你就可以编写多态的代码和这些聚合搭配。
元素之间游走的任务交给迭代器,而不是聚合对象。这不仅让聚合的接口和实现变得更简洁,也让聚合更专注在管理对象集合上。

demo:

1.模拟自己一天的三餐菜单

description:迭代器模式对外提供统一的接口,迭代不同的对象可能使用不同的方法,因此,对于我来说一天三餐,可能更多,而每一餐的菜单是不一样的,比如说早上我的菜单是用数组存储的,中午时用ArrayList存储的,晚上使用Hashtable存储的。而对外我需要提供一个同一个的接口,让别人通过这个同一个的接口来查看我的菜单。

MenuItem.java

/**
 * 用于描述菜单
 */
public class MenuItem {
    private String name;
    private Double price;
    /**
     * @return the name
     */
    public String getName() {
        return name;
    }
    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }
    /**
     * @return the price
     */
    public Double getPrice() {
        return price;
    }
    /**
     * @param price the price to set
     */
    public void setPrice(Double price) {
        this.price = price;
    }
    /**
     * @param name
     * @param price
     */
    public MenuItem(String name, Double price) {
        this.name = name;
        this.price = price;
    }
    
}

Menu.java

/**
 * 提供统一的菜单接口
 */
public interface Menu<T> {
    Iterator<T> createIterator();
}

BreakfastMenu.java

/**
 * 早餐菜单采用数组实现
 */
public class BreakfastMenu implements Menu<MenuItem>{
    
    private static final Integer ITEM_MAX = 6;
    private MenuItem[] items;
    
    private Integer position = 0;
    
    public BreakfastMenu(){
        items = new MenuItem[ITEM_MAX];
        addItem("牛奶",2.0);
        addItem("面包",3.0);
    }
    
    public void addItem(String name,Double price){
        MenuItem menuItem = new MenuItem(name,price);
        if(position >= ITEM_MAX){
            System.err.println("点餐已达极限!");
        }else{
            items[position] = menuItem;
            position += 1;
        }
    }

    @Override
    public Iterator<MenuItem> createIterator() {
        return new BreakfastMenuIterator(items);
    }
    
}

LunchMenu.java

/**
 * 午饭菜单采用ArrayList存储
 */
public class LunchMenu implements Menu<MenuItem>{

    private ArrayList<MenuItem> menus ;
    
    public LunchMenu(){
        menus = new ArrayList<MenuItem>();
        addItem("鸡块",5.00);
        addItem("莴苣炒鸡丁",4.00);
        addItem("紫菜汤",0.00);
        addItem("菠菜烧鸡蛋",2.00);
    }
    
    public void addItem(String name,Double price){
        MenuItem item = new MenuItem(name,price);
        menus.add(item);
    }
    @Override
    public Iterator<MenuItem> createIterator() {
        return menus.iterator();
    }

}

DinnerMenu.java

/**
 *晚餐采用Hashtable存储
 */
public class DinnerMenu implements Menu<MenuItem>{
    
    private Hashtable<String,MenuItem> menus;
    
    public DinnerMenu(){
        menus = new Hashtable<String,MenuItem>();
        addItem("红烧鳊鱼",5.00);
        addItem("青菜烧咸肉",4.00);
    }
    
    public void addItem(String name,Double price){
        MenuItem item = new MenuItem(name,price);
        menus.put(item.getName(), item);
    }

    @Override
    public Iterator<MenuItem> createIterator() {
        return menus.values().iterator();
    }
    
}

由于ArrayList、Hashtable都已经实现了Iterator接口,因此都可以直接实现迭代功能,对于数组来说没有,因此,需要手工实现。

BreakfastMenuIterator.java

/**
 * 早餐采用数组形式存储,因此需要实现Iterator接口,重写相关方法
 */
public class BreakfastMenuIterator implements Iterator<MenuItem>{

    private MenuItem[] items;
    
    private Integer position = 0;
    
    public BreakfastMenuIterator(MenuItem[] items){
        this.items = items;
    }
    
    @Override
    public boolean hasNext() {
        if(position>=items.length || items[position] == null){
            return false;
        }else{
            return true;
        }
    }

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

    @Override
    public void remove() {
        if(position <= 0){
            throw new IllegalStateException("该元素不存在");
        }
        if(items[position-1] != null){
            for(int i=position-1;i<items.length;i++){
                items[i] = items[i+1];
            }
            items[items.length-1] = null;
        }
    }

}

服务员类,主要作用是管理三餐

Service.java

public class Service {
    
    private ArrayList menus;
    
    public Service(ArrayList menus){
        this.menus = menus;
    }
    
    public void printMenu(){
        Iterator<Menu> menuIterator = menus.iterator();
        while(menuIterator.hasNext()){
            Menu menu = (Menu)menuIterator.next();
            printMenu(menu.createIterator());
        }
    }
    
    public void printMenu(Iterator<MenuItem> iterator){
        while(iterator.hasNext()){
            MenuItem menuItem = iterator.next();
            System.out.println(menuItem.getName()+",");
            System.out.println(menuItem.getPrice());
        }
        System.out.println();
        
    }
}

Test.java

public class Test {
    public static void main(String[] args) {
        //1.实例化三餐
        Menu<MenuItem> breakfast = new BreakfastMenu();
        Menu<MenuItem> lunch = new LunchMenu();
        Menu<MenuItem> dinner = new DinnerMenu();
        //2.将三餐添加到ArrayList中
        ArrayList<Menu> list = new ArrayList<Menu>();
        list.add(breakfast);
        list.add(lunch);
        list.add(dinner);
        
        Service service = new Service(list);
        
        service.printMenu();
    }
}

输出结果:

牛奶,
2.0
面包,
3.0


鸡块,
5.0
莴苣炒鸡丁,
4.0
紫菜汤,
0.0
菠菜烧鸡蛋,
2.0


青菜烧咸肉,
4.0
红烧鳊鱼,
5.0

在迭代器设计模式中,我们遇到了一个OO设计原则-单一责任原则

单一责任原则:
一个类应该只有一个引起变化的原因
类的每个责任都有改变的潜在区域,超过一个责任,意味着超过一个改变区域。
这个原则告诉我们,尽量让每个类保持单一责任。
我们知道要避免类内的改变,因为修改代码很容易造成许多潜在的错误。
内聚是用来衡量一个类或模块紧密地达到单一目的或责任。
当一个模块或一个类被设计成只支持一组相关的功能时,我们说它具有高内聚;反之,当被设计成支持一组不相关的功能时,我们说它是低内聚。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值