设计模式-----迭代器模式和组合模式

设计模式—–迭代器模式和组合模式

个人博客,想要搭建个人博客的可以进来看看: http://www.ioqian.top/

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

组合模式 ,允许你将对象组合成树结构来表现“整体/部分”层次结构。组合可以让客户以一致的方式处理个别对象以及对象组合。

设计模式系列源码 : https://github.com/liloqian/DesiginModeDemo

1.迭代器模式

背景,在我们的code中,会使用各种各样的集合,最常用的有数组,链表等。在访问这些集合的过程中,访问的方式各不相同(数组:arr[i] —- List:list.get(i))为了是访问更加灵活,我们需要为所有的集合提供统一的访问接口,并且不暴露内部的表示。

1.1 迭代器模式UML类图
此处输入图片的描述

  • Iterator ,迭代抽象类
  • ConcreteIterator ,具体迭代器类,针对不同的集合种类有不同的实现
  • Aggregate , 集合抽象类 , 每种集合都要继承的接口
  • ConcreteAggregate , 具体的集合类

从上面我们可以发现,Client不需要和具体的集合交互,仅仅和迭代器接口和集合接口交互;迭代器负责访问数据,和集合的实现分开,使得责任各得其所;

1.2 代码
Iterator迭代抽象类

public interface Iterator {
    boolean hasNext(); //是否存在下一个元素
    Object next();     //返回下一个元素
    void remove();      //移除元素
}

Aggregate 集合抽象类

public interface Aggregate {
    Iterator createIterator(); //每个集合都要可以用迭代器遍历
}

ConcreteAggregate 具体集合类

 public class ArrayCollections implements Aggregate{
    //数据使用数组存储
    Person[] arrays = new Person[5];
    public ArrayCollections() {
        for (int i = 0; i < arrays.length; i++) {
            arrays[i] = new Person("Array"+i,i*i);
        }
    }
    @Override
    public Iterator createIterator() {
        return new ArrayLiterator(arrays);
    }
}
public class ListCollections implements Aggregate{
    //使用List存储数据
    List<Person> lists = new ArrayList<>();
    public ListCollections(){
        for(int i = 0 ; i < 5;i++){
            lists.add(new Person("List"+i,i*i));
        }
    }
    @Override
    public Iterator createIterator() {
        return new ListIterator(lists);
    }
}

ConcreteIterator 具体迭代器

public class ArrayLiterator implements Iterator {
    Person[] arrays;
    int position = 0;
    public ArrayLiterator(Person[] persons) {
        this.arrays = persons;
    }
    @Override
    public boolean hasNext() {
        if(position >= arrays.length || arrays[position] == null){
            return false;
        }else {
            return true;
        }
    }
    @Override
    public Object next() {
        Person person = arrays[position];
        position += 1;
        return person;
    }
    @Override
    public void remove() {
        throw new UnsupportedOperationException("暂不支持");
    }
}
public class ListIterator implements Iterator {
    List<Person> list;
    int position = 0;
    public ListIterator(List<Person> list) {
        this.list = list;
    }
    @Override
    public boolean hasNext() {
        if(position >= list.size() || list.get(position)==null){
            return false;
        }else {
            return true;
        }
    }
    @Override
    public Object next() {
        Person person = list.get(position);
        position += 1;
        return person;
    }
    @Override
    public void remove() {
        throw  new UnsupportedOperationException("暂不支持");
    }
}

测试Main

public class Main {
    public static void main(String[] args) {
        //使用抽象集合类
        Aggregate arrays = new ArrayCollections();
        Aggregate lists = new ListCollections();
        Iterator arrIterator = arrays.createIterator();
        Iterator listIterator = lists.createIterator();
        //可以看到两种集合的访问都是一样的,我们不知道内部细节
        printInfo(arrIterator);
        System.out.println("-----------分割线------------");
        printInfo(listIterator);
    }

    private static void printInfo(Iterator iterator) {
        while (iterator.hasNext() ){
            System.out.println(iterator.next());
        }
    }
}
//结果:
Person{name='Array0', age=0}
Person{name='Array1', age=1}
Person{name='Array2', age=4}
Person{name='Array3', age=9}
Person{name='Array4', age=16}
-----------分割线------------
Person{name='List0', age=0}
Person{name='List1', age=1}
Person{name='List2', age=4}
Person{name='List3', age=9}
Person{name='List4', age=16}

Process finished with exit code 0

2 设计原则 单一责任

单一责任,一个类应该只有一个引起变化的原因。

内聚是用来度量一个类或者模块紧密地到达单一目的或责任。当一个模块或者类被设计成只支持一组相关的功能时,我们说它具有高内聚;反之,说它具有低内聚。

3.组合模式

组合模式,又叫部分整体模式。是为了忽略单个对象和对象集合的区别,统一使用组合结构中的所以对象(包括集合和对象)

3.1组合模式UML类图

背景 我们要出去旅游,需要有组织有纪律,人太多不好管理所以需要分成一个个组织(一个组织可能一个人或多个人),有的队都有几个组织。博主这里描述不清楚了…..

此处输入图片的描述

  • Component , 为组合中的所有对象声明一个接口,不管是组合还是叶节点 ,背景中的组织
  • Leaf , 叶节点 ,组织只有一个人
  • Composite,有叶节点的操作和组合对象的操作 ,组织有好几个组织

Leaf和Composite的关系可以参考下图,类似UI树的,集合的成员可以是集合
此处输入图片的描述

3.2代码实现,模拟上图中的组合
Compoent

/**抽象父类*/
public abstract class PersonFather {
    //这里直接抛出异常是因为printInfo()方法所以继承者都要重写,不论leaf还是Composite
    public void printInfo(){
        throw new UnsupportedOperationException();
    }
    //下面这两个方法只有Composite必须实现,所以在leaf中调用会出现运行时异常提醒
    public void add(PersonFather element){
        throw new UnsupportedOperationException();
    }
    void remvoe(PersonFather p){
        throw  new UnsupportedOperationException();
    }
}

Leaf

public class PersonSelf extends PersonFather {
    //两个变量模拟对象状态
    String name;
    int gae;
    public PersonSelf(String name, int gae) {
        this.name = name;
        this.gae = gae;
    }
    //实现打印状态信息
    @Override
    public void printInfo() {
        System.out.println(this.toString());
    }
    @Override
    public String toString() {
        return "PersonSelf{" +
                "name='" + name + '\'' +
                ", gae=" + gae +
                '}';
    }
}

Composite

public class PesonGroup extends PersonFather {
    //存储子类的集合
    List<PersonFather> lists = new ArrayList<>();
    String name;
    String age;
    public PesonGroup(String name, String age) {
        this.name = name;
        this.age = age;
    }
    @Override
    public void add(PersonFather element) {
        lists.add(element);
    }
    @Override
    void remvoe(PersonFather p) {
        lists.remove(p);
    }

    @Override
    public void printInfo() {
        System.out.println(this.toString());
        System.out.println("--------打印组织成员信息 start------");
        Iterator iterator = lists.iterator();
        //迭代递归打印
        while (iterator.hasNext()){
            PersonFather peson = (PersonFather) iterator.next();
            peson.printInfo();
        }
        System.out.println("-----------------------   end-------");
    }

    @Override
    public String toString() {
        return "PesonGroup{" +
                "lists=" + lists +
                ", name='" + name + '\'' +
                ", age='" + age + '\'' +
                '}';
    }
}

测试Main

public class Main {
    public static void main(String[] args) {
        //root根节点
        PersonFather root = new PesonGroup("root",0+"");
        //2个leaf节点,root儿子
        PersonFather son1 = new PersonSelf("son1",1);
        PersonFather son2 = new PersonSelf("son2",2);
        //1个group节点,是root的儿子
        PersonFather Songroup3 = new PesonGroup("sonGroup3" , 3 + "");
        //root把儿子挂在自己下面
        root.add(son1);
        root.add(son2);
        root.add(Songroup3);
        //root的三儿子group节点由有4个儿子,root的4个孙子
        Songroup3.add(new PersonSelf("grandson1",1));
        Songroup3.add(new PersonSelf("grandson2",2));
        Songroup3.add(new PersonSelf("grandson3",3));
        Songroup3.add(new PersonSelf("grandson4",4));
        //打印root家族信息
        root.printInfo();
        System.out.println("******************我是分割线*********************");
        //打印root三儿子家族信息
        Songroup3.printInfo();
        System.out.println("******************我是分割线*********************");
        //打印root大儿子信息,就一个单身狗
        son1.printInfo();
    }
}
//结果:
PesonGroup{lists=[PersonSelf{name='son1', gae=1}, PersonSelf{name='son2', gae=2}, PesonGroup{lists=[PersonSelf{name='grandson1', gae=1}, PersonSelf{name='grandson2', gae=2}, PersonSelf{name='grandson3', gae=3}, PersonSelf{name='grandson4', gae=4}], name='sonGroup3', age='3'}], name='root', age='0'}
--------打印组织成员信息 start------
PersonSelf{name='son1', gae=1}
PersonSelf{name='son2', gae=2}
PesonGroup{lists=[PersonSelf{name='grandson1', gae=1}, PersonSelf{name='grandson2', gae=2}, PersonSelf{name='grandson3', gae=3}, PersonSelf{name='grandson4', gae=4}], name='sonGroup3', age='3'}
--------打印组织成员信息 start------
PersonSelf{name='grandson1', gae=1}
PersonSelf{name='grandson2', gae=2}
PersonSelf{name='grandson3', gae=3}
PersonSelf{name='grandson4', gae=4}
-----------------------   end-------
-----------------------   end-------
******************我是分割线*********************
PesonGroup{lists=[PersonSelf{name='grandson1', gae=1}, PersonSelf{name='grandson2', gae=2}, PersonSelf{name='grandson3', gae=3}, PersonSelf{name='grandson4', gae=4}], name='sonGroup3', age='3'}
--------打印组织成员信息 start------
PersonSelf{name='grandson1', gae=1}
PersonSelf{name='grandson2', gae=2}
PersonSelf{name='grandson3', gae=3}
PersonSelf{name='grandson4', gae=4}
-----------------------   end-------
******************我是分割线*********************
PersonSelf{name='son1', gae=1}

Process finished with exit code 0

3.3 组合模式总结

  • 整体/部分思想,包含其他组件的组件称为组合对象,没有包含其他组件的组件称为叶节点对象
  • 调用组合对象或者叶节点对象的方式一致,如果一些方法对叶节点没有意义可以空实现,也可以和代码中的一样直接抛出异常
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值