『设计模式』我能进来坐坐吗?-访问者模式 23 种设计模式+额外常用设计模式汇总 (持续更新)
访问者模式 访问者( Visitor )模式的定义: 将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的新的操作, 为数据结构中的每个元素提供多种访问方式。它将对数据的操作与数据结构进行分离,是行为类模式中最复杂的一种模式。
优点: ① 扩展性好。能够在不修改对象结构中的元素的情况下,为对象结构中的元素添加新的功能。 ② 复用性好。可以通过访问者来定义整个对象结构通用的功能,从而提高系统的复用程度。 ③ 灵活性好。访问者模式将数据结构与作用于结构上的操作解嘱, 使得操作集合可相对自由地 演化而不影响系统的数据结构。 ④ 符合单一职责原则。访问者模式把相关的行为封装在一起,构成一个访问者,使每一个访问 者的功能都比较单一。
缺点: ① 增加新的元素类很困难。在访问者模式中,每增加一个新的元素类,都要在每一个具体访问者类中增加相应的具体操作, 这违背了“开闭原则” 。 ② 破坏封装。访问者模式中具体元素对访问者公布细节, 这破坏了对象的封装性。 ③ 违反了依赖倒置原则。访问者模式依赖了具体类,而没有依赖抽象类。
使用场景: 1、对象结构中对象对应的类很少改变,但经常需要在此对象结构上定义新的操作。 2、需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作”污染”这些对象的类,也不希望在增加新操作时修改这些类。
应用场景 对象结构相对稳定,但其操作算法经常变化的程序。 对象结构中的对象需要提供多种不同且不相关的操作,而且要避免让这些操作的变化影响对象的结构。 对象结构包含很多类型的对象,希望对这些对象实施一些依赖于其具体类型的操作。
实现 模式的结构 访问者模式包含以下主要角色。 ( 1 )抽象访问者( Visitor )角色: 定义一个访问具体元素的接口,为每个具体元素类对应一个访问操作visitXXX()
,该操作中的参数类型标识了被访问的具体元素。 ( 2 ) 具体访问者( Concrete Visitor )角色: 实现抽象访问者角色中声明的各个访问操作,确定访问者访问一个元素时该做什么。 ( 3 )抽象元素( Element )角色: 声明一个包含接受操作accept()
的接口,被接受的访问者对象作为accept()方
法的参数。 ( 4 )具体元素( Concrete Element )角色:实现抽象元素角色提供的accept()
操作,其方法体通常都是 visitor.visit(this) ,另外具体元素中可能还包含本身业务逻辑的相关操作。 ( 5 )对象结构(Object Structure ) 角色:是一个包含元素角色的容器,提供让访问者对象遍历容器中的所有元素的方法,通常由 List、Set、Map 等聚合类实现。 UML:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 package Visitor;import java.util.ArrayList;import java.util.Iterator;import java.util.List;interface Visitor { void visit (ConcreteElementA element) ; void visit (ConcreteElementB element) ; }class ConcreteVisitorA implements Visitor { public void visit (ConcreteElementA element) { System.out.println("具体访问者A访问-->" + element.operationA()); } public void visit (ConcreteElementB element) { System.out.println("具体访问者A访问-->" + element.operationB()); } }class ConcreteVisitorB implements Visitor { public void visit (ConcreteElementA element) { System.out.println("具体访问者B访问-->" + element.operationA()); } public void visit (ConcreteElementB element) { System.out.println("具体访问者B访问-->" + element.operationB()); } }interface Element { void accept (Visitor visitor) ; }class ConcreteElementA implements Element { public void accept (Visitor visitor) { visitor.visit(this ); } public String operationA () { return "具体元素A的操作。" ; } }class ConcreteElementB implements Element { public void accept (Visitor visitor) { visitor.visit(this ); } public String operationB () { return "具体元素B的操作。" ; } }class ObjectStructure { private List<Element> list = new ArrayList <Element>(); public void accept (Visitor visitor) { Iterator<Element> i = list.iterator(); while (i.hasNext()) { ((Element) i.next()).accept(visitor); } } public void add (Element element) { list.add(element); } public void remove (Element element) { list.remove(element); } }public class VisitorTest { public static void main (String[] args) { ObjectStructure os = new ObjectStructure (); os.add(new ConcreteElementA ()); os.add(new ConcreteElementB ()); Visitor visitor = new ConcreteVisitorA (); os.accept(visitor); System.out.println("------------------------" ); visitor = new ConcreteVisitorB (); os.accept(visitor); } }
我们再举一个客户管理系统的例子 用户位个人用户,企业用户 提出服务申请、客户价值分析、客户对产品偏好
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 package CRM;public interface Customer { public void accpet (Visitor vis) ; }package CRM;public class Enterprise implements Customer { @Override public void accpet (Visitor vis) { vis.visit(this ); } public String oper () { return "企业用户" ; } }package CRM;public class Personal implements Customer { @Override public void accpet (Visitor vis) { vis.visit(this ); } public String oper () { return "个人用户" ; } }package CRM;public interface Visitor { public void visit (Enterprise ent) ; public void visit (Personal per) ; }package CRM;public class Service_ApplyFor implements Visitor { @Override public void visit (Enterprise ent) { System.out.println(ent.oper()+"提出企业用户的服务申请" ); } @Override public void visit (Personal per) { System.out.println(per.oper()+"提出个人用户的服务申请" ); } }package CRM;public class Customer_AnalyzePrefer implements Visitor { @Override public void visit (Enterprise ent) { System.out.println("对" +ent.oper()+"提供企业用户的客户产品偏好分析" ); } @Override public void visit (Personal per) { System.out.println("对" +per.oper()+"提供个人用户的客户产品偏好分析" ); } }package CRM;public class Customer_AnalyzeValue implements Visitor { @Override public void visit (Enterprise ent) { System.out.println("对" +ent.oper()+"提供企业用户的客户价值分析" ); } @Override public void visit (Personal per) { System.out.println("对" +per.oper()+"提供个人用户的客户价值分析" ); } }package CRM;import java.util.ArrayList;import java.util.List;public class Manage_System { private List<Customer> OperList = new ArrayList <>(); public void accept (Visitor vis) { for (Customer cus : OperList) { cus.accpet(vis); } } public void add (Customer cus) { OperList.add(cus); } public void remove (Customer cus) { OperList.remove(cus); } }package CRM;public class Client { public static void main (String[] args) { Manage_System MS = new Manage_System (); MS.add(new Personal ()); MS.add(new Enterprise ()); Visitor vis=new Customer_AnalyzePrefer (); MS.accept(vis); vis=new Customer_AnalyzeValue (); MS.accept(vis); vis=new Service_ApplyFor (); MS.accept(vis); } }