代码要恰如其分——记一次代码审查

代码要恰如其分,说的是只实现当前须要的功能,保留必定的可扩展性,但不要为了在很长一段时间内都不会发生的事情实现可扩展性。
不要预测未来,未来的新需求能够经过不断的重构来保持代码的健康和可扩展性。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     }
View Code

这段代码有几个问题: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     }
View Code

 若是未来须要必定的开放程度,能够经过暴露内部集合来增长必定的扩展性,参考 Asp.Net MVC ViewEngines 类的实现。图片

不要对将来作过多(不是不要)的设想,保持代码的精简,增长代码的可读性、可维护性是软件开发过程当中很是重要的一点。代码的行数越少,可能发生的Bug就越少,未来的维护(重构、扩展)难度就越低。开发

本篇文章不讨论类的命名,代码规范等问题,若有此类问题请忽略。: )get

相关文章
相关标签/搜索