zoukankan      html  css  js  c++  java
  • 必会重构技巧(一):封装集合

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

      举例理解:比如你给一个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内对象的存取。
      先来看看原始的未经过封装的代码:

    publicclass UserEntity
    {
    public Guid Gid { get; set; }
    publicstring 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) 对于其它一些可能需要用的相似的方法,比如出了增加以外的 删除、读取等,都需要写很多相似的代码段
     
      为了偷懒,为了使程序程序便于维护,这段代码有必要重构,封装!
      经过重构的代码:
    publicenum ManageUserCacheActionType
    {
    Add
    =1,
    Remove
    = 2,
    Read
    =3
    }
    复制代码
    privatevoid 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 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必备技巧。
     
      第一篇就写到此,真的没写过这种东西,希望各位提出宝贵意见,有砖头尽管砸过来吧:)
  • 相关阅读:
    《VC驿站《PE文件格式解析》》
    《逆向分析教程》
    《逆向工程核心原理.pdf【2】》
    《逆向工程核心原理.pdf》
    一个完整的机器学习项目在Python中的演练(一)
    粒子群优化算法(PSO)之基于离散化的特征选择(FS)(三)
    Tensorboard详解(下篇)
    Tensorboard 详解(上篇)
    基于Doc2vec训练句子向量
    使用Keras进行深度学习:(七)GRU讲解及实践
  • 原文地址:https://www.cnblogs.com/ywsoftware/p/2892652.html
Copyright © 2011-2022 走看看