使用这两种技术有什么重大好处吗?如果有变化,我的意思是访客模式:http://en.wikipedia.org/wiki/Visitor_pattern
以下是使用委托实现相同效果的示例(至少我认为是相同的)
假设有一组嵌套元素:学校包含包含学生的部门
为什么不使用简单的回调(C#中的Action委托),而不是使用Visitor模式对每个集合项执行某些操作
说出这样的话
class Department
{
List Students;
}
class School
{
List Departments;
VisitStudents(Action<Student> actionDelegate)
{
foreach(var dep in this.Departments)
{
foreach(var stu in dep.Students)
{
actionDelegate(stu);
}
}
}
}
School A = new School();
...//populate collections
A.Visit((student)=> { ...Do Something with student... });
*代理接受多个参数的编辑示例
说我想通过学生和部门,我可以像这样修改动作定义: 操作
class School
{
List Departments;
VisitStudents(Action<Student, Department> actionDelegate, Action<Department> d2)
{
foreach(var dep in this.Departments)
{
d2(dep); //This performs a different process.
//Using Visitor pattern would avoid having to keep adding new delegates.
//This looks like the main benefit so far
foreach(var stu in dep.Students)
{
actionDelegate(stu, dep);
}
}
}
}
答案 0 :(得分:9)
访问者模式通常在有多种类型的访问内容时使用。您只有一种类型(Student
s),因此您并不真正需要访问者模式,只能传入委托实例。
假设您要访问Department
和Student
。然后你的访客看起来像这样:
interface ISchoolVisitor
{
void Visit(Department department);
void Visit(Student student);
}
当然,您也可以在这里使用委托,但传递多个委托实例会很麻烦 - 特别是如果您有两种以上的访问类型。
答案 1 :(得分:4)
当嵌套结构(如树)中的节点不知道其子节点的具体类型时,访问者模式更有用。然后,访问者将根据每个子对象的实际类型调度行为。
在您的示例中,学校确实知道它有一个孩子Departments
集合,而这个集合又有子Student
个集合。
如果您将示例扩展为包含School
的另一个子元素,那么您的代码可能如下所示:
public abstract class Manageable
{
abstract void Accept(IManagebleVisitor visitor);
}
public interface IManageableVisitor
{
void Visit(Department d);
void Visit(Building b);
}
public class Department : Manageable { ... }
public class Building : Manageable { ... }
现在您的School
课程可能如下:
public class School
{
private List<Manageable> manageables;
public void Accept(IManageableVisitor visitor)
{
foreach(var m in this.manageables)
{
m.Accept(visitor);
}
}
}
委托方法在这里不起作用,因为您需要为Manageable
的每个具体子类传递委托,因此将任何新的子类添加到层次结构将需要更改School.Accpet
方法