迭代器模式
定义:提供一个对象来顺序访问聚合对象中的一系列数据,而不暴露聚合时对象的内部表示。
优缺点
优点:
-
访问一个聚合对象的内容而无需暴露它的内部表示
; -
遍历任务交由迭代器完成,这
简化了聚合类
; -
它
支持以不同方式遍历一个聚合
,甚至可以自定义迭代器的子类以支持新的遍历; -
增加新的聚合类和迭代器类都很方便
,无须修改原有的代码; -
封装性良好
,为遍历不同的聚合结构提供了一个统一的接口。
缺点:增加了类的个数,在一定程度上增加了系统的复杂性。
应用场景
-
当
需要为聚合对象提供多种遍历方式时
。 -
当
需要为遍历不同的聚合结构提供一个统一的接口时
。 -
当
访问一个聚合对象的内容而无需暴露其内部细节的表示时
。
主要角色
- 抽象聚合(Aggregate)角色:定义存储、添加、删除聚合对象以及创建迭代器对象的接口。
- 具体聚合(ConcreteAggregate)角色:实现抽象聚合类,返回一个迭代器的实例。
- 抽象迭代(Iterator)角色:定义访问和遍历聚合元素的接口,通常包含以下方法:hasNext()、first()、next()等。
- 具体迭代器(ConcreteIterator)角色:实现抽象迭代器接口中所定义的方法,完成对聚合对象的遍历,记录遍历的当前位置。
结构图
应用实例
婺源的名胜古迹较多,要设计一个查看景点图片和简介的程序。结构图如下:
模式的扩展
迭代器模式常与组合模式结合起来使用
,在对组合模式中的容器构件进行访问时,经常将迭代器潜藏在组合模式的容器构造类中。当然,也可以构造一个外部迭代器来对容器构件进行访问。结构图如下:
访问者(Visitor)模式
定义:将作用于某种数据结构中的
各元素的操作分离出来封装成独立的类
,使其在不改变数据结构的前提下可以添加作用于这些元素的新的操作,为数据结构中的每个元素
提供多种访问方式
。
它将对数据的操作与数据结构进行分离,它是行为类模式中最复杂的一种模式。
优缺点
优点:
-
扩展性好
。能够在不修改对象结构中的元素是情况下,
为对象结构中的元素添加新的功能
; - ** 复用性好**。可以通过访问者来定义整个对象结构通用的功能,从而提高系统的复用程度;
-
灵活性好
。访问者模式将数据结构与作用于结构上的操作解耦,
使得操作集合可以相对自由地演化
而不影响系统的数据结构; -
符合单一职责原则
。访问者模式把相关的行为封装在一起,构成一个访问者,使每一个访问者的功能都比较单一。
缺点:
-
加新的元素很困难
。在访问者模式中,每增加一个新的元素类,都要在每一个具体访问者类中增加相应的具体操作,这
违背了“开闭原则”
; -
破坏封装
。访问者模式中具体元素对访问者公布细节,这破坏了对象的封装性; -
违反了依赖倒置原则
。访问者模式依赖了具体类,而没有依赖抽象类。
应用场景
-
对象结构相对稳定,但其操作算法经常变化的程序
。 -
对象结构中的对象需要提供多种不同且不相关的操作
,而且要
避免让这些操作的变化影响对象的结构
。 -
对象结构包含很多类型的对象,希望
对这些对象实施一些依赖于其具体类型的操作
。
主要角色
- 抽象访问者(Visitor)类:定义一个访问具体元素的接口,为每个具体元素对应一个访问操作visit(),该操作中的参数类型标识了被访问的具体元素。
- 具体访问者(ConcreteVisitor)角色:实现抽象访问者角色中声明的各个访问操作,确定访问者访问一个元素时该做什么。
- 抽象元素(Element)角色:声明一个包含接收操作accept()的接口,被接收的访问者对象作为accept()方法的参数。
- 具体元素(ConcreteElement)角色:实现抽象元素角色提供的accept()操作,其方法体通常都是visitor.visit(this),另外具体元素中可能包含本身业务逻辑的相关操作。
- 对象结构(ObjectStructure)角色:是一个包含元素角色的容器,提供让访问者对象遍历容器中的所有元素的方法,通常由List、Set、Map等聚合类实现。
结构图
应用实例
艺术公司利用“铜”设计铜像,利用“纸”画出图画;造币公司利用“铜”设计铜币,利用“纸”印出纸币;
对于“铜”和“纸”这两种元素,两个公司的处理方式不同。结构图如下:
注意:该文章内容采摘于《软件设计模式(Java版)》,作者:程细柱
版权声明:本文为weixin_44048668原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。