架构设计基础

访问者模式

2019-03-23  本文已影响0人  架构师的一小步

访问者模式-定义

访问者模式-场景

场景一:对象结构比较稳定,但经常需要在此对象结构上定义新的操作
场景二:需要对一个对象结构中的对象进行很多不同的并且不相关的操作。而需要避免这些操作"污染"对象的类,也不希望在增加新操作时修改这些类。

访问者模式-角色划分

\color{red}{五个核心角色}
角色一:抽象访问者->接口或者抽象类(visitor)
作用:定义了每一个元素访问行为
它的方法参数:就是可以访问的元素
角色二:具体访问者->ConcreteVisitor
作用:给出了每一个元素类访问时所产生的具体行为
角色三:元素接口->Element
角色四:具体元素->ConcreteElement
角色五: 定义了其中我们多提到所有的对象结构(ObjectStructure)

访问者模式-原理案例

公司里面管理:划分了等级(考核机制)
员工
项目经理:管理方式->项目完成数据
例如(查看):项目进度、项目个数(产品属相)、敲代码数量

老板:管理->KPI考核机制(业绩)

项目经理和老板访问员工数据,不同访问者需要数据不一样。

高层管理
角色一:抽象访问者->VisitorProtocol

//
//  VisitorProtocol.swift
//  Dream_20180723_Visitor
//
//  Created by Dream on 2018/7/23.
//  Copyright © 2018年 Tz. All rights reserved.
//

import Foundation


protocol VisitorProtocol {
    func visit(engineer:EngineerElement)
    func visit(manager:ManagerElement)
    //...
}

角色二:具体访问者->CTOVisitor(技术总监)、CEOVisitor

//
//  CTOVisitor.swift
//  Dream_20180723_Visitor
//
//  Created by Dream on 2018/7/23.
//  Copyright © 2018年 Tz. All rights reserved.
//

import UIKit

class CTOVisitor: VisitorProtocol {

    init(name:String) {
        print("\(name)CTO(技术总监)关心数据")
    }
    
    //项目经理数据
    func visit(manager: ManagerElement) {
        print("项目经理: \(manager.getName()), 产品数量: \(manager.getProductCount())")
    }
    
    //员工数据
    func visit(engineer: EngineerElement) {
        print("工程师: \(engineer.getName()), 代码数量: \(engineer.getCodeLines())")
    }
    
}

//
//  CEOVisitor.swift
//  Dream_20180723_Visitor
//
//  Created by Dream on 2018/7/23.
//  Copyright © 2018年 Tz. All rights reserved.
//

import UIKit

class CEOVisitor: VisitorProtocol {

    init(name:String) {
        print("\(name)CEO(技术总监)关心数据")
    }
    
    //项目经理数据
    func visit(manager: ManagerElement) {
        print("项目经理: \(manager.name), 业绩(KPI): \(manager.kpi)")
    }
    
    //员工数据
    func visit(engineer: EngineerElement) {
        print("工程师: \(engineer.name), 业绩(KPI): \(engineer.kpi)")
    }
    
}

角色三:元素接口(协议)->ElementProtocol

//
//  ElementProtocol.swift
//  Dream_20180723_Visitor
//
//  Created by Dream on 2018/7/23.
//  Copyright © 2018年 Tz. All rights reserved.
//

import UIKit

protocol ElementProtocol {
    func accpt(visitor:VisitorProtocol)
}

角色四:具体元素->EngineerElement、ManagerElement

//
//  EngineerElement.swift
//  Dream_20180723_Visitor
//
//  Created by Dream on 2018/7/23.
//  Copyright © 2018年 Tz. All rights reserved.
//

import UIKit

class EngineerElement: BaseElement {

    private var codeLines:Int
    
    override init(name: String) {
        self.codeLines = Int(arc4random() % 10000000)
        super.init(name: name)
        kpi = 100000
    }
    
    override func accpt(visitor: VisitorProtocol) {
        visitor.visit(engineer: self)
    }
    
    func getCodeLines() -> Int {
        return self.codeLines
    }
    
    override func getName() -> String {
        return super.getName()
    }
    
}

//
//  ManagerElement.swift
//  Dream_20180723_Visitor
//
//  Created by Dream on 2018/7/23.
//  Copyright © 2018年 Tz. All rights reserved.
//

import UIKit

class ManagerElement: BaseElement {

    private var productCount:Int
    
    override init(name: String) {
        self.productCount = Int(arc4random() % 50)
        super.init(name: name)
        kpi = 1000000
    }
    
    override func accpt(visitor: VisitorProtocol) {
        visitor.visit(manager: self)
    }
    
    func getProductCount() -> Int {
        return self.productCount
    }
    
    override func getName() -> String {
        return super.getName()
    }
   
}


//
//  BaseElement.swift
//  Dream_20180723_Visitor
//
//  Created by Dream on 2018/7/23.
//  Copyright © 2018年 Tz. All rights reserved.
//

import UIKit

class BaseElement: ElementProtocol {
    
    var name:String
    var kpi:Float
    
    init(name:String) {
        self.name = name
        self.kpi = Float(arc4random() % 1000000)
    }
    
    func accpt(visitor: VisitorProtocol) {
        
    }
    
    func getName() -> String {
        return self.name
    }
    
}


角色五:对象结构->查询系统->业务逻辑->BusinessReport

//
//  BusinessReport.swift
//  Dream_20180723_Visitor
//
//  Created by Dream on 2018/7/23.
//  Copyright © 2018年 Tz. All rights reserved.
//

import UIKit

class BusinessReport {

    private var arr = Array<ElementProtocol>()
    
    init() {
        self.arr.append(ManagerElement(name: "地平线"))
        self.arr.append(ManagerElement(name: "NSLog"))
        self.arr.append(EngineerElement(name: "校长"))
        self.arr.append(EngineerElement(name: "zsk"))
        self.arr.append(EngineerElement(name: "mumu"))
        self.arr.append(EngineerElement(name: "世界旁观者"))
        self.arr.append(EngineerElement(name: "只身穿越暴风雪"))
        self.arr.append(EngineerElement(name: "iOS学习之路"))
        self.arr.append(EngineerElement(name: "NSError"))
        self.arr.append(EngineerElement(name: "love"))
    }
    
    func showReport(visitor:VisitorProtocol) {
        for item in arr {
            item.accpt(visitor: visitor)
        }
    }
    
}


调用

  //老板、技术总监
        let business = BusinessReport()
        let cto = CTOVisitor(name: "独秀")
        let ceo = CEOVisitor(name: "图图")
        business.showReport(visitor: ceo)//访问的对象不同,所产生的数据也不同

打印

图图CEO(技术总监)关心数据
项目经理: 地平线, 业绩(KPI): 1000000.0
项目经理: NSLog, 业绩(KPI): 1000000.0
工程师: 校长, 业绩(KPI): 100000.0
工程师: zsk, 业绩(KPI): 100000.0
工程师: mumu, 业绩(KPI): 100000.0
工程师: 世界旁观者, 业绩(KPI): 100000.0
工程师: 只身穿越暴风雪, 业绩(KPI): 100000.0
工程师: iOS学习之路, 业绩(KPI): 100000.0
工程师: NSError, 业绩(KPI): 100000.0
工程师: love, 业绩(KPI): 100000.0

访问者模式-UML

上一篇下一篇

猜你喜欢

热点阅读