C# 访问者模式是将域枚举重构为类的最佳方法吗?
如果我们想要将域层中包含的枚举重构为多态类,那么使用简单的抽象方法可能是个坏主意,如果我们想要重构的所有开关和If语句都在其他层(如业务层或表示层)内,因为我们最终可能会在域层内引用这些层:C# 访问者模式是将域枚举重构为类的最佳方法吗?,c#,design-patterns,enums,polymorphism,visitor-pattern,C#,Design Patterns,Enums,Polymorphism,Visitor Pattern,如果我们想要将域层中包含的枚举重构为多态类,那么使用简单的抽象方法可能是个坏主意,如果我们想要重构的所有开关和If语句都在其他层(如业务层或表示层)内,因为我们最终可能会在域层内引用这些层: public abstract class MyRefactoredEnum { public abstract void DoSomething(IBusinnessObject aBizObject); //dependency to the biz. layer public abs
public abstract class MyRefactoredEnum
{
public abstract void DoSomething(IBusinnessObject aBizObject); //dependency to the biz. layer
public abstract MvcHtmlString GetImgTag(); //dependency to presentation layer
}
在上面的例子中,我们也可以有一个交叉引用问题
我发现访问者模式是这个问题的有效解决方案:在域层中,我们只定义MyRefactureDenum.IVisitor接口,所有其他层都可以实现自己的访问者
唯一的问题是:例如,当我们修改MyRefactureNum.IVisitor接口时,因为我们添加了另一个MyRefactureNum的子类,我们必须修改并重新编译引用域模型的所有项目和解决方案。我们可以使用反射来解决这个问题,但它可能很慢
有没有更好的模式来重构枚举
PS:对不起,我的英语很糟糕:您可以为访问者提供一个默认的实现,该实现有一个回退方法:
abstract class Cheese
{
public abstract void Visit(ICheeseVisitor visitor);
}
class Wensleydale : Cheese { ... }
class Gouda : Cheese { ... }
interface ICheeseVisitor
{
void Visit(Wensleydale cheese);
void Visit(Gouda cheese);
}
abstract class CheeseVisitor : ICheeseVisitor
{
public virtual void Visit(Wensleydale cheese) { Default(cheese); }
public virtual void Visit(Gouda cheese) { Default(cheese); }
public virtual void Default(Cheese cheese) { }
}
添加新类型时,根据旧版本生成的库将使用回退方法,而新库可以覆盖新重载:
class Brie
{
public override void Visit(ICheeseVisitor visitor)
{
visitor.Visit(this);
}
}
interface ICheeseVisitor
{
...
void Visit(Brie cheese);
}
abstract class CheeseVisitor : ICheeseVisitor
{
...
public virtual void Visit(Brie cheese) { Default(cheese); }
...
}
例如:
class CheeseImgVisitor : CheeseVisitor
{
private string src;
public string Src
{
get { return this.src; }
}
public override void Visit(Wensleydale cheese)
{
this.src = "wensleydale.png";
}
public override void Visit(Gouda cheese)
{
this.src = "gouda.png";
}
public override void Default(Cheese cheese)
{
this.src = "generic_cheese.png";
}
}
Enum是一个c关键字,只是一个只允许n个值的类型,比如Enum myEnum{value1,value2,…};我真的看不出你把它重构成访问者模式的真正含义。你是说一个枚举器吗?@Adrian Grigore:我可以用AcceptIVisitor方法和N个子类将N个枚举的值重构成一个抽象类。IVisitor将有N个Visit方法,一个方法用于抽象类的每个实现。多亏了访问者,我可以在域层之外定义polymophics行为,而无需将陌生对象导入域中,如业务或表示对象带有默认案例的抽象访问者是个好主意,谢谢!:如果客户希望在引入新的子类时收到编译错误的通知,那么他们总是可以选择从IVisitor接口继承…感谢您让我想起Cheese Shop草图,并微笑。我认为这个奶酪继承的例子是我新的最爱,虽然令人钦佩,但它有点局限于一个只有两层的层次结构