设计模式24——行为型模式之訪问者模式
定义:訪问者模式(Vistor Pattern),表示一个作用于对象结构中各元素的操作。它使你能够在不改变各元素的类的前提下定义作用于这些元素的新操作。
类型:对象行为型模式。
概述:
訪问者模式适用的场合比較狭窄。由于它的要求很严。
ConcreteElement要求具有一样的算法接口,而且ConcreteVisitor也要求一样的接口。这两点就使得訪问者模式的使用范围比較窄。在《Head First Design Patterns》中也将訪问者模式列为很常使用模式之中的一个。
举一个样例,有一个仓库(对象结构)。里面储存不同的电器(元素)。如电视、电脑(详细元素),仓库能够按电器新旧或大小(详细的訪问者)来摆放电器产品。
类图:
參与者:
- Client:构建抽象的訪问者以及结构体对象。
- Storage。详细生成并存储不同的商品(如Television、Computer)。
- Goods。抽象商品类。
- Television、Computer,详细的商品类,对对应的属性完毕赋值。
- Place,抽象的訪问者类。提供抽象訪问方法。
- State、Size。详细的訪问者类,依据对应商品属性来实现详细的摆放方法Put()。
演示样例代码:
using System; using System.Collections.Generic; using System.Text; namespace Pattern24 { abstract class Visitor { public abstract void PutTelevision(Television tv); public abstract void PutComputer(Computer comp); } class SizeVisitor : Visitor { public override void PutTelevision(Television tv) { Console.WriteLine("按商品大小{0}排放", tv.Size); } public override void PutComputer(Computer comp) { Console.WriteLine("按商品大小{0}排放", comp.Size); } } class StateVisitor : Visitor { public override void PutTelevision(Television tv) { Console.WriteLine("按商品新旧值{0}排放", tv.State); } public override void PutComputer(Computer comp) { Console.WriteLine("按商品新旧值{0}排放", comp.State); } } abstract class Goods { public abstract void Operate(Visitor visitor); private int nSize; public int Size { get {return nSize;} set {nSize = value;} } private int nState; public int State { get {return nState;} set {nState = value;} } } class Television : Goods { public override void Operate(Visitor visitor) { visitor.PutTelevision(this); } } class Computer : Goods { public override void Operate(Visitor visitor) { visitor.PutComputer(this); } } class Storage { private IList<Goods> list = new List<Goods>(); public void Attach(Goods element) { list.Add(element); } public void Detach(Goods element) { list.Remove(element); } public void Operate(Visitor visitor) { foreach (Goods e in list) { e.Operate(visitor); } } } class Program { static void Main(string[] args) { Storage storage = new Storage(); storage.Attach(new Television()); storage.Attach(new Computer()); SizeVisitor v1 = new SizeVisitor(); StateVisitor v2 = new StateVisitor(); storage.Operate(v1); storage.Operate(v2); Console.Read(); } } }
适用性:
- 一个对象结构包括非常多类对象。它们有不同的接口。而你想对这些对象实施一些依赖于其详细类的操作。
- 须要对一个对象结构中的对象进行非常多不同的而且不相关的操作,而你想避免让这些操作“污染”这些对象的类。
Visitor使得你能够将相关的操作集中起来定义在一个类中。
当该对象结构被非常多应用共享时,用Visitor模式让每一个应用仅包括须要用到的操作。
- 定义对象结构的类非常少改变,但常常须要在此结构上定义新的操作。
改变对象结构类须要重定义对全部訪问者的接口,这可能须要非常大的代价。
假设对象结构类常常改变,那么可能还是在这些类中定义这些操作较好
优缺点:
- 长处,完毕新的模板方法是不用改动原有代码,通过加入新代码完毕。
- 缺点,当使用訪问者模式时,打破了组合模式。
參考资料:
- 《设计模式——可复用面向对象软件基础》
- 《大话设计模式》