gpt4 book ai didi

c# - 在 C# 中实现访问者模式

转载 作者:太空狗 更新时间:2023-10-29 19:49:49 25 4
gpt4 key购买 nike

我是这个模式的新手,有人可以帮助我吗?

我有一个这样的对象:

public class Object
{
public string Name { get; set; }
public object Value { get; set; }
public List<Object> Childs { get; set; }
}

这是一个 JSON 示例:

  {
"Name": "Method",
"Value": "And",
"Childs": [{
"Name": "Method",
"Value": "And",
"Childs": [{
"Name": "Operator",
"Value": "IsEqual",
"Childs": [{
"Name": "Name",
"Value": "5",
"Childs": []
}]
},
{
"Name": "Operator",
"Value": "IsEqual",
"Childs": [{
"Name": "Name",
"Value": "6",
"Childs": []
}]
}]
},
{
"Name": "Operator",
"Value": "IsEqual",
"Childs": [{
"Name": "Name",
"Value": "3",
"Childs": []
}]
}]
}

我的问题是如何制作访问者模式以获得最终字符串:

(Name IsEqual 3)And((Name IsEqul 5)And(Name IsEqual 6))

最佳答案

要实现访客模式你需要两个简单的接口(interface)

  1. IVisitableAccept 方法,该方法以 IVisitor 作为参数。
  2. IVisitorIVisitable
  3. 的每个实现提供许多 Visit 方法

因此访问者模式的基本思想是根据实现的类型动态改变行为。

对于你的情况,你想要访问的东西(可访问的)是 Object 类,它显然没有不同的衍生物,你想根据属性值而不是类型来改变行为。所以访问者模式并不是您真正需要的,我强烈建议您使用递归方法来考虑答案。

但是如果你真的想在这里使用访问者模式,它可能看起来像这样。

interface IVisitable { void Accept(IVisitor visitor); }

interface IVisitor {
void VisitAnd(Object obj);
void VisitEquals(Object obj);
}

由于 Object 类是一个简单的 POCO,我假设您不想实现接口(interface)并向此类添加方法。所以你需要一个 adapterObject 适配为 IVisitable

的对象
class VisitableObject : IVisitable {
private Object _obj;

public VisitableObject(Object obj) { _obj = obj; }

public void Accept(IVisitor visitor) {
// These ugly if-else are sign that visitor pattern is not right for your model or you need to revise your model.
if (_obj.Name == "Method" && _obj.Value == "And") {
visitor.VisitAnd(obj);
}
else if (_obj.Name == "Method" && _obj.Value == "IsEqual") {
visitor.VisitEquals(obj);
}
else
throw new NotSupportedException();
}
}
}

public static ObjectExt {
public static IVisitable AsVisitable(this Object obj) {
return new VisitableObject(obj);
}
}

最后访问者的实现可能是这样的

class ObjectVisitor : IVisitor {
private StringBuilder sb = new StringBuilder();

public void VisitAnd(Object obj) {
sb.Append("(");
var and = "";
foreach (var child in obj.Children) {
sb.Append(and);
child.AsVisitable().Accept(this);
and = "and";
}
sb.Append(")");
}

public void VisitEquals(Object obj) {
// Assuming equal object must have exactly one child
// Which again is a sign that visitor pattern is not bla bla...
sb.Append("(")
.Append(obj.Children[0].Name);
.Append(" Equals ");
.Append(obj.Children[0].Value);
.Append(")");
}
}

关于c# - 在 C# 中实现访问者模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32933122/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com