必会重构技巧:封装集合

封装集合:将集合中的某些方法封装起来,这些方法一般会牵扯到其他的逻辑。

  举例理解:比如你给一个List<T>里面加一个对象的同时,可能还有一个计数器在计算List中对象的个数,我们不用暴露计数器,这样List.Add()和List.Remove()我们就可以封装起来了。

  项目实例:我记得我有个项目需要不断的从数据库中读取User的Guid然后狂发Mail。开始的想法很简单,根据Window ID 去 CorpDirectory 抓Guid和Mail Address就好了。实际情况也就这么简单,但是后来Debug的时候发现程序很慢,弄了半天终于发现是这个抓Guid和Mail的动作太慢了,CorpDirectory 这个DB在美国,Production的Server在国内,于是乎每次请求都来往返于太平洋。怎么解决?大家肯定一个就想到了Cache,恩,我第一个也是想到了在Server创建Cache。本实例的意义并不在于使用Cache来提高App的性能,而在于对于Cache内对象的存取。
  先来看看原始的未经过封装的代码:

 

  
    
public class UserEntity
{
public Guid Gid { get ; set ; }
public string Name { get ; set ; }
}

 

添加Cache对象方法
   
     
private void OldAddUserCache()
{
var user
= new UserEntity
{
Gid
= new Guid(),
Name
= " Yang,Dennis "
};
IDictionary
< Guid, string > users = new Dictionary < Guid, string > ();
if (Cache[ " Users >" ] != null )
{
users
= Cache[ " Users " ] as IDictionary < Guid, string > ;
if (users != null && ! users.ContainsKey(user.Gid))
{
users.Add(user.Gid, user.Name);
Cache[
" Users " ] = users;
}
}
else
{
Cache[
" Users " ] = users;
}
}

  以上方法可以实现对Cache的添加,让我们分析一下有什么问题,我觉得至少有以下四点:

(1) 对于每次的Cache存取都要再写一遍代码,都是 重复劳动不爽。
(2) 把Add,Remove暴露出来, 增加手误,出现Bug的几率。
(3) 最重要的,如果要 改里面的逻辑将要去改很多相似的代码段。
(4) 对于其它一些可能需要用的相似的方法,比如出了增加以外的 删除、读取等,都需要写 很多相似的代码段
  为了偷懒,为了使程序程序便于维护,这段代码有必要重构, 封装!
  经过重构的代码:
   
     
public enum ManageUserCacheActionType
{
Add
= 1 ,
Remove
= 2 ,
Read
= 3
}

 

   
     
private void TestManagerUserCache()
{
var user
= new UserEntity
{
Gid
= new Guid(),
Name
= " Yang,Dennis "
};
ManageUserCache(user, ManageUserCacheActionType.Add);
ManageUserCache(user, ManageUserCacheActionType.Read);
ManageUserCache(user, ManageUserCacheActionType.Remove);
ManageUserCache(user, ManageUserCacheActionType.Read);
}

 

管理UserCache的方法
    
      
private void ManageUserCache(UserEntity user, ManageUserCacheActionType act)
{
IDictionary
< Guid, string > users = new Dictionary < Guid, string > ();
if (Cache[ " Users " ] != null )
{
users
= Cache[ " Users " ] as IDictionary < Guid, string > ;
switch (act.ToString())
{
case " Add " :
ManageUserCacheAdd(users, user);
break ;
case " Remove " :
ManageUserCacheRemove(users, user);
break ;
case " Read " :
ManageUserCacheRead(users, user);
break ;
default :
return ;
}
}
else
{
Cache[
" Users " ] = users;
}
}

 

管理UserCache的方法
     
       
private void ManageUserCache(UserEntity user, ManageUserCacheActionType act)
{
IDictionary
< Guid, string > users = new Dictionary < Guid, string > ();
if (Cache[ " Users " ] != null )
{
users
= Cache[ " Users " ] as IDictionary < Guid, string > ;
switch (act.ToString())
{
case " Add " :
ManageUserCacheAdd(users, user);
break ;
case " Remove " :
ManageUserCacheRemove(users, user);
break ;
case " Read " :
ManageUserCacheRead(users, user);
break ;
default :
return ;
}
}
else
{
Cache[
" Users " ] = users;
}
}
对UserCache的增加、删除、读取
    
      
private void ManageUserCacheRead(IDictionary < Guid, string > users, UserEntity user)
{
if (users != null && users.ContainsKey(user.Gid))
{
Response.Write(
string .Format( " Guid:{0} -- Name:{1}<br> " , user.Gid, user.Name));
}
else
{
Response.Write(
string .Format( " Guid:{0} not exist<br> " , user.Gid));
}
}
private void ManageUserCacheRemove(IDictionary < Guid, string > users, UserEntity user)
{
if (users != null && users.ContainsKey(user.Gid))
{
users.Remove(user.Gid);
Cache[
" Users " ] = users;
}
}
private void ManageUserCacheAdd(IDictionary < Guid, string > users, UserEntity user)
{
if (users != null && ! users.ContainsKey(user.Gid))
{
users.Add(user.Gid, user.Name);
Cache[
" Users " ] = users;
}
}

 

以上重构方法包括:对集合方法的封装提取方法功能的单一化

  归纳总结:

  (1)把易出Bug的方法封装到类中,不要直接暴露出来,比如对于List,Dictionary,Queue等的Add(),Remove()。

  (2)在本文中其实也用到了其它的重构方法,如提取方法,提取方法对象,后面会有专门一篇介绍提取的技巧。 

  
  OK,这下清晰了,除了主函数,其它的方法可以独立出一个UserCacheUtility的类文件,以后所有对于UserCache的操作可就相当轻松了。
如此封装一下,可读性,可维护性都大大增强了,这种重构,易于掌握又很有实效,绝对是Coding必备技巧。
  第一篇就写到此,真的没写过这种东西,希望各位提出宝贵意见,有砖头尽管砸过来吧:)

你可能感兴趣的:(集合)