How many arguments is a reasonable number, large objects, and atomic arguments. Oop

I am a new developer, and I would like to learn from your experience what is best when you build a class of methods, and if there is no better approach, how to balance your decisions regarding:

  • Pass as arguments a large object containing most of the variables needed for this method.
  • Skip more variable atomic individuals, with the consequences of generating methods with large signatures.

What is better for the code that will evolve? and what do you think is a reasonable amount of arguments?

+4
source share
2 answers

I would strongly argue in favor of traversing the object if this allows for generality in the sets of arguments pf.

Why?

Because X% of the effort goes into preserving existing code, and LOT is more difficult to add new parameters - especially in methods that intercept each other and pass these new parameters - than add a property to the object.

Note that this should not be CLASS per se, in the sense of the availability of methods. Just a storage container (either a heterogeneous map / dictionary, or a security type, structure in C-type languages ​​that support it).

Example (I will use pseudo-code, do not hesitate in what language it is based):


First, look at the old and new code using argument lists

Old code:

function f1(arg1, arg2, arg3, arg4, arg5) { res = f2(arg1, arg2, arg3, arg4); } function f2(arg1, arg2, arg3, arg4) { res = f3(arg1, arg2, arg4); } function f3(arg1, arg2, arg4) { res = f4(arg1, arg4); } function f4(arg1, arg4) { return arg1 + arg4; } 

New code (add arg6 to f4 ()):

 function f1(arg1, arg2, arg3, arg4, arg5, arg6) { // changed line res = f2(arg1, arg2, arg3, arg4, arg6); // changed line } function f2(arg1, arg2, arg3, arg4, arg6) { // changed line res = f3(arg1, arg2, arg4, arg6); // changed line } function f3(arg1, arg2, arg4, arg6) { // changed line res = f4(arg1, arg4, arg6); // changed line } function f4(arg1, arg4, arg6) { // changed line return arg1 + arg4 + arg6; // changed line } 

As you can see, for 4-level nested calls, we changed ALL 4 functions at least 2 lines per function. YIKES. Thus, for 10-level nested calls, adding 1 parameter changes all TEN functions and 20 lines.


Now an example of the same change, besides the arg list, is now an object (or a heterogeneous map will be executed for dynamic languages ​​:)

 class args_class { public: int arg1, arg2, arg3, arg4, arg5; } } args_class arg_object; function f1(arg_object) { res = f2(arg_object); } function f2(arg_object) { res = f3(arg_object); } function f3(arg_object) { res = f4(arg_object); } function f4(arg_object) { return arg_object.arg1 + arg_object.arg4; } 

And what will we change to add arg6?

 class args_class { public: int arg1, arg2, arg3, arg4, arg5, arg6; // line changed } } // f1..f3 are unchanged function f4(arg_object) { return arg_object.arg1 + arg_object.arg4 + arg_object.arg6; // line changed } 

What is it. For 4-level nested methods or for 10-level nested methods, you ONLY change 2 lines.

Which one works less for support?

+1
source

I think it all depends on the context of the function parameters themselves. If you rely on the elements of some thing, then I would pass a link to this thing as a parameter (whether it is a link / pointer to the interface of this object or a link / pointer to the definition of the object itself - these are implementation details).

If the parameter is not directly derived from the object, and there are a small number of parameters (five or less, maybe really up to you), I would pass atomic arguments.

If there is a potentially large number of arguments, then I would create some kind of init structure as a parameter, where the calling code creates an instance and populates the structure, and then passes a link to it as an argument.

0
source

Source: https://habr.com/ru/post/1334712/


All Articles