java - 通过单独的类在复合设计模式上实现迭代器 - 它在编程上是否有效?

标签 java iterator composite iterable

我已经实现了 Composite Design Pattern,然后扩展了 Composite 类以实现 Iterable,但是 iterator() 方法(返回迭代器对象)也是抽象 Component 类的一部分,然后由 Composite 类实现(但不是 Leaf 类)。

我想对树状结构实现深度优先和广度优先搜索。请参阅下面的摘要代码:

public abstract class Component {

  public void add() {
  }

  public void remove() {
  }

  public ArrayList<Component> getItems() {
  }

  public ItemIterator iterator() {
  }
public class Composite extends Component implements Iterable<Component> {

  ArrayList<Component> items = new ArrayList<Component>();
  String name;

  public ItemIterator iterator() {
  return new ItemIterator(this);
  }

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

  public getName() {
  // returns name
  }

  public ArrayList<Component> getItems() {
  return this.items;
  }
public class ItemIterator implements Iterator<Component> {

  ArrayList<Component> breadthFirstSearch = new ArrayList<Component>();
  Component currentItem;

  public ItemIterator(Component firstItem) {
  currentItem = firstItem;
  breadthFirstSearch.add(currentItem);
  }

  public boolean hasNext() {
  if (breadthFirstSearch.isEmpty()) {
    return false;
  }
  return true;
  }

  public Component next() {
  // This method pops the root item the first time, creates its children, 
  // places at end of ArrayList,
  // then returns the root. Second time the same operations are performed
  // on the following item in the breadth first traversal of the tree.
  if (hasNext()) {
    Component nextItem = breadthFirstSearch.get(0);
    if (nextItem instanceof Composite) {
      for (Component item : currentItem.getItems()) {
        breadthFirstSearch.add(item);
      }
    }
    breadthFirstSearch.remove(0);
    if (hasNext()) {
      currentItem = breadthFirstSearch.get(0);
    }
    return nextItem;
  }
  return null;
  }
public class Demo {

  public static void main(String[] args) {
    Component bag = new Composite("bag");
    Component plasticBag = new Composite("plastic bag");
    Component makeupBag = new Composite("makeup bag");
    Component phone = new Composite("phone");
    Component lipstick = new Composite("lipstick");
    Component mascara = new Composite("mascara");

    bag.add(plasticBag); bag.add(makeupBag);
    plasticbag.add(phone); makeupBag.add(lipstick); makeupBag.add(mascara);

    ItemIterator itr = bag.iterator();

    while (itr.hasNext()) {
      System.out.println(itr.next().getName());
    }
  }
}

上面的代码可以正常编译和运行,它可以工作。但是,我不确定它是否在编程上是可接受的。它的结构似乎从根本上违背了我见过的其他 Iterator 实现(我在完成上述解决方案后发现的实现),但我不能完全理解/解释它有什么问题。另一种实现 Iterable 的方法(在不同的上下文中)是以下形式:

public abstract class Component {

  public void add() {
  }

  public void remove() {
  }

  public ArrayList<Component> getItems() {
  }
}

请注意上面的抽象类中缺少 iterator() 方法。

public class Composite extends Component implements Iterable<Component> {

  ArrayList<Component> items = new ArrayList<Component>();
  String name;

  public Iterator<Component> iterator() {

    return new Iterator() {
      public boolean hasNext() {
      // Code
      }

      public Iterator<Component> next() {
      // Code
      };
  }

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

  public getName() {
  // returns name
  }

  public ArrayList<Component> getItems() {
  return this.items;
  }
}

哪种构建解决方案的方式更好,我的做法是完全错误的/不好的做法,如果是这样,为什么?我是 Java 的新手,所以如果这是一个糟糕的问题,我深表歉意。

最佳答案

我认为您描述了访问者模式:

interface Visitable {
   void accept(Visitor v);
}

class Visitor {
    void visit(Component c){
        c.doFooBar();// implement your logic here
    }

}

class Component implements Visitable {

    private List<Component> children;

    void accept(Visitor v){
        v.visit(this);
        children.forEach(child -> child.accept(v)); // sumbit the visitor/iterator down the composite tree
    }
}

public static void main(String[] args){
    Component composite = Factory.createComposite();
    composite.accept(new Visitor());
}

关于java - 通过单独的类在复合设计模式上实现迭代器 - 它在编程上是否有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57963817/

相关文章:

java - Controller Spring MVC 之前的自定义逻辑

java - 编程接口(interface)和同步集合

size - SWT 复合 Material 最大尺寸

c++ - 当数据可以在类对象超出范围之前被删除时,类允许访问其数据(通过 ptr/it)是不是糟糕的设计?

c# - 如何注入(inject)具有开放泛型类型的集合以使用 Autofac 提供服务

linux - Wayland 合成器不能像在 X 上那样做窗口装饰吗?

java - null是java中的一个类吗?

java - Java 中的可重置超时

generics - 你如何像 itertools 那样用 collect_vec() 扩展一个特征?

javascript - 比较多个点之间的距离