代码之家  ›  专栏  ›  技术社区  ›  Hernán Eche Shankar ARUL

特定函数vs多参数vs上下文相关

  •  7
  • Hernán Eche Shankar ARUL  · 技术社区  · 15 年前

    writeInUpperCaseAndCentered(char *str){//..}
    writeInLowerCaseAndCentered(char *str){//..}
    writeInUpperCaseAndLeft(char *str){//..}
    and so on...
    

    write( char *str , int toUpper, int centered ){//..}
    

    上下文相关(难以重用、难以编码、使用难看的全局变量,有时甚至无法“检测”上下文)

    writeComplex (char *str)
    {    
        // analize str and perhaps some global variables and 
        // (under who knows what rules) put it center/left/right and upper/lowercase
    }
    

    也许还有其他的选择……(欢迎)

    问题是:

    有什么问题吗 良好做法 经验/学术建议 为了这个(反复出现的)三位一体?

    我通常做的是将“特定案例”实现与内部(我的意思是不在头中)通用多参数函数相结合,只实现使用过的案例,隐藏难看的代码,但我不知道是否有更好的方法我不知道。这类事情让我意识到OOP为什么会被发明。

    6 回复  |  直到 14 年前
        1
  •  7
  •   torak    15 年前

    我会避免使用第一种方法,因为正如您所说,最终必须实现的函数(尽管可能仅作为宏)的数量可能会失控。当您决定添加斜体支持时,计数加倍,下划线再次加倍。

    剩下第三种选择了。实际上,通过使用位标志,您可以获得其他替代方法的一些好处。例如

    #define WRITE_FORMAT_LEFT   1
    #define WRITE_FORMAT_RIGHT  2
    #define WRITE_FORMAT_CENTER 4
    #define WRITE_FORMAT_BOLD   8
    #define WRITE_FORMAT_ITALIC 16
    ....
    write(char *string, unsigned int format)
    {
      if (format & WRITE_FORMAT_LEFT)
      {
         // write left
      }
    
      ...
    }
    

    编辑:回答格雷格S。

    1. 添加 #define WRITE_FORMAT_UNDERLINE 32 到页眉
    2. 在中添加对下划线的支持 write() .

    另一个潜在的好处是,它允许您执行以下操作:

    #define WRITE_ALERT_FORMAT  (WRITE_FORMAT_CENTER | \
                                 WRITE_FORMAT_BOLD |   \
                                 WRITE_FORMAT_ITALIC)
    
        2
  •  3
  •   Luca Matteis    15 年前

    因为所有不同的场景都需要用到一些代码。从每个场景中生成一个函数将产生代码重复,这是不好的。

    不要为每个不同的情况(toUpper,centered等等)使用一个参数,而是使用一个struct。如果需要添加更多案例,则只需更改结构:

    typedef struct {
        int toUpper;
        int centered;
        // etc...
    } cases;
    write( char *str , cases c ){//..}
    
        3
  •  2
  •   ChrisF    15 年前

    编写一个方法(a),其中包含您现在需要/可以想到的所有参数,以及一个没有额外参数的“裸”版本(B)。此版本可以使用默认值调用第一个方法。如果您的语言支持,请添加默认参数。我还建议您在参数中使用有意义的名称,并且在可能的情况下使用枚举,而不是幻数或一系列数字 true false 旗帜。这将使读取代码和实际传递的值更加容易,而不必查找方法定义。

    这给了你一套有限的方法来维护和90%的使用将是基本的方法。

    如果以后需要扩展该功能,请添加一个带有新参数的新方法,并修改(a)以调用该方法。您可能想修改(B)来调用它,但这不是必需的。

        4
  •  1
  •   Jerry Coffin    15 年前

    这样做的一个主要优点是我可以创建指定 符合逻辑的

    Format title = {upper_case, centered, bold};
    Format body = {lower_case, left, normal};
    
    write(title, "This is the title");
    write(body, "This is some plain text");
    

    将逻辑格式与物理格式分离可以提供与样式表大致相同的功能。如果你想把你所有的标题从斜体改为粗体,把你的身体样式从左对齐改为完全对齐,等等,这就相对容易了。使用当前代码,您可能会搜索所有代码并“手动”检查,以确定特定的小写左对齐项是要重新格式化的正文文本,还是要保留的脚注。。。

        5
  •  0
  •   Greg S    15 年前

    正如您已经提到的,一个突出的点是可读性: writeInUpperCaseAndCentered("Foobar!") write("Foobar!", true, true) ,尽管可以通过使用枚举来消除该问题。另一方面,有争论可以避免尴尬的结构,比如:

    if(foo)
      writeInUpperCaseAndCentered("Foobar!");
    else if(bar)
      writeInLowerCaseAndCentered("Foobar!");
    else
     ...
    

    在我看来,这是一个非常有力的论点(没有双关语的意图)的论点方式。

        6
  •  0
  •   stinky472    15 年前

    我建议使用更具内聚性的函数,而不是可以做各种事情的超函数,除非真的需要一个超函数(printf如果一次只打印一种类型,那就相当尴尬了)。签名冗余一般不应被视为冗余代码。从技术上讲,这是更多的代码,但您应该更多地关注于消除代码中的逻辑冗余。结果是代码更易于维护,具有非常简洁、定义良好的行为。当编写/使用多个函数似乎是多余的时,可以将其视为理想。