Iterator Pattern

Create your own custom Iterator so that it will iterate upons custom logic

Considering the following system

package designpatterns.iterator;

import java.util.HashMap;
import java.util.Map;

public class TemplateSystem {
  private final Map<String, Template> templateIdToTemplate;

  public TemplateSystem() {
    templateIdToTemplate = new HashMap<>();
  }

  public void saveTemplate(Template userTemplate) {

    Template template = new Template(userTemplate); // Use copy constructor here to avoid letting user modify the original object
    Template previousTemplate = templateIdToTemplate.get(template.id);

    if (previousTemplate != null) {
      template.setVersion(previousTemplate.getVersion() + 1);
      userTemplate.setVersion(template.getVersion()); // reflect the new change on user object
    } else {
      template.setVersion(0);
    }

    template.setPreviousTemplate(previousTemplate);
    templateIdToTemplate.put(template.id, template);
  }

  public void searchAllVersion(Template template) {
    VersionIterator templateIterator = new VersionIterator(templateIdToTemplate.get(template.id));
    while (templateIterator.hasNext()) {
      Template currentTemplate = templateIterator.next();
      System.out.printf("%s: %s %s %n", currentTemplate.getVersion(), currentTemplate.templateName, currentTemplate.color);
    }
  }
}

With a custom VersionIterator

package designpatterns.iterator;

import java.util.Iterator;

public class VersionIterator implements Iterator<Template> {
  private Template templateCursor;

  public VersionIterator(Template template) {
    templateCursor = template;
  }

  @Override
  public boolean hasNext() {
    return templateCursor != null;
  }

  @Override
  public Template next() { // go back to previous version
    Template currentTemplate = templateCursor;
    templateCursor = templateCursor.getPreviousTemplate();
    return currentTemplate;
  }
}

package designpatterns.iterator;


import java.util.UUID;

public class Template {
  public final String id;
  public final String color;
  public String templateName;
  private Integer version;

  private Template previousTemplate;

  public Template(String color, String templateName) {
    this.id = UUID.randomUUID().toString();
    this.color = color;
    this.templateName = templateName;
  }

  public Template(Template template) {
    this.id = template.id;
    this.color = template.color;
    this.templateName = template.templateName;
    this.version = template.version;
  }


  public Integer getVersion() {
    return version;
  }

  public void setVersion(Integer version) {
    this.version = version;
  }

  public Template getPreviousTemplate() {
    return previousTemplate;
  }

  public void setPreviousTemplate(Template previousTemplate) {
    this.previousTemplate = previousTemplate;
  }
}

package designpatterns.iterator.test;

import designpatterns.iterator.Template;
import designpatterns.iterator.TemplateSystem;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class TemplateSystemTest {
  @Test
  void endToEnd_givenTemplateSystem_shouldIterateThroughPreviousTemplate() {
    TemplateSystem templateSystem = new TemplateSystem();
    Template firstTemplate = new Template("red", "my template name");
    Template secondTemplate = new Template("blue", "my template name");
    templateSystem.saveTemplate(firstTemplate);
    templateSystem.saveTemplate(secondTemplate);

    // Modification to the first template
    firstTemplate.templateName = "another template name";
    templateSystem.saveTemplate(firstTemplate);

    firstTemplate.templateName = "yes template name";
    templateSystem.saveTemplate(firstTemplate);

    secondTemplate.templateName = "hi template name";
    templateSystem.saveTemplate(secondTemplate);

    assertEquals(2, firstTemplate.getVersion());
    assertEquals(1, secondTemplate.getVersion());

    templateSystem.searchAllVersion(firstTemplate);
    templateSystem.searchAllVersion(secondTemplate);
  }
}
2: yes template name red 
1: another template name red 
0: my template name red 
1: hi template name blue 
0: my template name blue 

[!important]
Considering VersionControlSystem as alternative approaches