Advertisement
himself

Untitled

Jul 1st, 2011
102
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pascal 3.26 KB | None | 0 0
  1. { Let's say I have a function which accepts a lot of arguments,
  2.  but only one or two are used in most of calls.
  3.  Problem is, it's never the same one or two. }
  4.  
  5. { This is how it looks like if you do it the usual way }
  6.  
  7. function DoStuff(Param1: integer; Param2: string; Param3: TRecordType;
  8.   Param4: integer; Param5: currency; Param6: float; Param7: TSomeFlag;
  9.   Param8: AnsiString); forward;
  10.  
  11. procedure Main();
  12. begin
  13.   DoStuff(0, '', CreateEmptyRecord(...), 0, 0, 35, 150.2, sfSomeFlagValue, '');
  14. end;
  15.  
  16. { Honestly, is this code readable? Nope. You don't know just by looking
  17.  which parameter goes where.
  18.  
  19.   Now imagine you have tens of call points for this function, and every one
  20.  relies on different parameters.
  21.   One sets Param4 and Param6. Another one Param4 and Param7. And so on.
  22.  
  23.   What are your options there to make this readable and handy to use?
  24.  
  25.   You cannot split this function into many because then you would need as many
  26.  versions of it as there are callers. Unmaintanable.
  27.  
  28.   You cannot rely on default parameters because they require that you don't set anything
  29.  after them:
  30.   DoStuff(5,,,,,,,,sfSomeFlagValue); //not allowed
  31.  
  32.   So you have to explicitly state the whole set of default values in every call point.
  33.  
  34.   What if you need to change the default values? Unmaintanable.
  35.  
  36.   On the contrary, my approach requires only one point of excessive coding: }
  37.  
  38. type
  39.  TDoStuffMaker = record
  40.    Param1: integer;
  41.    Param2: string;
  42.    Param3: TRecordType;
  43.    Param4: integer;
  44.    Param5: currency;
  45.    Param6: float;
  46.    Param7: TSomeFlag;
  47.    Param8: AnsiString;
  48.    procedure Call;
  49.  end;
  50.  
  51. function DoStuff: TDoStuffMaker;
  52. begin
  53.   {All default values are easily configurable from one place}
  54.   Param1 := 0;
  55.   Param2 := '';
  56.   {etc}
  57.   Param8 := '';
  58. end;
  59.  
  60. { The rest of the code is perfectly readable, even more so than the usual function calls: }
  61.  
  62. procedure Main()
  63. begin
  64.   with DoStuff do begin
  65.     Param5 := 35;
  66.     Param6 := 150.2;
  67.     Call;
  68.   end;
  69. end;
  70.  
  71. { You can care only about those parameters you want to set,
  72.  and you can even make several sets of default values for different
  73.  default cases!
  74.  
  75.   Just create two different functions which initialize and return TDoStuffMaker.
  76.  
  77.   Calling this is just as easy as calling normal functions.
  78.  You don't need to declare additional variables.
  79.  
  80.   The code generated is 2x to 3x slower than normal function calls. With inlining,
  81.  you actually construct TDoStuffMaker and fill it in the stack, so there's almost no overhead.
  82.  
  83.   Readable, maintanable, configurable, fast, what else you need?
  84.  
  85.   Just compare it: }
  86.  
  87. procedure Main()
  88. begin
  89.  { Old way }
  90.   DoStuff(0, '', CreateEmptyRecord(...), 0, 0, 35, 150.2, sfSomeFlagValue, '');
  91.  
  92.  { New way }
  93.   with DoStuff do begin
  94.     Param5 := 35;
  95.     Param6 := 150.2;
  96.     Call;
  97.   end;
  98. end;
  99.  
  100. { It's worth mentioning that you can accept and pre-parse results this way,
  101.  making code even more readable! }
  102.  
  103. procedure Main()
  104. begin
  105.   with DoStuff do begin
  106.     Param5 := 35;
  107.     Param6 := 150.2;
  108.     Call;
  109.     if ErrorCode<0 then
  110.       raise Exception.Create(ErrorMessage);
  111.   end;
  112. end;
  113.  
  114. { You don't have to contaminate your function with temporary variable declarations
  115.  to hold ErrorCode and ErrorMessage, it's all hidden in the structure. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement