Is there a design standard or recommendation that defines the optimal amount of parameters a function should have?

Asked

Viewed 542 times

13

I always value writing my codes in a short and readable way. My motto is always to think that "someday someone will mess with my code and I want the person who does it to understand it easily". Thinking like this, I came to mind the question of parameters of functions.

What is the maximum of parameters I should use?

I say this because I, in particular, have an immense difficulty in using functions that contain more than 4 parameters - and, as a personal rule, if a function I am building ends up having more parameters than that, I redo it all, so as not to have that amount of parameters.

My dream was to know who was the [enlightened] person who had the brilliant idea to create the function imagecopyresampled() and chat with him!

This function has 10 parameters!

 bool imagecopyresampled ( resource $dst_image , resource $src_image , int $dst_x , int $dst_y , int $src_x , int $src_y , int $dst_w , int $dst_h , int $src_w , int $src_h )

That for me [and I think for many other programmers] doesn’t help at all. It would be very easy to confuse a parameter, or simply not know what each thing does, because it is easy to get lost.

I know the site doesn’t allow questions based on opinions, but is not my goal here to want to know the opinion about the amount of parameters that should be used, but if there is a Design Pattern or some Encoding Style Guide (like PHP PSR) that gives some good argument about how the number of parameters should be handled.

  • Is there any standard or recommendation regarding the optimal amount of parameters that can be used in a function?

  • Creating a function with many parameters would be a Anti-pattern?

  • 1
  • @Piovezan Vish, I don’t know if it’s related or duplicated now, huh!

  • Mine is object-oriented, yours seems not :)

  • @Piovezan but function and method are almost the same thing (I said almost). So I’m talking that it’s quite capable of being duplicated

  • 1

    @Wallacemaxters I do not consider as duplicate. Arguments passed via this changes the situation somewhat

4 answers

9


It doesn’t exist, and I’m going to say that anyone who says they do loses credibility with engineers "for real".

Book review

A book that I think people should read was quoted in the answers. But I’m afraid they will actually read it. If one is prepared to read, that is, to have a critical thinking, to understand scientific method, to already have the foundations of software engineering, which are pragmatic and neutral, not to mention to be able to interpret text properly and to understand the context of the book, that is not written in it, then reading it can give you ideas, provoke questions, suggest techniques, and can propose good things.

That goes for everything in life. I especially find the book disastrous in the hands of those who are unable to select what helps and what hinders them. And it’s a problem in what is not obvious. And obviousness depends on each one. Some consider that 17 lines of code is the maximum size a function should have. And don’t argue with the person. I can’t even imagine why it’s not 16, or 18, or 13, or 23.

Criticism of the state of society’s "thinking"

When someone says things that cannot be affirmed without saying that it is a joke, or that justifies deeply, what is almost always said to consider as a joke, distrust the author. Delivering something "concrete" works just as well as marketing. People like clear, straightforward answers, even if they’re fake. If that wasn’t the case fake news did not prosper (and people do not usually even know what it is fake news, most think it’s the literal translation). Validating what a person believes, and that’s easier when they have little basis on what they think, is very powerful. So much so that even those who have good philosophical basis fall into this.

Critique of the book idea

One of the mistakes you make is you don’t look at the context. The book does not have a clear context, but it has an implicit one, and the fact that you do not know easily is already an indication that you should distrust what is there. It depends on the type of code, the type of team, the type of technology used.

It has scenario that fits some criterion. But it does not fit in several others. What counts is the common sense. I think the book quote is interesting even in isolation. But only if you understand that this is a useful theory, not an always applicable practice. You have to look at the alternative. Is it a benefit or not?

Creating an object just to encapsulate parameters that are naturally parameters, and not parts of an object, is one of the stupidest ideas I’ve ever seen. Encapsulating data in a single object that makes sense to be together, and that this can be used in some places makes a lot of sense, in many cases.

Criticism of generic response

Nothing wrong with it, just think it was given an emphasis to the type of project and team without considering that even within a team or project has different needs at each time, at each point. The micro context should be considered more than anything else. To think that a team deciding how to do it is good, is interesting from a political point of view, but not from an engineering point of view (in some cases it does too), each shooting to one side is not good engineering. It just bothered me a little bit the last paragraph that treats the acceptable in a generic way. What is understandable that is done.

Criticism of the PHP response

The answer is not bad. I just don’t agree with her basic idea, far from being wrong. I’m not fascistic.

In general they do not do so in low ceremony languages, with naturally self-contained codes. Especially it makes no sense in PHP. And even if I did, I don’t see why I shouldn’t wear one array simple, even associative that only exists in that context. Creating a class just for that already tends to be bad in Java, in PHP even more.

Counterpoint

But Java has a justification. It is a language that values performance, and sending several parameters can be expensive. And the only way to create a heterogeneous structure to go through references is to create a class. Still, there will only be gains if you don’t create the object just for this, it will exist in a larger context within the application. It will never be a good idea to create the class just for this. Nor from an organizational point of view. This is complication and not simplification. People have lost sight of what’s simple.

In PHP without performance being a requirement and having another better mechanism makes even less sense.

It is a right of each author of what you want to transmit, but adapting Clean Code to PHP would be interesting if the adaptation had done almost everything backwards (I’m exaggerating a little here :) ).

Bringing software engineering from scratch

Curiously this done without criterion decreases cohesion and can increase coupling, and this is an old concept, much more than the book, this original idea that makes sense.

An interesting point to show that the citation in isolation is already flawed, is that this applies to functions or methods. Because with this whole accuracy of the ideal quantity, a difference parameter already changes a lot. Method has one more parameter that is not visible, it counts or not?

Continuing

I think the answer that was most voted on was rather sensitive in relation to this, it just lacked to justify a little more, so I decided to answer. If there are several authors saying different things is the show that has no ideal number.

My justification

Of course, a small number is interesting, no one can deny.

Some say that zero is not good, but this is fundamentalism, there are cases that communication requires it, it may be that it accesses external resources without needing any configuration, what would make a parameter be exaggerated because if it is only to configure the function, may be the case of separating the function into more than one, keeping as an abstraction for something larger within the DRY.

When there are too many parameters, it stinks. But what is bad depends on the context, even the smell of gas (which is artificially bad) is good because it does what it proposes. Smell is indicator, not proof.

Perhaps the cat’s answer shows something that deserves an object (not necessarily class), not because of the parameters, but because it is cohesive to be one thing, for every application. A well thought out would already have this object naturally, there is nothing to discuss. My criticism is to create abstraction without reason.

I know from experience that functions with more than 4 or 5 parameters usually have something wrong, but not all. I know that if you have many functions like this, with the same parameters it is usually something very wrong. But only usually.

One of the indications of many parameters is that the function has many responsibilities, so the solution is not to decrease the number of parameters is to separate the responsibilities. No use finding the problem, you have to find the right solution. Creating a class is not the only solution.

Answering the question more directly

Short form (1) and readable (2) is never write more code (1) and delegate to another location (2). We write more and in another place when needed, when it brings a greater advantage than the disadvantage it brings together.

Always someone will mess with your code, you for example. Few people have the ability to remember everything you’ve done after a while. I also criticize those who have this ability and use it as if everyone should have.

See? I have the same difficulty as the AP, the number is close to his, and little more than the book. But I’ve worked well with functions with 7 or more parameters. And where there were many the solution was not to create a class, because it did not solve any problem, it only remained a shorter stretch, anothers stayedm longests.

A much bigger problem with this function is that it uses little-readable names.

It has language that has named arguments to avoid the difficulty of understanding what is being passed. If the language doesn’t have is a shame, bad choice, but it still has comments, right? You can use /*argumentoX*/. It’s funny that nobody thinks of these things to solve the problems. It must be because it’s not in any cake recipe that’s out there.

I don’t know the context to talk more about the example shown in the question. It may be worth having some form for the coordinates. But I have doubts.

I don’t know if PHP has any official recommendations. In general these recommendations are silly and being PHP twist a little more the nose since very important things to have something clear and objective, has not.

Having many parameters is clearly a antipattern. Just don’t think they should ever be used or that a number will establish when it’s normal or not.

I didn’t even mention the fact that parameter is not the same as argument. And that there are cases that may have many parameters, but use even few arguments (in languages that have optional arguments).

  • I wouldn’t do it that way with a class, but in a scenario when you’re doing a database search, passing a class that represents a filter wouldn’t be bad, it could be an array, but I think that would be too subjective, And why would a PHP function with 5 or 6 parameters be bad? I just think 10 or more is too much ;)

  • So it depends a lot on the concrete scenario.

6

There are some recommendations in the literature. In Robert Martin’s Clean Code, there is a section that mentions this topic specifically (Chapter 3, Function Arguments section). There is a quote that is very similar to your perception:

The ideal number of Arguments for a Function is zero (niladic). Next comes one (monadic), Followed closely by two (Dyadic). Three Arguments (Triadic) should be avoided Where possible. More than three (polyadic) requires very special justification-and then shouldn’t be used anyway.

However, some other authors and developers do not agree with this approach and believe it to be very idealistic, because in many scenarios it is really difficult to reach a function that receives a smaller amount of parameters. To strictly follow this recommendation, it is often necessary to create data structures that will function as Wrappers for each function/method.

Knowing this, the most sensible thing to do would be to define what is the acceptable amount of parameters that will be used within your team/project specifically.

4

The best known recommendation of limit parameters is from the book Clean Code in which the Daniel quoted in his reply.

However, this perception is different among some authors and even among the tools of code analysis.

For example, considered one of the references in software development, the book Code Complete 2 Steve Mcconnell says the parameter limit is 7:

Limit the number of a routine’s Parameters to about seven

The Code Analysis Tool Sonarqube has a code problem in classes with more than 7 parameters in the constructor.

However, whether 3, 7 or 10, I understand that they are only one indicative that there is something wrong with your method or class, but not necessarily that the problem exists.

I believe that the worst indicative of having many parameters is that code executed within the method varies whether a parameter is passed or not. This brings extra complexity and concern to the method and, when we have many parameters, the chances are great that the method has this type of behavior.

But it is not always so if all parameters are used. Imagine a method like this:

public Pessoa criar(nome, sobrenome, idade, cpf, genero, profissao, 
    rua, cidade, estado, pais, cep);

We have 11 parameters, but there is not much doubt of what it does and the method has nothing complex, as it simply creates a person object based on the parameters passed. Of course it is possible to improve it:

public Pessoa criar(new Nome(nome, sobrenome), idade, cpf, genero, profissao, 
    new Endereco(rua, cidade, estado, pais, cep));

Decreasing to 6 parameters, and in both modes the method is consistent with its purpose and the complexity has not changed, only became a little more organized.

In the case of classes with many parameters, this problem can be particularly serious if we are talking about classes that take the concept of Service (service layer).

In the previous example I created a class Endereco that received 4 parameters, all of them being used and without additional complexity in their treatment. Simple and direct use of the parameters. But the service classes do not receive only data in their constructor, but other services (through dependency injection) that have other responsibilities. Classes of Service thus, with many dependencies of other classes of the same type, they are probably classes that are doing more than they should.

In my experience, service classes with more than 5 parameters are strong candidates for good refactoring, as they usually end up having several methods and not all of these methods use all available services and injected via class constructor. In a way, we have the same problem of methods with many functions: some constructor parameters end up being optional within the class depending on the method called within it.

2

There is this principle of the book Clean Code by Robert C. Martin, he was adapted for PHP by the community, not that people should follow to the letter, but have to consider the context and justification.

In my case, I always adopt to give more maintainability and testability, are two factors that are at the top to adopt some of these principles, soon after comes legibility.

Therefore, for the amount of parameters we have this example:

Bad approach

function createMenu(string $title, string $body, string $buttonText, bool $cancellable): void
{
    // ...
}

Good approach

class MenuConfig
{
    public $title;
    public $body;
    public $buttonText;
    public $cancellable = false;
}

$config = new MenuConfig();
$config->title = 'Foo';
$config->body = 'Bar';
$config->buttonText = 'Baz';
$config->cancellable = true;

function createMenu(MenuConfig $config): void
{
    // ...
}

The principle says that two arguments or less already this good, three is already a matter of rethinking its function and leave it with fewer vestments.

In the case of this function that you illustrated in the question, this above approach would already be sufficient to make it simpler, or divide into smaller functions.

  • 5

    Nothing against the answer, but when someone says that in PHP it is better to create a class than a simple function, just because of the number of parameters, definitely I discard immediately. Either the interpretation of what was written was misinterpreted, or who adapted does not understand or programming, (at least does not understand PHP)

  • 1

    @Bacco is complicated, in my case I prefer to divide the function because it is a sign that this doing too much, and so becomes more imperative.

  • 3

    Of course, each one has a way of using. I agree with the idea of rethinking the function yes, only "very suspicious" eye to the examples of good and bad approach, I would exchange the titles of position without C :P - Not that there is a rule, but that we can not generalize, does not give.

  • 1

    @Bacco would either make the two equal :P

  • 1

    @Bacco, if many parameters are bad and passing an object is unnecessary, an array (associative or not) would be a good intermediary?

  • 1

    @Guilhermecostamilam I think depends very much on the nature of the parameters. The problem with the array is that if it is positional, it is just a "disguise" for many parameters in the function. What can happen is that it is associative, so you can use the array as a way to handle many optional parameters. Ex: NewUser( $uniqueid, $username, $optionalfields ), and then pass 'name'=>'Jonas', 'telegram'=>'@jonasinexistentalias', 'born'=>'1997-03-27' on optionalfields. When you use array you are actually doing something intermediate to a function and a class creation, but quite punctually.

  • 1

    @Guilhermecostamilam I am more of the "many parameters are bad when they are sign of architecture with problems". The very function of the question example I think suffers from an ORDER problem of parameters, not quantity. She is very objective and in a call only does what is proposed, anything to "beautify" she would force to take more steps to get the result. I would probably just group things together in origin and destiny instead of intermingling.

  • I would choose to imagecopyresampled ( $source, $sx, $sy, $sw, $sh, $destination, $dx, $dy, $dw, $dh ), easy to "decorate" and in the Western natural sense (from left to right, first the source data and its parameters, followed by the destination and its parameters )

Show 3 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.