设计模式系列(2)- 迭代器模式、适配器模式

迭代器模式

简介

所谓迭代器模式,就是面向Iterator接口编程,无论底层的数据结构和迭代算法如何变化,调用者都不用修改代码;

高内聚,低耦合,才是程序设计之道。

一般很少需要自己写这个iterator模式,都是在集合编程中使用,尤其是如果要对集合元素遍历过程中做插入删除操作,那就用iterator,如果要对某个类中的集合进行遍历,由那个集合类返回一个iterator回来,统一面向iterator迭代器接口来编程遍历,提高系统整体的可维护性,可扩展性。

如果自己写iterator模式,一般是研发底层的框架,比如提供某个数据给外部遍历,那么可以使用iterator模式自己封装迭代器。

使用场景

集合迭代,遍历元素。

代码示例

package com.wc.designpattern.iterator;

import lombok.Data;

/**
 * 迭代器模式
 */
public class IteratorPatternApplication {

    @Data
    static class Student {
        private String name;

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

        @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    '}';
        }
    }

    static class Classroom {
        private Student[] students;
        private int last = 0;

        public Classroom(int size) {
            this.students = new Student[size];
        }

        public Student getStudents(int index) {
            return students[index];
        }

        public void addStudents(Student students) {
            this.students[last] = students;
            last ++;
        }

        public int getLength() {
            return last;
        }

        public Iterator iterator() {
            return new ClassroomIterator(this);
        }
    }

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

    static class ClassroomIterator implements Iterator {
        private Classroom classroom;
        private int index;

        public ClassroomIterator(Classroom classroom) {
            this.classroom = classroom;
            this.index = 0;
        }

        @Override
        public boolean hasNext() {
            if (index < classroom.getLength()) {
                return true;
            } else {
                return false;
            }
        }

        @Override
        public Object next() {
            Student student = classroom.getStudents(index);
            index ++;
            return student;
        }
    }

    public static void main(String[] args) {
        Student s1 = new Student("lilei");
        Student s2 = new Student("hanmeimei");

        Classroom classroom = new Classroom(2);
        classroom.addStudents(s1);
        classroom.addStudents(s2);

        Iterator iterator = classroom.iterator();
        while (iterator.hasNext()) {
            Student student = (Student) iterator.next();
            System.out.println(student);
        }
    }
}

测试

执行Main函数,得到执行结果

Student{name='lilei'}
Student{name='hanmeimei'}

Process finished with exit code 0

适配器模式

简介

适配器模式,一般是在系统不断升级的过程中使用,对已经写好的老代码,写一套适配器来适配,但是提供新的接口。

还有一种情况,是对于已有的第三方类库,比如redis的客户端,或者是elasticsearch的客户端,他们提供了一套API,但是我们这里的要求是需要面向我们这里的DAO接口来进行编程,此时可以写一个适配器,将比如redis客户端的接口适配到我们的接口。

使用场景

(1)假设我们做了一个第一版的一个系统,这个系统里有一个接口和一个实现类

(2)接着我们开始做第二版的系统,这个系统我们定义了一个新的接口,和新的实现类

(3)但是我们同时在第二版的系统中,也要使用第一版系统中定义的那个老接口和老实现类

代码示例

没有使用设计模式

package com.wc.designpattern.adapter;

/**
 * 不使用迭代器模式,就会出现新老两套接口,无法适配的问题
 * 在使用的地方可能需要调用多套API,但是因为是新老两套接口,
 * 会有很多重复的代码,就不是一个好的设计。
 */
public class NonPatternApplication {

    public interface V1Interface {
        void v1Execute();
    }

    static class V1InterfaceImpl implements V1Interface {
        @Override
        public void v1Execute() {
            System.out.println("v1 operator...");
        }
    }

    public interface V2Interface {
        void v2Execute();
    }

    static class V2InterfaceImpl implements V2Interface {
        @Override
        public void v2Execute() {
            System.out.println("v2 operator...");
        }
    }

    public static void main(String[] args) {
        V1Interface v1 = new V1InterfaceImpl();
        V2Interface v2 = new V2InterfaceImpl();
        v1.v1Execute();
        v2.v2Execute();
    }
}

使用适配器模式

package com.wc.designpattern.adapter;

/**
 * 适配器模式
 * 就是你手上有新老俩接口和一个老接口的实现类
 * 但是现在系统中要面向新接口来开发,老接口的实现类就不能直接用了,不能直接面向老接口来开发
 * 开发一个老接口到新接口的一个适配器
 * 适配器是实现了新接口的,但是适配器中持有老接口实现类实例的引用
 * 适配器的新接口方法的实现,全部基于老接口实现类的老方法来实现即可
 * 对于调用方而言,只要使用适配器来开发即可,就可以通过面向新接口开发,底层使用老接口实现类
 *
 * @author WenChao
 * @date 21/12/23
 */
public class AdapterPatternApplication {

    public interface V1Interface {
        void v1Execute();
    }

    static class V1InterfaceImpl implements V1Interface {
        @Override
        public void v1Execute() {
            System.out.println("v1 operator...");
        }
    }

    public interface V2Interface {
        void v2Execute();
    }

    static class V2InterfaceImpl implements V2Interface {
        @Override
        public void v2Execute() {
            System.out.println("v2 operator...");
        }
    }

    /**
     * 定义一个适配器类
     */
    static class V2Adapter implements V2Interface {
        private V1Interface v1Interface;

        public V2Adapter(V1Interface v1Interface) {
            this.v1Interface = v1Interface;
        }

        @Override
        public void v2Execute() {
         v1Interface.v1Execute();
        }
    }

    public static void main(String[] args) {
        V2Interface v1 = new V2Adapter(new V1InterfaceImpl());
        V2Interface v2 = new V2InterfaceImpl();
        v1.v2Execute();
        v2.v2Execute();
    }
}

测试

v1 operator...
v2 operator...

Process finished with exit code 0
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值