访问者模式 VS 迭代器模式:跨层次结构类访问?

2024-04-10

我正在研究访客模式的优点,并引用设计模式 http://it.wikipedia.org/wiki/Design_Patterns:

但是迭代器不能跨具有不同结构的对象工作 元素类型。例如,页面上定义的 Iterator 接口 295 只能访问Item类型的对象:

template <class Item> 
clas  Iterator { // ... Item CurrentItem() const; };

这意味着迭代器可以访问的所有元素都有一个共同的父类 Item。 访客没有此限制...

class Visitor {
public:
// ...
void VisitMyType(MyType*);
void VisitYourType(YourType*);
};

MyType 和 YourType 不必通过继承关联起来 全部。

我同意这句话,但我无法找出访问者模式可以探索结构的示例(例如List) 其中收集的对象与超类不相关。

换句话说,您能给我举一个例子来证明上述特征是正确的吗?


首先,您应该知道这些模式的用途。

迭代器模式用于顺序访问聚合而不暴露其底层表示。因此,您可以在迭代器后面隐藏列表或数组或类似的聚合。

访问者模式用于对元素结构执行操作,而无需更改元素本身的实现。

因此,您可以在两种不同的情况下使用这些模式,而不是相互替代。

在访问者模式中,您在要访问的每个元素中实现接口 IAcceptor。因此,访问者模式不依赖于超类,而是依赖于接口

public interface IAcceptor
{
    public void Accept(IVisitor visitor);
}

因此,如果您有一个对象列表,您可以对其进行迭代并访问实现 IAcceptor 的对象

public VisitorExample()
{
    MyVisitorImplementation visitor = new MyVisitorImplementation();
    List<object> objects = GetList();
    foreach(IAcceptor item in objects)
        item.Accept(visitor);
}


public interface IVisitor
{
    public void Visit(MyAcceptorImplementation item);
    public void Visit(AnotherAcceptorImplementation item);
}

public class MyAcceptorImplementation : IAcceptor
{ 
    //Some Code ...
    public void Accept(IVisitor visitor)
    {
        visitor.Visit(this);
    }
}

要完成这里的代码,如果访问者访问我的或另一个接受器的实现,则将其写入控制台。

public class MyVisitorImplementation : IVisitor
{
        public void Visit(MyAcceptorImplementation item)
        {
            Console.WriteLine("Mine");
        }
        public void Visit(AnotherAcceptorImplementation item)
        {
            Console.WriteLine("Another");
        }
}

有关更多有用的示例和更好的解释,请查看访客模式 http://www.dofactory.com/net/visitor-design-pattern and 迭代器模式 http://www.dofactory.com/net/iterator-design-pattern

编辑:这里是一个同时使用访问者和迭代器的示例。迭代器只是如何在聚合中移动的逻辑。如果采用分层结构会更有意义。

public VisitorExample2()
{
    MyVisitorImplementation visitor = new MyVisitorImplementation();
    List<object> myListToHide = GetList();

    //Here you hide that the aggregate is a List<object>
    ConcreteIterator i = new ConcreteIterator(myListToHide);

    IAcceptor item = i.First();
    while(item != null)
    {
       item.Accept(visitor);
       item = i.Next();
    }
    //... do something with the result
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

访问者模式 VS 迭代器模式:跨层次结构类访问? 的相关文章

  • 通用 C++ 多维迭代器

    在我当前的项目中 我正在处理多维数据结构 底层文件按顺序存储 即一个巨大的数组 没有向量的向量 使用这些数据结构的算法需要知道各个维度的大小 我想知道是否已在某处以通用方式定义了多维迭代器类 以及是否有任何标准或首选方法来解决此问题 目前
  • Javascript:使用非连续键迭代数组

    我需要迭代一个键不连续的数组 var messages new Array messages 0 This is the first message messages 3 This is another message 显然 使用 for
  • 访问者模式对于动态类型语言有用吗?

    访问者模式允许在不扩展对象类的情况下编写对对象的操作 当然 但为什么不直接编写一个全局函数或静态类来从外部操作我的对象集合呢 基本上 在像 java 这样的语言中 accept 出于技术原因需要方法 但在一种语言中我可以实现相同的设计而无需
  • 调试时无法进入迭代器块 (C#)

    我正在尝试调试从单元测试项目执行的代码 但是当我尝试进入一个方法时 它只是直接传递到下一行 并且不会命中该方法内的断点 该方法位于不同项目中的一个类上 但所有代码都是在调试模式下构建的 我已经尝试清理和重建解决方案 但没有任何乐趣 然而 自
  • 为什么 std::search 需要前向迭代

    我的问题与下面的线程相同 我正在努力理解给出的答案 或者更确切地说 我的代码不应该工作 因为它只使用输入迭代器 但我的 func 似乎工作并且行为与 std search 相同 所以我不知所措 不愿意在没有正确理解的情况下继续前进 也许如果
  • 编写迭代器[重复]

    这个问题在这里已经有答案了 编者注 此代码示例来自 Rust 1 0 之前的版本 不是有效的 Rust 1 0 代码 此代码的更新版本不再因更改方式而产生错误for循环被实现 我正在用 Rust 编写一个 Vector 结构 pub str
  • 在迭代器上使用 map()

    假设我们有一张地图 let m new Map using m values 返回一个地图迭代器 但我不能使用forEach or map 在该迭代器上并在该迭代器上实现 while 循环似乎是一种反模式 因为 ES6 提供了类似的函数ma
  • 为什么迭代器使用“!=”而不是“<”?

    我习惯这样写循环 for std size t index 0 index lt foo size index Do stuff with foo index 但是当我在其他人的代码中看到迭代器循环时 它们看起来像这样 for Foo It
  • 迭代 std 容器中的所有元素对 (C++)

    迭代 std 容器中所有元素对的最佳方法是什么std list std set std vector etc 基本上与此等效 但使用迭代器 for int i 0 i lt A size 1 i for int j i 1 j lt A s
  • 迭代 Hashmap 时如何得到 ConcurrentModificationException?

    我正在尝试将键值对添加到迭代器方法内的哈希映射中 但这并没有给我ConcurrentModificationException Why 由于 Hashmap 是快速失败的 Map
  • 如何解决 pandas 读取大 csv 文件时的内存问题

    我有一个 100GB 的 csv 文件 其中有数百万行 我需要在 pandas 数据框中一次读取 10 000 行 并将其分块写入 SQL 服务器 我按照建议使用了 chunksize 以及 iteartorhttp pandas docs
  • 并行迭代器

    我正在设计一个 C 数据结构 用于图形 供并行代码 使用 OpenMP 使用 假设我想要一个能够迭代所有元素 节点 的方法 当然 这个迭代将是并行的 是否可以使用迭代器来实现此目的 迭代器应该是什么样子才能实现并行访问 在这种情况下 您会建
  • 使用 std::istream_iterator 限制 std::copy 的范围

    我构建了一个最小的工作示例来展示我在使用 STL 迭代器时遇到的问题 我在用着istream iterator读书floatss 或其他类型 来自 astd istream include
  • 在 C++ 中将惰性生成器实现为forward_iterator

    MyGenerator 表示 可能 有限的整数序列 计算成本很高 所以我不想预先生成它们并将它们放入容器中 struct MyGenerator bool HasNext int Next 要打印全部 MyGenerator generat
  • 使用迭代器将部分文件流读入字符串

    这是我到目前为止所尝试过的但没有成功 std string ReadPartial std ifstream file int size std istreambuf iterator
  • 产量回报延迟迭代问题

    我知道yield return 利用了延迟加载 但我想知道我是否可能滥用迭代器或者很可能需要重构 我的递归迭代器方法返回给定的所有祖先PageNode包括pageNode itself public class PageNodeIterat
  • 打字稿地图迭代失败

    我正在使用下面的函数来比较两个地图 有趣的是 for 循环内的代码永远不会被执行 所以 console log key val 代码永远不会被执行 当然 我确保我正在比较的映射不为空并且大小相同 以强制执行 for 循环内的代码 我犯了一个
  • 链表迭代器实现 C++

    我已经在 C 中创建了一个链接列表 并想为其实现一个迭代器 以便我可以执行范围循环 for const int i list where Linked List
  • 从tensorflow 2.0 beta中的tf.data.Dataset检索下一个元素

    在tensorflow 2 0 beta之前 要从tf data Dataset中检索第一个元素 我们可以使用迭代器 如下所示 usr bin python import tensorflow as tf train dataset tf
  • 列表到优先队列

    我有一个 C 大学编程项目 分为两个部分 在开始第二部分时应该使用priority queues hash tables and BST s 我 至少 在优先级队列方面遇到了麻烦 因为它迫使我自己重做第一部分中已经实现的许多代码 该项目是关

随机推荐