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