zoukankan      html  css  js  c++  java
  • 重构,走出重构误区

    现在有太多是文章讨论各种重构的技术,咱们就不谈了,我们就谈谈要怎么重构。

    一谈到重构,大家大多认为是运用设计模式,来使你的代码看上去非常优雅。其实重构包括很多,一个变量名的修改、代码格式的编排、分解一个大方法的等等都是属于重构的范畴。

    我相信肯定有人和我一样,捧一本重构方面的书(《重构与模式》Joshua Kerievsky著,这本就不错),一劲的狂喊这样写代码太漂亮;可是丢开书本,面对自己的代码一直寻找可以运用设计模式、需要重构的代码,最后发现一处可重构的都没。 写出优雅的代码,相信对于很多人来说一直是个瓶颈、很难去突破。不过突破后,你会发现你的世界变大了,犹如跳出井口的青蛙。

    那我们到底才能写出那么优雅的代码呢。我们先说说,我们的重构误区吧。

    误区:

     1、从已有的代码寻找与书本中匹对一样或类似的场景。

     2、在编写新代码时,脑子一直想着那几种模式,想去套用,一直想用上几个。

    最终还是没什么好的消息,造成这样的原因是,你没真正的理解设计模式的运用场景、重构技术。

    也许心里面会对自己说,这是项目比较小,没出现书本提到的那些场景。

    其实重构你可以从以下几个方面入手。

    1、寻找代码的坏味。 《你的代码需要重构吗?》

    2、review自己的代码如果觉得不好的地方就想想有没有更好的方法。可以拿出来和别人讨论,相信你一定有不一样的收获。

    3、让别人review自己的代码。在团队开发中,难免其他队员开发的功能,会和你这边的模块有关联,当有队员来问你这个函数实现什么功能、这段代码的什么意思。

    这有可能以下的原因:a、自己写的代码太烂! b、队员的技术太菜,看不懂。 c、队员较懒,不想去看。

    在给他解释时,你就要注意你们的对话,对你重构是有帮助的。

     队员:我不懂你这个变量是干什么的。

    你就要想想,自己写变量命名不规范?

    队员:你这段太长了,看得我头痛。

    也是你的函数真的太长了,该修剪你的代码了,把这个大功能,分割为几个小功能。

     4、阅读别人的代码。你可以阅读一些比较经典的开源代码,这样你可以和很多人一起讨论。在阅读时,要认认真真的看,读懂它的框架,渗透理解它的各个细节。

    下面我举一个我在现实开发中碰到的一个问题:

    第一次代码:

    1 public class OrderSync
    2 {
    3 //订单状态,Created、Closee、Dealing、Paying、Posting
    4   public string Status;
    5 public void Sync()
    6 {
    7 OrderRequest req=new OrderRequest();
    8 req.Status=Status;
    9
    10 req.Search();
    11 ...
    12 }
    13 }
    14
    15 OrderSync orderSync=new OrderSync();
    16 orderSync.Status = "Created";

    缺点:

    1、不清楚订单有哪几种状态。

    2、如果“Created”,改成为“Create”,需要修改所有的地方,那你就开始寻找吧。

    3、orderSync.Status = "Created";不小心写成orderSync.Status = "Created1111";只能单独纳闷为什么无法查询到记录。

    第二次代码:

    1 public class OrderSync
    2 {
    3 //订单状态,Created、Closed、Dealing、Paying、Posting
    4   public string Status;
    5 public void Sync()
    6 {
    7 OrderRequest req = new OrderRequest();
    8 req.Status=Status;
    9
    10 req.Search();
    11 ...
    12 }
    13 }
    14
    15  public class OrderStatu
    16 {
    17 public static string Created = "Created";
    18 public static string Closed = "Closed";
    19 public static string Dealing = "Dealing";
    20 public static string Paying = "Paying";
    21 public static string Posting = "Posting";
    22 }
    23
    24 OrderSync orderSync = new OrderSync();
    25 orderSync.Status = OrderStatu.Created;

    此次重构解决了第一次的3个缺点。但它还是有缺点的:

     1、在OrderSync中Status是字符串的,没相应的格式来限制。若你的团队来了一个新的成员,他对此系统不是很熟悉,他就有可能这么写: OrderSync orderSync = new OrderSync(); orderSync.Status = "Created";

    第三次代码:

     

    1 public class OrderSync
    2 {
    3 public OrderStatu Status;
    4 public void Sync()
    5 {
    6 OrderRequest req=new OrderRequest();
    7 req.Status = OrderStatuHelper.GetStatu(Status);
    8
    9 req.Search();
    10 ...
    11 }
    12 }
    13
    14  public enum OrderStatu
    15 {
    16 Created,
    17 Closed,
    18 Dealing,
    19 Paying,
    20 Posting
    21 }
    22
    23  public class OrderStatuHelper
    24 {
    25 private static string Created = "Created";
    26 private static string Closed = "Closed";
    27 private static string Dealing = "Dealing";
    28 private static string Paying = "Paying";
    29 private static string Posting = "Posting";
    30
    31 public static string GetStatu(OrderStatu orderStatu)
    32 {
    33 switch(orderStatu)
    34 {
    35 case OrderStatu.Closed:
    36 return Closed;
    37 case OrderStatu.Dealing:
    38 return Dealing;
    39 case OrderStatu.Payding:
    40 return Pading;
    41 case OrderStatu.Posting:
    42 return Posting;
    43 default:
    44 return Created;
    45 }
    46 }
    47 }

    这样在给订单赋值时,只能从OrderStatu去选择状态,避免了第二次的缺点。

    当然了它也是有缺点的:

    1、性能相对于第一次不是很高。(在性能差的系统中,这往往不是影响系统性能的主要原因)

     2、增加了系统的复杂度。

    这样,如果以后我们再碰到“第一次的代码”,我们就能直接把它重构到“第三次代码”,不用经过“第二次代码”。

    想想为什么我们无法写出像书本上那样的优雅的代码,那是因为我们没真正理解问题的所在、找到问题的关键点。必须先经历“第二次代码”,才能到达“第三次代码”。

    PS:很高兴得到大家的积极回复、讨论。

    对于“第三次代码”中的OrderStatusHelper560889223又再次重构,我个人觉得是一段很精彩的代码,把它在这,提供大家参考。

    1 public class OrderStatuHelper
    2 {
    3 private static readonly Dictionary<OrderStatu, string> enum2string;
    4
    5 static OrderStatuhelper
    6 {
    7 enum2string = new Dictionary<OrderStatu, string>();
    8 enum2string[OrderStatu.Created] = "Created";
    9 enum2string[OrderStatu.Closed] = "Closed";
    10 enum2string[OrderStatu.Dealing] = "Dealing";
    11 enum2string[OrderStatu.Paying] = "Paying";
    12 enum2string[OrderStatu.Posting] = "Posting";
    13 }
    14
    15 public static string GetStatu(OrderStatu orderStatu)
    16 {
    17 string statuString;
    18 return enum2string.TryGetValue(orderStatu, out statuString) ? statuString : enum2string[OrderStatu.Created];
    19 }
    20 }
    
  • 相关阅读:
    lea
    DIV指令
    html基础
    浮点计算结果误差,以及解决方法
    java的threadLocal类
    java多线程基础总结
    sql反模式读书笔记 (持续更新)
    pdb 调试初步
    面向对象设计原则与总结 (持续更新)
    @servcie注解基本用法
  • 原文地址:https://www.cnblogs.com/chingho/p/1891647.html
Copyright © 2011-2022 走看看