Na samym początku stwórzmy pomocnicze metody:
public class HelpClass
{
public static IEnumerable<T> GenerateData<T>(Func<int, T> func)
{
for (int i = 0; ; i++)
{
yield return func(i);
}
}
public static DescriptionAttribute GetClassDescriptionAttribute(Type type)
{
return type
.GetCustomAttributes(typeof(DescriptionAttribute), false)
.FirstOrDefault() as DescriptionAttribute;
}
}
Następnie stwórzmy abstrakcyjną klasę bazową, po której klasy z implementacją kroku będą dziedziczyć.Klasa ta będzie miała abstrakcyjną metodę - Handle(T input).
public abstract class BaseStep<T>
{
protected BaseStep<T> _nextStep;
public void SetNextStep(BaseStep<T> nextStep)
{
_nextStep = nextStep;
}
public T HandleProcess(T input)
{
var desc = HelpClass
.GetClassDescriptionAttribute(this.GetType());
if(desc != null)
Console.WriteLine(desc.Description);
var items = Handle(input);
return _nextStep != null ? _nextStep.HandleProcess(items) : items;
}
protected abstract T Handle(T input);
}
Teraz możemy napisać poszczególne implementacje kroków. Niech pierwszy krok będzie usuwał pierwszy element w liście, a drugi krok będzie usuwał duplikaty. Skorzystamy z atrybutu Description, aby mieć opis w którym kroku jesteśmy.
[Description("Filters first element")]
public class FilterFirstStep<T> : BaseStep<IEnumerable<T>>
{
protected override IEnumerable<T> Handle(IEnumerable<T> input)
{
return input.Skip(1);
}
}
[Description("Filters duplicated elements")]
public class FilterDuplicatedStep<T> : BaseStep<IEnumerable<T>>
{
protected override IEnumerable<T> Handle(IEnumerable<T> input)
{
return input.Distinct();
}
}
Dodatkowo stwórzmy krok, który będzie zawierał informacje jak długo trwało przetwarzanie listy.
[Description("Measuring step")]
public class MeasureStep<T> : BaseStep<IEnumerable<T>>
{
public long Elapsed { get; private set; }
protected override IEnumerable<T> Handle(IEnumerable<T> input)
{
Stopwatch stopwatch = Stopwatch.StartNew();
var result = input.ToList();
Elapsed = stopwatch.ElapsedMilliseconds;
return result;
}
}
Teraz jak mamy wszystkie kroki to możemy zająć się testowaniem pipelineu.
Random random = new Random();
var items = HelpClass.GenerateData(i => random.Next(i)).Take(90000);
MeasureStep<int> measure = new MeasureStep<int>();
FilterFirstStep<int> filterFirst= new FilterFirstStep<int>();
measure.SetNextStep(filterFirst);
filterFirst.SetNextStep(new FilterDuplicatedStep<int>());
var hanled = measure
.HandleProcess(items)
.ToList();
Console.WriteLine(measure.Elapsed);
I na konsoli mamy:
Brak komentarzy:
Prześlij komentarz