use*_*358 8 c# design-patterns
访问者设计模式是一种将算法与其操作的对象结构分离的方法.这是它的官方定义.我试图弄清楚这是如何不破坏封装的.如果说例如我对不同类型的银行账户[保存/固定/当前]有不同类型的类实现抽象类帐户,我应该将计算利息方法作为抽象方法放在抽象帐户类中,还是我发送帐户?键入访问者实现并在那里计算?
方法1:访客实施是否应负责计算不同帐户类型的利息?
public interface IInterestVisitor
{
void GetInterest(Savings AccountType);
void GetInterest(Fixed AccountType);
void GetInterest(Current AccountType);
}
Run Code Online (Sandbox Code Playgroud)
方法2:或者Account类的实现者应该这样做吗?
public abstract class Account
{
public abstract void AcceptCalculateInterestVisitor(IInterestVisitor iv);
public abstract int CalculateInterestAmount();
}
Run Code Online (Sandbox Code Playgroud)
如果我使用方法1,即上面实现IInterestVisitor的访问者实现,那么计算兴趣的工作将被委托给访问者类.使用这种方法,如果我添加其他帐户类型,那么每次新帐户出现时我都需要修改访问者实施.
但是,如果我将兴趣计算位留给方法2中的抽象Account类实现,那么在我看来[ 纠正我,如果我在这里错了 ]我没有打破封装.此外,修改的代码较少,因为我所做的只是添加一个新类,并让访问者实现如下所示的接口
public interface IInterestVisitor
{
void GetInterest(Account AccountType);
}
public class InterestVisitor : IInterestVisitor
{
public void GetInterest(Account AccountType)
{
int i = AccountType.CalculateInterestAmount();
Console.WriteLine(i);
}
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,使用方法2的兴趣访问者类不需要修改.方法1是否打破了封装?方法2仍然可以称为访客模式吗?
谢谢阅读...
我根本没有看到访问者的需要 - 你的方法完美地说明你可以使用CalculateInterestAmount子类可以实现的方法使用多态来解决这个问题.
在我看来,你真的需要一个非常引人注目的案例来考虑使用访问者模式 - 大多数时候其他解决方案更直接,更自然地适应.
话虽如此,你的版本2实际上只是使用多态 - 以这种方式使用Visitor没有任何好处.版本1更好地说明了访问者的"双重调度"方法,这就是访问者通常的工作方式.
访问者允许您定义新操作,而无需更改其操作的元素的类.
在提供的代码中,我没有看到您需要更改对象以满足您的需求,Visitor基本上是通过使用提供的Properties/ Methods/ Fields对象本身来更改对象状态.
因此,通过我,您的代码可以适合访问者模式,如果这实际上是问题,也会导致模式是指导而不是严格的规则.
我个人会选择第二种方式,因为它更清晰,面向OOP.
问候.