Boh*_*ohn 4 c# design-patterns
目前我有一些像这样的代码:
OntologyGenerator generator = new OntologyGenerator();
generator.AddOntologyHeader("Testing");
generator.AddClassDeclaration(owlBuilder);
generator.AddSubClass(owlBuilder);
generator.AddAnnotationAssertions(owlBuilder);
Run Code Online (Sandbox Code Playgroud)
您看到传递的OwlBuilder参数的集合具有如下对象的集合:
public class OwlLBuilder: IOwlLBuilder
{
private ICollection<IOwlClass> owlClasses = new Collection<IOwlClass>();
private ICollection<IOwlRelation> owlRelations = new Collection<IOwlRelation> ();
}
Run Code Online (Sandbox Code Playgroud)
所以例如当我说generator.AddClassDeclaration(owlBuilder); 它将循环遍历owlBuilder param的owlClasses集合并为它做一些事情......
我觉得这是一个丑陋的设计.您认为我可以利用修改现有代码来使用模板方法设计模式或您拥有的任何其他更好的设计建议吗?以及一些代码示例,以便我可以全面了解我应该做的事情!
Chr*_*tte 14
这是一个例子.
想象一下,你有一堆房子,你需要把它们全部涂成黄色.现在你可以:
var houses = ... a list of houses ...
foreach (var house in houses)
{
house.Color = Color.Yellow;
}
Run Code Online (Sandbox Code Playgroud)
但是,不是总是把你的房子涂成黄色,你可能希望将这个动作(在这种情况下是绘画)抽象成其他东西.一个解决方案是写一个负责将房子涂成黄色的类.以后这个课程可以替代另一个用不同颜色描绘房子的课程,或者做一些与你的房子完全不同的课程,比如添加另一个楼层!
输入访客模式.
我将展示一些我一直在使用的通用助手类和接口.我喜欢泛型.如果你不这样做,请随意自己动手.语义是:"访问者访问访问者","访问者访问访问者".
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在我们可以设置我们的房子和我们的房屋列表,如下所示:
public class House : Visitable<House>
{
public Color Color { get; set; }
}
public class Houses : VisitableList<House> {}
Run Code Online (Sandbox Code Playgroud)
现在,访客 - 我们的画家 - 可以访问我们的可访问的房子:
public class YellowPainter : IVisitor<House>
{
public void Visit(House visitable)
{
visitable.Color = Color.Yellow;
}
}
Run Code Online (Sandbox Code Playgroud)
简单,优雅,单一责任(!).
我们来建房子:
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 });
Run Code Online (Sandbox Code Playgroud)
现在我们准备好把我们所有的房子都画出来.它只需要一个电话:
houses.Accept(new YellowPainter());
Run Code Online (Sandbox Code Playgroud)
......我们所有的房子现在都是黄色的.太好了!
我们可以轻松地做到这一点:
houses.Accept(new AdditionalFloorsBuilder(floors: 2));
Run Code Online (Sandbox Code Playgroud)
或这个:
owlClasses.Accept(new OwlClassVisitor(owlBuilder, ...));
Run Code Online (Sandbox Code Playgroud)
通过这样做,我们已经owlClasses从集合本身的迭代中隔离了每个元素的实际"访问"中发生的事情.访问不需要修改访问.它可以用于仅检查可访问性并使用信息来修改完全不同的内容,例如.你可以用这些信息来喂你的owlBuilder.