23设计模式之访问者模式(Visitor)



一、概述

        Visitor属于行为型模式中的一种,表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

二、适用性

        1. 一个对象结构包含很多类对象,它们有不同的接口,而你想对这些对象实施一些依赖于其具体类的操作。
        2. 需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而你想避免让这些操作“污染”这些对象的类。Visitor使得你可以将相关的操作集中起来定义在一个类中。当该对象结构被很多应用共享时,用Visitor模式让每个应用仅包含需要用到的操作。
        3. 定义对象结构的类很少改变,但经常需要在此结构上定义新的操作。改变对象结构类需要重定义对所有访问者的接口,这可能需要很大的代价。如果对象结构类经常改变,那么可能还是在这些类中定义这些操作较好。


三、参与者

        1. Visitor:为该对象结构中ConcreteElement的每一个类声明一个Visit操作。该操作的名字和特征标识了发送Visit请求给该访问者的那个类。这使得访问者可以确定正被访问元素的具体的类。这样访问者就可以通过该元素的特定接口直接访问它。
        2. ConcreteVisitor:实现每个由Visitor声明的操作。每个操作实现本算法的一部分,而该算法片断乃是对应于结构中对象的类。ConcreteVisitor为该算法提供了上下文并存储它的局部状态。这一状态常常在遍历该结构的过程中累积结果。
        3. Element:定义一个Accept操作,它以一个访问者为参数。
        4. ConcreteElement:实现Accept操作,该操作以一个访问者为参数。
        5. ObjectStructure:能枚举它的元素。:可以提供一个高层的接口以允许该访问者访问它的元素。可以是一个复合或是一个集合,如一个列表或一个无序集合。

四、类图 



五、代码实现 

1. Visitor:为该对象结构中ConcreteElement的每一个类声明一个Visit操作。该操作的名字和特征标识了发送Visit请求给该访问者的那个类。这使得访问者可以确定正被访问元素的具体的类。这样访问者就可以通过该元素的特定接口直接访问它。

Visitor.swift

//
//  Visitor.swift
//  23设计模式
//
//  Created by 阳君 on 14/12/5.
//  Copyright (c) 2014年 六月. All rights reserved.
//

import Foundation

/// Visitor为该对象结构中ConcreteElement的每一个类声明一个Visit操作
protocol Visitor {
    
    func visitString(stringE:StringElement)
    
    func visitFloat(floatE:FloatElement)
    
    func visitCollection(collection:Array<Visitable>)
    
}

 

2. ConcreteVisitor:实现每个由Visitor声明的操作。每个操作实现本算法的一部分,而该算法片断乃是对应于结构中对象的类。ConcreteVisitor为该算法提供了上下文并存储它的局部状态。这一状态常常在遍历该结构的过程中累积结果。

ConcreteVisitor.swift

//
//  ConcreteVisitor.swift
//  23设计模式
//
//  Created by 阳君 on 14/12/5.
//  Copyright (c) 2014年 六月. All rights reserved.
//

import Foundation

/// ConcreteVisitor实现每个由Visitor声明的操作
class ConcreteVisitor: Visitor {
    
    func visitFloat(floatE: FloatElement) {
        print(floatE.fe)
    }
    
    func visitString(stringE: StringElement) {
        print(stringE.se)
    }
    
    func visitCollection(collection: Array<Visitable>) {
        for visitable in collection {
            visitable.accept(self)
        }
    }
    
}


3. Element:定义一个Accept操作,它以一个访问者为参数。

Visitable.swift

//
//  Visitable.swift
//  23设计模式
//
//  Created by 阳君 on 14/12/5.
//  Copyright (c) 2014年 六月. All rights reserved.
//

import Foundation

/// Visitable定义一个Accept操作,它以一个访问者为参数。
protocol Visitable {
    
    func accept(visitor:Visitor)
    
}


4. ConcreteElement:实现Accept操作,该操作以一个访问者为参数。

a) FloatElement.swift

//
//  FloatElement.swift
//  23设计模式
//
//  Created by 阳君 on 14/12/5.
//  Copyright (c) 2014年 六月. All rights reserved.
//

import Foundation

/// FloatElement实现Visitor操作,该操作以一个访问者为参数
class FloatElement: Visitable {
    
    var fe:Float
    
    init(fe:Float) {
        self.fe = fe
    }
    
    func accept(visitor: Visitor) {
        visitor.visitFloat(self)
    }
    
}

 

b) StringElement.swift

//
//  StringElement.swift
//  23设计模式
//
//  Created by 阳君 on 14/12/5.
//  Copyright (c) 2014年 六月. All rights reserved.
//

import Foundation

/// StringElement实现Visitor操作,该操作以一个访问者为参数
class StringElement: Visitable {
    
    var se:String
    
    init(se:String) {
        self.se = se
    }
    
    func accept(visitor: Visitor) {
        visitor.visitString(self)
    }
    
}

六、测试

1. 代码

// 访问者模式
let visitor = ConcreteVisitor()
let se = StringElement(se: "abc")
se.accept(visitor)
let fe = FloatElement(fe: 1.5)
fe.accept(visitor)
print("===========")
let list:[Visitable] = [se, fe]
visitor.visitCollection(list)

2. 运行结果

abc

1.5

===========

abc

1.5


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值