代码要恰如其分,说的是只实现当前须要的功能,保留必定的可扩展性,但不要为了在很长一段时间内都不会发生的事情实现可扩展性。
不要预测未来,未来的新需求能够经过不断的重构来保持代码的健康和可扩展性。web
下面是一个在WCF内部服务中实现的类,这个前提很重要,这是一个服务的内部实现,不是契约,是不须要对外发布的组件(不含服务契约,契约经过另外的组件发布)。ide
1 public static class PictureRecognizerFactory 2 { 3 private static PictureRecognizer[] m_Recognizers; 4 private static object _oSync = new object(); 5 6 private static PictureRecognizer[] m_AllRecognizers 7 { 8 get 9 { 10 if (m_Recognizers == null) 11 { 12 lock (_oSync) 13 { 14 if (m_Recognizers == null) 15 { 16 m_Recognizers = FindAllPictureRecognizer(); 17 } 18 } 19 } 20 return m_Recognizers; 21 } 22 } 23 24 /// <summary> 25 /// 获取图片的类别 26 /// </summary> 27 /// <param name="picture"></param> 28 /// <returns></returns> 29 public static PictureType GetPictureType(Picture picture) 30 { 31 foreach (PictureRecognizer item in m_AllRecognizers) 32 { 33 PictureType type = item.Reconize(picture); 34 if (type != PictureType.Unknown) 35 return type; 36 } 37 return PictureType.Unknown; 38 39 } 40 41 /// <summary> 42 /// 寻找全部被标识了PictureRecognizerAttribute的类 43 /// </summary> 44 /// <returns></returns> 45 private static PictureRecognizer[] FindAllPictureRecognizer() 46 { 47 Type[] typesWithRecognizer = GetTypesWithRecognizers(); 48 49 List<PictureRecognizer> list = new List<PictureRecognizer>(); 50 foreach (Type type in typesWithRecognizer) 51 { 52 list.Add((PictureRecognizer)type.Assembly.CreateInstance(type.FullName)); 53 } 54 55 return list.ToArray(); 56 } 57 58 /// <summary> 59 /// 获取全部标记为RecognizerAttribute的类型 60 /// </summary> 61 /// <returns></returns> 62 private static Type[] GetTypesWithRecognizers() 63 { 64 List<Type> typesRecognizers = new List<Type>(); 65 Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); 66 foreach (Assembly ass in assemblies) 67 { 68 try 69 { 70 Type[] types = ass.GetTypes(); 71 foreach (Type type in types) 72 { 73 if (type.GetCustomAttributes(typeof(PictureRecognizerAttribute), true).Length > 0) 74 { 75 typesRecognizers.Add(type); 76 } 77 78 } 79 } 80 catch { }//若是在某个Assembly中加载不到类型,则不予理会,不处理异常 81 } 82 if (typesRecognizers.Count == 0) 83 throw new Exception("找不到任何图像识别器"); 84 return typesRecognizers.ToArray(); 85 } 86 }
这段代码有几个问题:spa
一、它经过AppDomain.CurrentDomain.GetAssemblies()来获取当前加载的全部程序集,也就是做者认为会有不少类被标记了PictureRecognizerAttribute。实际上,正如咱们前提条件所说,PictureRecognizerAttribute是一个在非公开发布的服务组件中定义的类,它是属于服务的内部实现机制,在能够预见的未来都不须要发布给服务外部的类使用。所以,全部定义了PictureRecognizerAttribute的类都和PictureRecognizerAttribute在同一个程序集中。这点很是重要。代码规范
二、基于第一个前提,也就是说全部被标记为PictureRecognizerAttribute的类对PictureRecognizerFactory都是可见的,而且可能被标记为PictureRecognizerAttribute类数量很是少,所以经过New来实现是最简单、高效的。code
三、实际上程序须要获取的是继承至PictureRecognizer的实现类,所以应该直接判断类型是否继承至PictureRecognizer,无需经过判断PictureRecognizerAttribute,引入一个无用的类。blog
重构之后的代码:继承
1 public static class PictureRecognizerFactory 2 { 3 static readonly PictureRecognizer[] _Recognizers = new PictureRecognizer[] 4 { 5 new PictureRecognizerImpl1(), 6 new PictureRecognizerImpl2(), 7 }; 8 9 /// <summary> 10 /// 获取图片的类别 11 /// </summary> 12 /// <param name="picture"></param> 13 /// <returns></returns> 14 public static PictureType GetPictureType(Picture picture) 15 { 16 foreach (PictureRecognizer item in _Recognizers) 17 { 18 PictureType type = item.Reconize(picture); 19 if (type != PictureType.Unknown) 20 return type; 21 } 22 return PictureType.Unknown; 23 24 } 25 }
若是未来须要必定的开放程度,能够经过暴露内部集合来增长必定的扩展性,参考 Asp.Net MVC ViewEngines 类的实现。图片
不要对将来作过多(不是不要)的设想,保持代码的精简,增长代码的可读性、可维护性是软件开发过程当中很是重要的一点。代码的行数越少,可能发生的Bug就越少,未来的维护(重构、扩展)难度就越低。开发
本篇文章不讨论类的命名,代码规范等问题,若有此类问题请忽略。: )get