zoukankan      html  css  js  c++  java
  • 简化条件表达式之移除控制标记(Remove Control Flag)

    在一系列布尔表达式中,某个变量带有“控制标记’的作用。以break或return语句取代控制标记。

    动机:在一系列条件表达式中,常常会看到用以判断何时停止条件检查的控制标记。这样的标记带来的麻烦超过了它所带来的便利。人们之所以会使用这样的控制标记,因为结构化编程原则告诉他们:每个子程序只能有一个入口和出口。“单一出口“原则会让你在代码中加入让人讨厌的控制标记,大大降低条件表达式的可读性。这就是编程语言提供break和continue语句的原因:用它们跳出复杂的条件语句。去掉控制标记所产生的效果往往让你大吃一惊:条件语句真正的用途会清晰得多。

    做法:1、对控制标记的处理,最显而易见的办法就是使用break或continue语句。

           2、找出让你跳出这段逻辑的控制标记值。

           3、找出对标记变量赋值的语句,代以恰当的break或continue语句。

           4、每次替换后,编译并测试

    范例:以break 取代简单的控制标记

    void checkSecurity(String[] people) {
    
          boolean found = false;
    
          for (int i = 0; i < people.length; i++) {
    
              if (! found) {
    
                 if (people[i].equals ("Don")){
    
                   sendAlert();
    
                   found = true;
    
                 }
    
                 if (people[i].equals ("John")){
    
                   sendAlert();
    
                   found = true;
    
                 }
    
              }
    
          }
    
      }

    这种情况下很容易找出控制标记:当变量found 被赋予true 时,搜索就结束。我可以逐一引入break 语句:

    void checkSecurity(String[] people) {
    
          boolean found = false;
    
          for (int i = 0; i < people.length; i++) {
    
              if (! found) {
    
                 if (people[i].equals ("Don")){
    
                   sendAlert();
    
                break;
    
                 }
    
                 if (people[i].equals ("John")){
    
                   sendAlert();
    
                   found = true;
    
                 }
    
              }
    
          }
    
      }

       处理后的代码

    void checkSecurity(String[] people) {
    
          boolean found = false;
    
          for (int i = 0; i < people.length; i++) {
    
              if (! found) {
    
                 if (people[i].equals ("Don")){
    
                   sendAlert();
    
                   break;
    
                 }
    
                 if (people[i].equals ("John")){
    
                   sendAlert();
    
                   break;
    
                 }
    
              }
    
          }

    最后可以把对控制标记的所有引用去掉:

     void checkSecurity(String[] people) {
    
          for (int i = 0; i < people.length; i++) {
    
              if (people[i].equals ("Don")){
    
                 sendAlert();
    
                 break;
    
              }
    
              if (people[i].equals ("John")){
    
                 sendAlert();
    
                 break;
    
              }
    
          }
    
      }

    范例:以return 返回控制标记

    本项重构的另一种形式将使用return 语句。为了阐述这种用法,我把前面的例子稍加修改,以控制标记记录搜索结果:

     void checkSecurity(String[] people) {
    
          String found = "";
    
          for (int i = 0; i < people.length; i++) {
    
              if (found.equals("")) {
    
                 if (people[i].equals ("Don")){
    
                   sendAlert();
    
                   found = "Don";
    
                 }
    
                 if (people[i].equals ("John")){
    
                   sendAlert();
    
                   found = "John";
    
                 }
    
              }
    
          }
    
          someLaterCode(found);
    
      }

    在这里,变量found 做了两件事:它既是控制标记,也是运算结果。遇到这种情况,我喜欢先把计算found 变量的代码提炼到一个独立函数中:

     void checkSecurity(String[] people) {
    
          String found = foundMiscreant(people);
    
          someLaterCode(found);
    
      }
    
      String foundMiscreant(String[] people){
    
          String found = "";
    
          for (int i = 0; i < people.length; i++) {
    
              if (found.equals("")) {
    
                 if (people[i].equals ("Don")){
    
                   sendAlert();
    
                   found = "Don";
    
                 }
    
                 if (people[i].equals ("John")){
    
                   sendAlert();
    
                   found = "John";
    
                 }
    
              }
    
          }
    
          return found;
    
      }

    然后以return 语句取代控制标记:

    String foundMiscreant(String[] people){
    
          String found = "";
    
          for (int i = 0; i < people.length; i++) {
    
              if (found.equals("")) {
    
                 if (people[i].equals ("Don")){
    
                   sendAlert();
    
                  return "Don";
    
                 }
    
                 if (people[i].equals ("John")){
    
                   sendAlert();
    
                   found = "John";
    
                 }
    
              }
    
          }
    
          return found;
    
      }

    最后完全去掉控制标记:

     String foundMiscreant(String[] people){
    
          for (int i = 0; i < people.length; i++) {
    
              if (people[i].equals ("Don")){
    
                 sendAlert();
    
                 return "Don";
    
              }
    
              if (people[i].equals ("John")){
    
                 sendAlert();
    
                 return "John";
    
              }
    
          }
    
          return "";
    
      }

    即使不需要返回某值,你也可以使用语句来取代控制标记。这时候你只需 要一个空的return 语句就行了。

    当然,如果以此办法去处理带有副作用(连带影响)的函数,会有一些问题。所以我需要先以 Separate Query from Modifier 将函数副作用分离出去。

  • 相关阅读:
    Python基础语法 第2节课(数据类型转换、运算符、字符串)
    python基础语法 第5节课 ( if 、 for )
    python基础语法 第4节课 (字典 元组 集合)
    Python基础语法 第3节课 (列表)
    A. Peter and Snow Blower 解析(思維、幾何)
    C. Dima and Salad 解析(思維、DP)
    D. Serval and Rooted Tree (樹狀DP)
    C2. Balanced Removals (Harder) (幾何、思維)
    B. Two Fairs 解析(思維、DFS、組合)
    D. Bash and a Tough Math Puzzle 解析(線段樹、數論)
  • 原文地址:https://www.cnblogs.com/newbee0101/p/11981976.html
Copyright © 2011-2022 走看看