Во-первых, это хороший заводской образец? Обновление: нет - ISorter технически не соответствует правильному определению для заводского шаблона
Учитывая следующий интерфейс:
public interface ISorter
{
ISorter Initialize(IEnumerable<int> Source);
void Sort( );
string Name { get; }
IEnumerable<int> SortedList { get; }
}
... и 3 сортировщика - InsertionSort, MergeSort и QuickSort. Вот реализация, использующая MergeSort:
[Export(typeof(ISorter))]
public class MergeSorter : ISorter
{
int[] leftArray;
int[] rightArray;
private MergeSorter(IEnumerable<int> source)
{
// independent copies of array
leftArray = source.ToArray( );
rightArray = source.ToArray( );
}
public ISorter Initialize(IEnumerable<int> Source)
{
return new MergeSorter(Source);
}
public void Sort( )
{ /* call merge sort method */ }
// assume the rest of ISorter is implemented
// as well as the main Sort( ... ) method
}
Классы InsertionSort
и QuickSort
следуют идентичной схеме. Конечно, SortController совершенно не знает, какими Сортировщиками он даже управляет. Он просто предоставляет список SorterNames для всех заинтересованных сторон. Теперь мой вопрос вращается вокруг реализации ISorter.Initialize( )
. Я возвращаю вновь созданный объект ISorter с инициализированными внутренними массивами. Предполагается, что SortController может обрабатывать несколько запросов к экземпляру нескольких сортировщиков; Кроме того, метод Sort будет выполняться с помощью метода SortController.StartSorter ( )
:
public static void StartSorter(string SorterName, IEnumerable<int> Source)
{
// find ISorter by name and initialize
// 'sorters' is an internal SorterCollection initialized from MEF discovery
ISorter sorter = sorters.Sorters
.Where(key => key.Name == SorterName)
.FirstOrDefault( )
.Initialize(Source);
if (sorter == null)
{ return; }
SortInfo info = new SortInfo
{
Collection = sorter.SortedList,
Invoker = sorter.Sort, // delegate for asynchronous execution
Sorter = sorter,
Timer = new System.Diagnostics.Stopwatch( )
};
info.Timer.Start( );
info.Invoker.BeginInvoke(new AsyncCallback(SortCompleted), info);
RunningSorters.Add(sorter);
}
Тогда в обратном вызове вы увидите мое единственное событие, определенное следующим образом:
public static event EventHandler<SortCompletedEventArgs> OnSortCompleted = delegate { };
static void SortCompleted ( IAsyncResult iaResult )
{
// retrieve SortInfo object from IAsyncResult
var info = (SortInfo)iaResult.AsyncState;
// delegate - EndInvoke
info.Invoker.EndInvoke ( iaResult );
// raise event
OnSortCompleted ( info, new SortCompletedEventArgs ( info ) );
// remove from running sorters list
RunningSorters.Remove(info.Sorter);
}
Это хороший заводской шаблон для MEF? И является ли это поточно-ориентированная и стабильная реализация, способная обрабатывать несколько сортировщиков (скажем, до 100 000 целых чисел на сортировщик)?
Редактировать
Примечание: MergeSorter требует, чтобы исходный массив был разбит на 2 массива; следовательно, leftArray
и rightArray
. Как только массив назначен, мы закончили с Source
, и его можно свободно изменять.
3 алгоритма сортировки, которые я использовал, были демонстрационными библиотеками, а не моими собственными. Моя собственная процедура сортировки будет использовать метод Compare
.
Поскольку это расширяемый SortController, использующий MEF, все алгоритмы сортировки имеют открытые, не имеющие параметров конструкторы, удовлетворяющие требованию создания экземпляров.