首先是良好工厂模式? 更新:否 - 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完全不知道它甚至控制着哪些Sorters。它只是为任何前端感兴趣的提供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
方法
由于这是一个使用MEF的可扩展SortController,所有排序算法都有公共的无参数构造函数来满足实例化需求。
答案 0 :(得分:2)
IMO,Factory假设您要返回一个类型的实例。我不太确定这是代码实际上做的。我可能错了,所以请纠正我的逻辑。
1)工厂界面应简单,仅负责创建,ISorter
的名称并不表示它是工厂
2)ISorter Initialize(IEnumerable<int> Source)
;我认为返回当前接口实例的方法不是最好的做法,你在这里面临某种无限递归
3)IEnumerable<int> SortedList { get; }
名称表明它是一个排序列表,实际上是.NET中的type name。此类代码可能会使其他开发人员感到困惑
4)MergeSorter > constructor
包含两个数组副本 - 一个数组需要两倍的内存,这会使内存消耗增加一倍(这实际上是否需要这种排序算法?)
5)它不是线程安全的,因为您正在将ToArray()用于同一个数组(进入两个私有字段)。那里没有同步,因此数组可能会在这两个调用之间发生变化,导致令人讨厌的异常
总结
我建议:
1)瘦而专用的工厂界面
2)将排序功能移至实施IComparer
3)这需要进行大量的重构,因此如果此代码有效,只需添加复制/删除/修改数组的锁(以使其保证线程安全)并删除(如果可能)重复的副本