Iterator mode
brief introduction
The so-called Iterator mode is the interface programming for Iterator. No matter how the underlying data structure and iterative algorithm change, the caller does not need to modify the code;
High cohesion and low coupling are the way of programming.
Generally, you rarely need to write this iterator mode yourself, which is used in Collection programming. In particular, if you want to insert and delete the collection elements during traversal, use the iterator. If you want to traverse the collection in a class, the collection class returns an iterator, and the iterator interface is used for programming traversal, Improve the maintainability and scalability of the whole system.
If you write the iterator pattern yourself, you usually develop the underlying framework, such as providing a data for external traversal, you can use the iterator pattern to encapsulate the iterator yourself.
Usage scenario
Set iteration, traversing elements.
Code example
package com.wc.designpattern.iterator; import lombok.Data; /** * Iterator mode */ 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); } } }
test
Execute the Main function to get the execution result
Student{name='lilei'} Student{name='hanmeimei'} Process finished with exit code 0
Adapter mode
brief introduction
The adapter mode is generally used in the process of continuous system upgrading. For the old code that has been written, write a set of adapters to adapt, but provide new interfaces.
In another case, for the existing third-party class libraries, such as redis clients or elasticsearch clients, they provide a set of API s, but our requirement here is to program for our DAO interface. At this time, you can write an adapter to adapt the interface of redis clients to our interface.
Usage scenario
(1) Suppose we make a first version of a system with an interface and an implementation class
(2) Then we started to make the second version of the system. In this system, we defined a new interface and a new implementation class
(3) However, in the second version of the system, we should also use the old interface and class defined in the first version of the system
Code example
Design patterns are not used
package com.wc.designpattern.adapter; /** * If the iterator mode is not used, there will be the problem that the old and new interfaces cannot be adapted * It may be necessary to call multiple sets of API s where they are used, but because they are new and old interfaces, * There will be a lot of repetitive code, which is not a good design. */ 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(); } }
Use adapter mode
package com.wc.designpattern.adapter; /** * Adapter mode * That is, you have two new and old interfaces and an implementation class of an old interface * But now the system should be developed for the new interface, and the implementation classes of the old interface can not be used directly, and can not be developed directly for the old interface * Develop an adapter from an old interface to a new interface * The adapter implements the new interface, but the adapter holds the reference of the old interface implementation class instance * The implementation of the new interface method of the adapter is based on the old method of the old interface implementation class * For the caller, as long as the adapter is used for development, it can be developed by facing the new interface, and the bottom layer uses the old interface to implement the class * * @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..."); } } /** * Define an adapter class */ 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(); } }
test
v1 operator... v2 operator... Process finished with exit code 0