ljs*_*ljs 8 c# design-patterns visitor
我想知道以下是否是访客模式的可接受用途.从Accept()或Visit()调用返回时我感到有点不舒服 - 这是否适合使用此模式,如果没有,为什么不呢?
注意:长代码示例的道歉,似乎有必要了解我正在做的事情,因为访问者似乎总是有点参与......
interface IAnimalElement<T>
{
T Accept(IAnimalVisitor<T> visitor);
}
interface IAnimalVisitor<T>
{
T Visit(Lion lion);
T Visit(Peacock peacock);
T VisitZoo(List<Animal> animals);
}
abstract class Animal
{
public int Age { get; protected set; }
}
class Lion : Animal, IAnimalElement<int>
{
public Lion(int age)
{
Age = age;
}
public int Accept(IAnimalVisitor<int> visitor)
{
return visitor.Visit(this);
}
}
class Peacock : Animal, IAnimalElement<int>
{
public Peacock(int age)
{
Age = age;
}
public int Accept(IAnimalVisitor<int> visitor)
{
return visitor.Visit(this);
}
}
class AnimalAgeVisitor : IAnimalVisitor<int>
{
public int TotalAge { get; private set; }
int IAnimalVisitor<int>.Visit(Lion lion)
{
TotalAge += lion.Age;
return lion.Age;
}
int IAnimalVisitor<int>.Visit(Peacock peacock)
{
TotalAge += peacock.Age + 10;
return peacock.Age + 10; // peacocks ages are always -10y, correct.
}
public int VisitZoo(List<Animal> animals)
{
// Calculate average animal age.
int sum = 0;
int count = 0;
foreach (IAnimalElement<int> animal in animals)
{
sum += animal.Accept(this);
++count;
}
return count == 0 ? 0 : sum / count;
}
}
class Program
{
static void Main(string[] args)
{
List<Animal> animals = new List<Animal>() { new Lion(10),
new Lion(15), new Peacock(3), new Lion(2), new Peacock(9) };
AnimalAgeVisitor visitor = new AnimalAgeVisitor();
Console.WriteLine("Average age = {0}, Total age = {1}",
visitor.VisitZoo(animals), visitor.TotalAge);
}
}
Run Code Online (Sandbox Code Playgroud)
对我来说,这感觉实施有点犹豫。
让您的 Visit 和 Accept 方法返回 void 并跟踪 Visitor 对象中的所有状态。最后询问一下。
或者 ...
让 Visit 和 Accept 返回正在进行的状态,并以功能方式接受传入的正在进行的状态。
如果您选择第二个选项,我不太确定是否需要访问者对象或模式,您可以使用迭代器、函数和一些瞬态状态。