建站优化公司,杭州微网站开发公司,怎样看网站是谁做的,网站建设ppt课件引言:数据结构与操作的分离困境
在软件开发中,我们经常面临数据结构稳定但操作频繁变化的场景: 编译器中的抽象语法树(AST)需要支持语法检查、代码生成、格式化等操作文件系统需要实现文件查找、大小计算、权限检查等功能电商系统中的商品目录需要支持价格计算、库存检查…引言:数据结构与操作的分离困境
在软件开发中,我们经常面临数据结构稳定但操作频繁变化的场景:
编译器中的抽象语法树(AST)需要支持语法检查、代码生成、格式化等操作文件系统需要实现文件查找、大小计算、权限检查等功能电商系统中的商品目录需要支持价格计算、库存检查、导出等功能传统的面向对象设计面临一个核心困境:在保持数据结构稳定的同时,如何支持不断新增的操作? 如果直接在数据结构中添加新方法,会导致类不断膨胀;如果使用类型判断,则违反开闭原则。
访问者模式正是为解决这一困境而生的设计模式。它允许你将算法与对象结构分离,在不修改已有类的前提下定义新操作。本文将深入剖析访问者模式的原理、实现及高级应用。 一、模式定义与核心思想
1.1 官方定义 访问者模式 (Visitor Pattern):表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。 1.2 设计哲学 #mermaid-svg-KgYLXPUADfWMJ05u {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-KgYLXPUADfWMJ05u .error-icon{fill:#552222;}#mermaid-svg-KgYLXPUADfWMJ05u .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-KgYLXPUADfWMJ05u .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-KgYLXPUADfWMJ05u .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-KgYLXPUADfWMJ05u .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-KgYLXPUADfWMJ05u .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-KgYLXPUADfWMJ05u .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-KgYLXPUADfWMJ05u .marker{fill:#333333;stroke:#333333;}#mermaid-svg-KgYLXPUADfWMJ05u .marker.cross{stroke:#333333;}#mermaid-svg-KgYLXPUADfWMJ05u svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-KgYLXPUADfWMJ05u .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-KgYLXPUADfWMJ05u .cluster-label text{fill:#333;}#mermaid-svg-KgYLXPUADfWMJ05u .cluster-label span{color:#333;}#mermaid-svg-KgYLXPUADfWMJ05u .label text,#mermaid-svg-KgYLXPUADfWMJ05u span{fill:#333;color:#333;}#mermaid-svg-KgYLXPUADfWMJ05u .node rect,#mermaid-svg-KgYLXPUADfWMJ05u .node circle,#mermaid-svg-KgYLXPUADfWMJ05u .node ellipse,#mermaid-svg-KgYLXPUADfWMJ05u .node polygon,#mermaid-svg-KgYLXPUADfWMJ05u .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-KgYLXPUADfWMJ05u .node .label{text-align:center;}#mermaid-svg-KgYLXPUADfWMJ05u .node.clickable{cursor:pointer;}#mermaid-svg-KgYLXPUADfWMJ05u .arrowheadPath{fill:#333333;}#mermaid-svg-KgYLXPUADfWMJ05u .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-KgYLXPUADfWMJ05u .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-KgYLXPUADfWMJ05u .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-KgYLXPUADfWMJ05u .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-KgYLXPUADfWMJ05u .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-KgYLXPUADfWMJ05u .cluster text{fill:#333;}#mermaid-svg-KgYLXPUADfWMJ05u .cluster span{color:#333;}#mermaid-svg-KgYLXPUADfWMJ05u div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-KgYLXPUADfWMJ05u :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 访问 接受 访问者Visitor 元素Element 对象结构 核心原则:
双重分派:通过两次方法调用实现动态绑定开闭原则:对扩展开放(新访问者),对修改关闭(元素类)关注点分离:数据结构与操作逻辑解耦二、模式结构解析
2.1 UML类图 #mermaid-svg-fqk49WRCx8O96RZB {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-fqk49WRCx8O96RZB .error-icon{fill:#552222;}#mermaid-svg-fqk49WRCx8O96RZB .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-fqk49WRCx8O96RZB .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-fqk49WRCx8O96RZB .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-fqk49WRCx8O96RZB .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-fqk49WRCx8O96RZB .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-fqk49WRCx8O96RZB .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-fqk49WRCx8O96RZB .marker{fill:#333333;stroke:#333333;}#mermaid-svg-fqk49WRCx8O96RZB .marker.cross{stroke:#333333;}#mermaid-svg-fqk49WRCx8O96RZB svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-fqk49WRCx8O96RZB g.classGroup text{fill:#9370DB;fill:#131300;stroke:none;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:10px;}#mermaid-svg-fqk49WRCx8O96RZB g.classGroup text .title{font-weight:bolder;}#mermaid-svg-fqk49WRCx8O96RZB .nodeLabel,#mermaid-svg-fqk49WRCx8O96RZB .edgeLabel{color:#131300;}#mermaid-svg-fqk49WRCx8O96RZB .edgeLabel .label rect{fill:#ECECFF;}#mermaid-svg-fqk49WRCx8O96RZB .label text{fill:#131300;}#mermaid-svg-fqk49WRCx8O96RZB .edgeLabel .label span{background:#ECECFF;}#mermaid-svg-fqk49WRCx8O96RZB .classTitle{font-weight:bolder;}#mermaid-svg-fqk49WRCx8O96RZB .node rect,#mermaid-svg-fqk49WRCx8O96RZB .node circle,#mermaid-svg-fqk49WRCx8O96RZB .node ellipse,#mermaid-svg-fqk49WRCx8O96RZB .node polygon,#mermaid-svg-fqk49WRCx8O96RZB .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-fqk49WRCx8O96RZB .divider{stroke:#9370DB;stroke:1;}#mermaid-svg-fqk49WRCx8O96RZB g.clickable{cursor:pointer;}#mermaid-svg-fqk49WRCx8O96RZB g.classGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-fqk49WRCx8O96RZB g.classGroup line{stroke:#9370DB;stroke-width:1;}#mermaid-svg-fqk49WRCx8O96RZB .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-fqk49WRCx8O96RZB .classLabel .label{fill:#9370DB;font-size:10px;}#mermaid-svg-fqk49WRCx8O96RZB .relation{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-fqk49WRCx8O96RZB .dashed-line{stroke-dasharray:3;}#mermaid-svg-fqk49WRCx8O96RZB #compositionStart,#mermaid-svg-fqk49WRCx8O96RZB .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-fqk49WRCx8O96RZB #compositionEnd,#mermaid-svg-fqk49WRCx8O96RZB .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-fqk49WRCx8O96RZB #dependencyStart,#mermaid-svg-fqk49WRCx8O96RZB .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-fqk49WRCx8O96RZB #dependencyStart,#mermaid-svg-fqk49WRCx8O96RZB .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-fqk49WRCx8O96RZB #extensionStart,#mermaid-svg-fqk49WRCx8O96RZB .extension{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-fqk49WRCx8O96RZB #extensionEnd,#mermaid-svg-fqk49WRCx8O96RZB .extension{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-fqk49WRCx8O96RZB #aggregationStart,#mermaid-svg-fqk49WRCx8O96RZB .aggregation{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-fqk49WRCx8O96RZB #aggregationEnd,#mermaid-svg-fqk49WRCx8O96RZB .aggregation{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-fqk49WRCx8O96RZB .edgeTerminals{font-size:11px;}#mermaid-svg-fqk49WRCx8O96RZB :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 依赖 依赖 «interface» Visitor +visitElementA(ElementA) +visitElementB(ElementB) ConcreteVisitor1 +visitElementA(ElementA) +visitElementB(ElementB) «interface» Element +accept(Visitor) ElementA +accept(Visitor) +operationA() ElementB +accept(Visitor)