5

I'm currently designing a protocol for internal use, so it doesn't make a huge difference in this particular case, but it got me wondering:

Is it better for a method to accept a single object of a specific type, or an array of objects, with the documentation specifying the type it will contain? Obviously the array allows for greater flexibility in calling the method, but specifying a type gives the programmer greater clarity as to what the method will be doing.

For example, my protocol has a single method (so far), called recieveDroppedItems:. It needs to accept either one or multiple NSURLs, which point at the files dropped on the sender.

Thanks in advance for any advice you have! :D

asked May 2, 2011 at 16:46

4 Answers 4

3

There is no general answer to your question, but let me provide one to your example to point out some principles that generally apply.

Note: I shall henceforth speak of "interfaces" instead of "protocols", not only because it is arguably more common name for it in other languages, but also because I really mean interfaces in a more abstract way, as in "the definition of how something can be interfaced with".

When designing an interface, you should design it, as if you had no means to implement it yourself, but rather had to rely on somebody else, whom you will only be able to communicate your needs to through your definition.
If you assume this scenario, you see that you want an interface to be very clear (otherwise the implementation may not be designed to do what you expect) and very easy to implement (otherwise the implementation may fail to do what you expect).

Now in the context where you depend on the service abstracted to the interface you design, you should have been able to make several important decisions, that you shouldn't forward to the implementor to not force them to overstep the single responsibility principle, nor provoke code duplication. Instead, you need to make those decisions and convey them in your method invocation.
In this example, you might have:

  • figured out, whether some items can be processed in batch - assuming you expect any advantages in doing so
  • been able to filter out duplicates - assuming your system can produce any in the first place

And thus (under both assumptions) your contract with the implementor should be "you must be able to process a batch of unique URLs".

You can hardly transport this contract unambiguously without documentation, but you can try, for example by method names. IMHO receiveDroppedItems is not very expressive, because item is really ambiguous and receive also is in a language based on message passing.
I would call it processDroppedURLs. It's not longer, but it really says what's expected to happen. If I am asked to implement such a method, I think "Oh, ok, so I am expected to process a collection of dropped URLs" (assuming I know what dropped means in that context, I know all I need). Even though the collection's type might be defined to something as vague as NSFastEnumeration, I would expect for...in to yield NSURLs. As for the uniqueness information, I would probably rather put that into the documentation, rather than the method name, because it's not that vital.

So to summarize: You want clean, concise, almost minimalistic interfaces with expressive method names, that create abstraction barriers between the current client scope and the abstracted service scope, which are clear and simple from both sides.

answered May 2, 2011 at 19:47
2
  • Thanks for a very in-depth answer! Renaming the method to be more descriptive is a great idea. Commented May 3, 2011 at 16:25
  • +1: Careful naming (and renaming) is a great way to keep code both readable and maintainable. I would pick a good name over a good comment any time. Commented May 11, 2011 at 13:39
4

It depends on the overhead of sending a message, and how much you can simplify by handling only one notification at a time.

If you have high overhead (e.g., network protocol) and it's fairly easy to handle multiple notifications (which could certainly be the case in sending multiple URLs at once) then you might as well as allow multiples.

If you have low overhead (e.g., these are messages exchanged inside a single machine) there's a lot less motivation to coalesce messages.

answered May 2, 2011 at 17:08
1

Hate to tell you, but It Depends.

One case I've seen in common use is the J2EE HttpServletRequest.getParameterList(). It returns a Map<String, String[]>. Reason being, certain HTML form elements, like select boxes, can have multiple values. Or, there are multiple elements with the same name but different values (probably bad programming, but there are valid cases). In this case, the API designers decided that mutiple values were common enough to warrant forcing the array on all calls.

Look at the most common ways your API will be called. If you are getting multiple values a lot of the time, it's probably worth doing. Another option could be having two methods - one for a single value, and one for multiple.

answered May 2, 2011 at 17:33
1

The method could take a variable-length list of arguments; then it can accept just one, or more than on object (without the need to create an array to hold them).

answered May 2, 2011 at 17:47
1
  • This would be great, except I'm relying on performSelector: to call the method, and it only accepts a max of two arbitrary arguments. Although, I suppose I could use NSInvocation... Commented May 3, 2011 at 12:14

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.