我真的在这里看不到模板方法。我看到了访客模式。
这是一个例子。
想象一下,你有一堆房子,你需要把它们都漆成黄色。现在你可以:
var houses = ... a list of houses ...
foreach (var house in houses)
{
house.Color = Color.Yellow;
}
但是,您可能希望将动作(在本例中为绘画)抽象为其他东西,而不是总是将房屋涂成黄色。一种解决方案是编写一个负责将房子涂成黄色的类。该课程稍后可以替换为另一个课程,该课程以不同的颜色粉刷房屋,或者对您的房屋做一些完全不同的事情,例如添加另一层!
输入访客模式。
我将展示一些我一直在使用的通用帮助类和接口。我喜欢泛型。如果你不这样做,请随意滚动你自己的。语义是:“访问者访问可访问者”和“可访问者接受访问者”。
public interface IVisitor<in T> where T : IVisitable<T>
{
void Visit(T visitable);
}
public interface IVisitable<out T> where T : IVisitable<T>
{
void Accept(IVisitor<T> visitor);
}
public abstract class Visitable<T> : IVisitable<T> where T : Visitable<T>
{
public void Accept(IVisitor<T> visitor)
{
visitor.Visit((T)this);
}
}
public abstract class VisitableList<T> : List<T>, IVisitable<T> where T : Visitable<T>
{
public void Accept(IVisitor<T> visitor)
{
foreach (var item in this)
{
item.Accept(visitor);
}
}
}
现在我们可以像这样设置我们的房子和我们的房子列表:
public class House : Visitable<House>
{
public Color Color { get; set; }
}
public class Houses : VisitableList<House> {}
现在,访客——我们的画家——可以参观我们可参观的房子:
public class YellowPainter : IVisitor<House>
{
public void Visit(House visitable)
{
visitable.Color = Color.Yellow;
}
}
简单,优雅和单一的责任(!)。
让我们设置房屋:
var houses = new Houses();
houses.Add(new House() { Color = Color.Green });
houses.Add(new House() { Color = Color.Blue });
houses.Add(new House() { Color = Color.White });
现在我们已经准备好粉刷我们所有的房子了。它只需要一个电话:
houses.Accept(new YellowPainter());
...我们所有的房子现在都是黄色的。好的!
我们可以很容易地做到这一点:
houses.Accept(new AdditionalFloorsBuilder(floors: 2));
或这个:
owlClasses.Accept(new OwlClassVisitor(owlBuilder, ...));
通过这样做,我们将 中每个元素的实际“访问”owlClasses
与集合本身的迭代隔离开来。访问不需要修改可访问。它可以用来只检查可访问的并使用信息来修改完全不同的东西,例如。您可以使用这些信息来满足您的owlBuilder
.