设计模式之组合模式与迭代器模式

读书笔记:headfirst 设计模式 ,大话设计模式


迭代器模式

使用场景
  • 当需要访问一个聚集对象,而且不管这些对象是什么都需要遍历时
单一责任原则

单一责任 : 一个类应该只有一个引起变化的原因
内聚 :用来度量一个类或模块紧密的达到单一目的或责任

  • 一个模块或一个类被设计只支持一组相关功能,称为高内聚
  • 反之当被设计成支持一组不相关的功能时,称为低内聚
类图

image
迭代器模式:提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示

  • 为遍历不同的聚集结构提供如开始,下一个,是否结束,当前哪一项等统一的接口
  • 迭代器模式就是分离了集合对象的遍历行为,分离出一个迭代器,使得集合的内部结构不被暴露,又可以让外部代码透明的访问集合内部数据
  • 迭代器将遍历聚合的工作封装进一个对象中
  • 当使用迭代器时,迭代器依赖聚合提供遍历
  • 迭代器提供了一个通用的接口,当编码使用聚合的项时,就可以使用多态机制
  • 我们应当努力让一个类只分配一个责任
空迭代器

如果集合中没有什么可以遍历的,有两种选择

  1. 返回null,但是代码就需要判断返回值是否为null
  2. 返回一个空迭代器,这个迭代器的hasNext永远返回false
代码案例
// 测试
public class TestClient {
    
    public static void main(String[] args) {
        Aggregate<String> agg = new ConcreteAggregate<String>();
        agg.add("a");
        agg.add("b");
        agg.add("c");
        MyIterator<String> createIterator = agg.createIterator();
        while (createIterator.hasNext()) {
            String next = createIterator.next();
            System.out.println(next);
        }
    }
}

结果:
a
b
c

// 迭代器接口
public interface MyIterator<T> {
    boolean hasNext();
    T next();
}

// 迭代器实现
public class ConcreteIterator<T> implements MyIterator<T> {
    
    private List<T> list ;
    private int mark = 0;
    private int size = 0;
    

    public ConcreteIterator(List<T> list) {
        this.list =list;
        this.size=list.size();
    }

    @Override
    public boolean hasNext() {
        if (mark<=(size-1)) {
            return true;
        }
        mark = 0;
        return false;
    }

    @Override
    public T next() {
        T t = list.get(mark);
        mark++;
        return t;
    }

}

// 聚集接口
public interface Aggregate<T> {
    MyIterator<T> createIterator();
    void add(T t);
}

// 聚合实现类
public class ConcreteAggregate<T> implements Aggregate<T> {
    
    private List<T> list = new ArrayList<T>();

    @Override
    public MyIterator<T> createIterator() {
        return new ConcreteIterator<T>(list);
    }

    @Override
    public void add(T t) {
        list.add(t);
    }

}

组合模式

组合模式:将对象组合成树形结构以表示"部分-整体"的层次结构.组合模式使得用户对单个对象和组合对象的使用具有一致性

  • 组合模式让用户可以一致的使用组合结构和单个对象
  • 组合模式提供一个结构,可同时包容个别对象和组合对象
  • 组合结构内的任意对象成为组件,组件可以是组合,也可以是叶节点

类图
image

使用场景
  • 需求中是体现部分与整体层次的结构时
  • 希望用户可以忽略组合对象与单个对象的不同,统一的使用组合结构中的所有对象时
代码案例
// 测试
public class ComponentTest {

    public static void main(String[] args) {
        Composite root = new Composite("根");
        Leaf leafA = new Leaf("叶子A");
        Composite branchB = new Composite("分支B");
        Composite branchC = new Composite("分支C");
        root.add(leafA);
        root.add(branchB);
        root.add(branchC);
        
        Composite branchC1 = new Composite("分支C1");
        Leaf leafC2 = new Leaf("叶子C2");
        branchC.add(branchC1);
        branchC.add(leafC2);
        
        Composite branchB1 = new Composite("分支B1");
        Leaf leafB2 = new Leaf("叶子B2");
        branchB.add(branchB1);
        branchB.add(leafB2);
        
        root.display(1);
    }
}

结果:
-根
---叶子A
---分支B
-----分支B1
-----叶子B2
---分支C
-----分支C1
-----叶子C2


// 组合接口
public interface Component {
    void add(Component t);
    void remove(Component t);
    void display(int depth);
}

// 组合抽象默认实现
public abstract class ComponentDefault implements Component {
    
    private String name;

    public ComponentDefault(String name) {
        this.name= name;
    }

    @Override
    public void add(Component t) {
        System.out.println("非法操作");
    }

    @Override
    public void remove(Component t) {
        System.out.println("非法操作");        
    }

    @Override
    public void display(int depth) {
        int abs = Math.abs(depth);
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < abs; i++) {
            sb.append("-");
        }
        System.out.println(sb.toString()+name);
    }

}

// 叶子节点
public class Leaf extends ComponentDefault {

    public Leaf(String name) {
        super(name);
    }
    
}

// 组合节点
public class Composite extends ComponentDefault {

    private List<Component> list = new ArrayList<Component>();

    public Composite(String name) {
        super(name);
    }

    @Override
    public void add(Component t) {
        list.add(t);
    }

    @Override
    public void remove(Component t) {
        list.remove(t);
    }

    @Override
    public void display(int depth) {
        super.display(depth);
        // 组合需要继续展示子节点
        for (Component component : list) {
            component.display(depth+2);
        }
    }
        
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值