Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- { Let's say I have a function which accepts a lot of arguments,
- but only one or two are used in most of calls.
- Problem is, it's never the same one or two. }
- { This is how it looks like if you do it the usual way }
- function DoStuff(Param1: integer; Param2: string; Param3: TRecordType;
- Param4: integer; Param5: currency; Param6: float; Param7: TSomeFlag;
- Param8: AnsiString); forward;
- procedure Main();
- begin
- DoStuff(0, '', CreateEmptyRecord(...), 0, 0, 35, 150.2, sfSomeFlagValue, '');
- end;
- { Honestly, is this code readable? Nope. You don't know just by looking
- which parameter goes where.
- Now imagine you have tens of call points for this function, and every one
- relies on different parameters.
- One sets Param4 and Param6. Another one Param4 and Param7. And so on.
- What are your options there to make this readable and handy to use?
- You cannot split this function into many because then you would need as many
- versions of it as there are callers. Unmaintanable.
- You cannot rely on default parameters because they require that you don't set anything
- after them:
- DoStuff(5,,,,,,,,sfSomeFlagValue); //not allowed
- So you have to explicitly state the whole set of default values in every call point.
- What if you need to change the default values? Unmaintanable.
- On the contrary, my approach requires only one point of excessive coding: }
- type
- TDoStuffMaker = record
- Param1: integer;
- Param2: string;
- Param3: TRecordType;
- Param4: integer;
- Param5: currency;
- Param6: float;
- Param7: TSomeFlag;
- Param8: AnsiString;
- procedure Call;
- end;
- function DoStuff: TDoStuffMaker;
- begin
- {All default values are easily configurable from one place}
- Param1 := 0;
- Param2 := '';
- {etc}
- Param8 := '';
- end;
- { The rest of the code is perfectly readable, even more so than the usual function calls: }
- procedure Main()
- begin
- with DoStuff do begin
- Param5 := 35;
- Param6 := 150.2;
- Call;
- end;
- end;
- { You can care only about those parameters you want to set,
- and you can even make several sets of default values for different
- default cases!
- Just create two different functions which initialize and return TDoStuffMaker.
- Calling this is just as easy as calling normal functions.
- You don't need to declare additional variables.
- The code generated is 2x to 3x slower than normal function calls. With inlining,
- you actually construct TDoStuffMaker and fill it in the stack, so there's almost no overhead.
- Readable, maintanable, configurable, fast, what else you need?
- Just compare it: }
- procedure Main()
- begin
- { Old way }
- DoStuff(0, '', CreateEmptyRecord(...), 0, 0, 35, 150.2, sfSomeFlagValue, '');
- { New way }
- with DoStuff do begin
- Param5 := 35;
- Param6 := 150.2;
- Call;
- end;
- end;
- { It's worth mentioning that you can accept and pre-parse results this way,
- making code even more readable! }
- procedure Main()
- begin
- with DoStuff do begin
- Param5 := 35;
- Param6 := 150.2;
- Call;
- if ErrorCode<0 then
- raise Exception.Create(ErrorMessage);
- end;
- end;
- { You don't have to contaminate your function with temporary variable declarations
- to hold ErrorCode and ErrorMessage, it's all hidden in the structure. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement