这个也是在重构一个开源软件中想到的小技巧。我们先来看原型
Java代码
public class A:IVisitbale{
public void Accpet(Visitor visitor)
{
visitor.VisitItem(this)
}
public override String ToString()
{
return "A";
}
}
public class ACollection:List,IVisitable
{
public void Accpet(Visitor visitor)
{
visitor.VisitACollection(this);
}
}
public class BCollection:List
{
//donothing
}
public class Visistor
{
public void VisitACollection(ACollection a)
{
VisitColllection(a);
}
public void VisitItem(A item)
{
System.Console.Out.WriteLine(A.ToString();
}
private void VisitCollection(ICollection col)
{
foreach(IVisitale v in col)
{
v.Accpet(this);
}
}
}
public class A:IVisitbale{
public void Accpet(Visitor visitor)
{
visitor.VisitItem(this)
}
public override String ToString()
{
return "A";
}
}
public class ACollection:List,IVisitable
{
public void Accpet(Visitor visitor)
{
visitor.VisitACollection(this);
}
}
public class BCollection:List
{
//donothing
}
public class Visistor
{
public void VisitACollection(ACollection a)
{
VisitColllection(a);
}
public void VisitItem(A item)
{
System.Console.Out.WriteLine(A.ToString();
}
private void VisitCollection(ICollection col)
{
foreach(IVisitale v in col)
{
v.Accpet(this);
}
}
}
为了范型化A,B两个Class,我们做如此重构
Java代码
public class MyCollection:List,IVisitable
{
public void Accept(Vistor vistor) //IVisitable member
{
Vistor.VisitCollection(this);
}
}
public Class Vistor
{
VisitGenericCollection(MyCollection col)
{
VisitColllection(col);
}
VisitGenericCollection(MyCollection[B] col)
{
....
}
public void VisitItem(A item)
{
System.Console.Out.WriteLine(A.ToString();
}
private void VisitCollection(ICollection col)
{
foreach(IVisitale v in col)
{
v.Accpet(this);
}
}
}
public class MyCollection:List,IVisitable
{
public void Accept(Vistor vistor) //IVisitable member
{
Vistor.VisitCollection(this);
}
}
public Class Vistor
{
VisitGenericCollection(MyCollection col)
{
VisitColllection(col);
}
VisitGenericCollection(MyCollection[B] col)
{
....
}
public void VisitItem(A item)
{
System.Console.Out.WriteLine(A.ToString();
}
private void VisitCollection(ICollection col)
{
foreach(IVisitale v in col)
{
v.Accpet(this);
}
}
}
这个例子并没办法编译,因为
Java代码
public void Accept(Vistor vistor) //IVisitable member
{
Vistor.VisitCollection(this);
}
public void Accept(Vistor vistor) //IVisitable member
{
Vistor.VisitCollection(this);
}
是无法特例化造型成MyCollection和MyCollection[B]的,而且对于MyCollection[B]来说,也不应该有Accept方法. |