我在下面描述的案例中选择设计模式时遇到问题:
我有基本相同的请求,但每个人都在添加更多属性,例如:Animal
BaseClass
有一些属性(bool Color{get; set;}
....),猫和狗必须派生Animal,但添加更多属性,例如Dog => bool IsBarking {get; set; }
和Cat bool isMewIng {get; set;};
此请求将发送到服务器,它将根据请求类型以不同方式处理它们,但是会有一些请求的属性将被平等处理。例如public void Validation(request)
对于所有请求都是一样的......
感谢您的帮助!
答案 0 :(得分:1)
这将是访客模式的一个很好的候选人。
让我们采用以下基类:
public abstract class Animal {
public abstract int Legs { get; }
public virtual void Speak() { Console.WriteLine("..."); }
public abstract void Accept(IAnimalVisitor visitor);
}
注意接受方法。这是我们的Visitor对象发生魔力的地方。
我们将实施这些作为我们需要处理的衍生动物。
public class Cat : Animal {
public bool IsMewling { get; set; }
public override int Legs { get; } = 4;
public override void Accept(IAnimalVisitor visitor) { visitor.Visit(this); }
public override void Speak() { Console.WriteLine("Meow"); }
}
public class Dog : Animal {
public bool IsBarking { get; set; }
public override int Legs { get; } = 4;
public override void Accept(IAnimalVisitor visitor) { visitor.Visit(this); }
public override void Speak() { Console.WriteLine("Woof"); }
}
好的,非常好。我们可能需要检查几个不同属性名称的布尔值。让我们实现IAnimalVisitor接口。
public interface IAnimalVisitor {
void Visit(Dog dog);
void Visit(Cat cat);
}
最后,让我们创建一个实现,看看动物是否正在说话,并根据条件采取不同的行动。
public class LetsHearWhatItHasToSay : IAnimalVisitor {
public void Visit(Dog dog) {
if (dog.IsBarking) dog.Speak();
else Console.WriteLine("Good boy!");
}
public void Visit(Cat cat) {
if (cat.IsMewling) cat.Speak();
else Console.WriteLine("Pretty kitty");
}
}
好的,太好了。让我们把它们放在一个小样本中。
void Main()
{
var animals = new List<Animal>
{
new Cat { IsMewling = true },
new Dog { IsBarking = false },
new Cat { IsMewling = false },
new Dog { IsBarking = true }
};
var visitor = new LetsHearWhatItHasToSay();
foreach (var animal in animals)
{
animal.Accept(visitor);
}
}
我们得到了预期的产出
Meow
Good boy!
Pretty kitty
Woof
在这种情况下使用visitor的优点是我们可以创建任意数量的封装对象,这些对象可以以类型安全的方式处理类层次结构上的不同类型的逻辑操作,而无需对该类层次结构进行修改。缺点是当您添加要访问的其他Animal时,您必须更新在层次结构上工作的每个访问者。