Visitor 访问者(行为型模式)--学习笔记
问题的提出:在软件构建过程中,由于需求的改变,某些类层次结构中常常需要增加新的行为(方法),如果直接在基类中做这样的更改,将会给子类带来很繁重的变更负担,甚至破坏原有设计。例如下面的代码:
public abstract class Shape
{
public abstract void Draw();
//问题:由于Shape中增加了MoveTo方法,其各个子类将不得不随之更改
public abstract void MoveTo(Point p); //新增加的方法,子类需要override该方法,
}

public class Rectangle:Shape
{
public override void Draw()
{
}
}

public class Circle:Shape
{
public override void Draw()
{
}
}
public class Line:Shape
{
public override void Draw()
{
}
}
解决思路:在不更改类层次结构的前提下,在运行时根据需要透明地为类层次结构上的各个类动态添加新的操作,从而避免上述问题。
代码:
public abstract class Shape
{
public abstract void Draw();
//预料到将来可能会引入新的操作
public abstract void accept(ShapeVisitor v, Context context);
}

public abstract class ShapeVisitor
{
public abstract void Visit(Rectangle shape, Context context); //#1
public abstract void Visit(Circle shape, Context context); //#2
public abstract void Visit(Line shape, Context context); //#3
}

public class Rectangle:Shape
{
public override void Draw()
{
}
public override void Accept(ShapeVisitor v)
{
v.Visit(this,context);//调用#1
}
}

public class Circle:Shape
{
public override void Draw()
{
}
public override void Accept(ShapeVisitor v)
{
v.Visit(this, context);//调用#2
}
}
public class Line:Shape
{
public override void Draw()
{
}
public override void Accept(ShapeVisitor v)
{
v.Visit(this, context);//调用#3
}
}

//

class App
{
ShapeVisitor visitor ;
public App (ShapeVisitor visitor)
{
this.visitor = visitor ;
}
public void Process (Shape shape)
{
shape.Accept(visitor);
}
}

//*******
App app = new App(new MyVisitor());
app.Process(new line());
public abstract class Shape
{
public abstract void Draw();
//问题:由于Shape中增加了MoveTo方法,其各个子类将不得不随之更改
public abstract void MoveTo(Point p); //新增加的方法,子类需要override该方法,
}
public class Rectangle:Shape
{
public override void Draw()
{
}
}
public class Circle:Shape
{
public override void Draw()
{
}
}
public class Line:Shape
{
public override void Draw()
{
}
}代码:
public abstract class Shape
{
public abstract void Draw();
//预料到将来可能会引入新的操作
public abstract void accept(ShapeVisitor v, Context context);
}
public abstract class ShapeVisitor
{
public abstract void Visit(Rectangle shape, Context context); //#1
public abstract void Visit(Circle shape, Context context); //#2
public abstract void Visit(Line shape, Context context); //#3
}
public class Rectangle:Shape
{
public override void Draw()
{
}
public override void Accept(ShapeVisitor v)
{
v.Visit(this,context);//调用#1
}
}
public class Circle:Shape
{
public override void Draw()
{
}
public override void Accept(ShapeVisitor v)
{
v.Visit(this, context);//调用#2
}
}
public class Line:Shape
{
public override void Draw()
{
}
public override void Accept(ShapeVisitor v)
{
v.Visit(this, context);//调用#3
}
}
//
class App
{
ShapeVisitor visitor ;
public App (ShapeVisitor visitor)
{
this.visitor = visitor ;
}
public void Process (Shape shape)
{
shape.Accept(visitor);
}
}
//*******
App app = new App(new MyVisitor());
app.Process(new line());



浙公网安备 33010602011771号