4

目前我有一些这样的代码:

    OntologyGenerator generator = new OntologyGenerator();
    generator.AddOntologyHeader("Testing");
    generator.AddClassDeclaration(owlBuilder);
    generator.AddSubClass(owlBuilder);
    generator.AddAnnotationAssertions(owlBuilder);

您看到传递的 OwlBuilder 参数具有如下对象的集合:

public class OwlLBuilder: IOwlLBuilder
{
       private ICollection<IOwlClass> owlClasses = new Collection<IOwlClass>();
       private ICollection<IOwlRelation>  owlRelations = new Collection<IOwlRelation> ();
}

例如,当我说generator.AddClassDeclaration(owlBuilder); 它将循环遍历该 owlBuilder 参数的 owlClasses 集合并对其执行一些操作...

我觉得这是一个丑陋的设计。您认为我可以利用修改现有代码以使用模板方法设计模式或您拥有的任何其他更好的设计建议来受益吗?加上一些代码示例,这样我就可以在脑海中大致了解我应该做什么!

4

1 回答 1

14

我真的在这里看不到模板方法。我看到访客模式

这是一个例子。

想象一下,你有一堆房子,你需要把它们都漆成黄色。现在你可以:

var houses = ... a list of houses ...

foreach (var house in houses)
{
    house.Color = Color.Yellow;
}

但是,您可能希望将动作(在本例中为绘画)抽象为其他东西,而不是总是将房屋涂成黄色。一种解决方案是编写一个负责将房子涂成黄色的类。该课程稍后可以替换为另一个课程,该课程以不同的颜色粉刷房屋,或者对您的房屋做一些完全不同的事情,例如添加另一层!

输入访客模式。

我将展示一些我一直在使用的通用帮助类和接口。我喜欢泛型。如果你不这样做,请随意滚动你自己的。语义是:“访问者访问可访问者”和“可访问者接受访问者”。

public interface IVisitor<in T> where T : IVisitable<T>
{
    void Visit(T visitable);
}

public interface IVisitable<out T> where T : IVisitable<T>
{
    void Accept(IVisitor<T> visitor);
}

public abstract class Visitable<T> : IVisitable<T> where T : Visitable<T>
{
    public void Accept(IVisitor<T> visitor)
    {
        visitor.Visit((T)this);
    }
}

public abstract class VisitableList<T> : List<T>, IVisitable<T> where T : Visitable<T>
{
    public void Accept(IVisitor<T> visitor)
    {
        foreach (var item in this)
        {
            item.Accept(visitor);
        }
    }
}

现在我们可以像这样设置我们的房子和我们的房子列表:

public class House : Visitable<House>
{
    public Color Color { get; set; }
}

public class Houses : VisitableList<House> {}

现在,访客——我们的画家——可以参观我们可参观的房子:

public class YellowPainter : IVisitor<House>
{
    public void Visit(House visitable)
    {
        visitable.Color = Color.Yellow;
    }
}

简单,优雅和单一的责任(!)

让我们设置房屋:

var houses = new Houses();
houses.Add(new House() { Color = Color.Green });
houses.Add(new House() { Color = Color.Blue });
houses.Add(new House() { Color = Color.White });

现在我们已经准备好粉刷我们所有的房子了。它只需要一个电话:

houses.Accept(new YellowPainter());

...我们所有的房子现在都是黄色的。好的!

我们可以很容易地做到这一点:

houses.Accept(new AdditionalFloorsBuilder(floors: 2));

或这个:

owlClasses.Accept(new OwlClassVisitor(owlBuilder, ...));

通过这样做,我们将 中每个元素的实际“访问”owlClasses与集合本身的迭代隔离开来。访问不需要修改可访问。它可以用来只检查可访问的并使用信息来修改完全不同的东西,例如。您可以使用这些信息来满足您的owlBuilder.

于 2012-08-20T22:43:27.343 回答