代碼要恰如其分,說的是隻實現當前須要的功能,保留必定的可擴展性,但不要爲了在很長一段時間內都不會發生的事情實現可擴展性。
不要預測未來,未來的新需求能夠經過不斷的重構來保持代碼的健康和可擴展性。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