Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Most API designers agree that you should avoid long argument lists if possible, e.g., Joshua Bloch (Effective Java) suggests that 5 or more is too many. Some ways to avoid this include:</p> <ol> <li><p>Create a struct to hold the arguments and pass that single struct to the function. This is often called a Plain Old Data (POD) type. You may want to add a helper function to create the structure that sets the default values (or if you're using Objective-C++ you could define a constructor for the struct to do the same). If you think the list of arguments may change over time and binary compatibility is important to you, you could add a version field and have the constructor set it appropriately. That way, your code can check the version number to know what fields are available.</p></li> <li><p>Pass a dictionary of values. This is effectively a data-driven API, where arguments and their values are passed in a structure that supports keys with arbitrarily-typed values. In C/C++ you'd have to create this structure yourself or use something like boost::any or Qt's QVariant. But, as you note, NSDictionary lets you hold objects of type id so you could use that. The nice thing about this is that changing the list of arguments doesn't break your interface - it's just up to the implementation to detect the new keys and support older keys. Though an implication of this is that your compiler won't catch incorrect keys for you - it's up to your code. The main downside is that just looking at your API doesn't tell a user what keys are supported so this approach must be supported by good documentation.</p></li> <li><p>Create an object and turn arguments into method calls. This has the benefit of being able to specify arguments in any order, to essentially name arguments, and to still handle optional arguments (by simply not calling a given method). Adding new parameters is also backward compatible as it resolves to adding a new function to the object.</p></li> <li><p>Building on 3., you could use the Named Parameter Idiom (NPI), where each function returns a pointer or reference to the object, thus allowing you to chain calls together. This option has all the benefits of 3. but also allows for more terse syntax, e.g., MyObject().setValue(100).setName("Hello").setEnabled(true);</p></li> </ol> <p>It sounds like you've considered most of these options already, so I'm probably not telling you anything new. For my own preference, I would tend more toward the NPI style as it avoids long parameter lists, is strongly-typed, names each argument, is backward compatible, and still offers a relatively compact syntax. It's more typing (for you) than the NSDictionary approach, but importantly it's easy for your users to use and it makes the set of supported 'arguments' obvious (and always correct) via your header files even without any documentation, unlike an NSDictionary solution.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload