Quando si progetta un protocollo, è meglio per un metodo accettare un singolo oggetto di un tipo specifico o un array?

5

Attualmente sto progettando un protocollo per uso interno, quindi non fa una grande differenza in questo caso particolare, ma mi sono chiesto:

È meglio per un metodo accettare un singolo oggetto di un tipo specifico, o una matrice di oggetti, con la documentazione che specifica il tipo che conterrà? Ovviamente l'array consente una maggiore flessibilità nel chiamare il metodo, ma specificando un tipo offre al programmatore una maggiore chiarezza su ciò che il metodo farà.

Ad esempio, il mio protocollo ha un unico metodo (finora), chiamato recieveDroppedItems :. Deve accettare uno o più NSURL, che puntano ai file lasciati sul mittente.

Grazie in anticipo per qualsiasi consiglio che hai! : D

    
posta vilhalmer 02.05.2011 - 18:46
fonte

5 risposte

3

Non c'è una risposta generale alla tua domanda, ma lascia che ti fornisca un esempio per indicare alcuni principi che generalmente si applicano.

Nota: d'ora in poi parlerò di "interfacce" anziché di "protocolli", non solo perché è probabilmente il nome più comune in altre lingue, ma anche perché intendo davvero interfacce in un modo più astratto, come in " la definizione di come si possa interfacciare qualcosa con ".

Quando progettate un'interfaccia, dovreste progettarla come se non aveste alcun mezzo per implementarla da soli, ma dovreste affidarvi a qualcun altro, al quale sarete in grado di comunicare le vostre esigenze solo attraverso la vostra definizione.
Se si assume questo scenario, si vede che si desidera che l'interfaccia sia molto chiara (altrimenti l'implementazione potrebbe non essere progettata per fare ciò che si aspetta) e molto facile da implementare (altrimenti l'implementazione potrebbe non riuscire a fare ciò che si aspetta).

Ora, nel contesto in cui dipendi dal servizio estrapolato all'interfaccia che hai progettato, dovresti essere in grado di prendere diverse decisioni importanti, che non dovresti inoltrare al implementatore per non costringerlo a oltrepassare il singolo principio di responsabilità , né provocare la duplicazione del codice. Invece, è necessario prendere tali decisioni e trasmetterle nell'invocazione del metodo.
In questo esempio, potresti avere:

  • capito, se alcuni articoli possono essere elaborati in batch - supponendo che tu ti aspetti vantaggi nel farlo
  • è stato in grado di filtrare i duplicati, supponendo che il tuo sistema sia in grado di produrre tutti in primo luogo

E quindi (in entrambe le ipotesi) il tuo contratto con l'implementatore dovrebbe essere "devi essere in grado di elaborare un lotto di URL univoci".

Difficilmente puoi trasportare questo contratto senza ambiguità senza documentazione, ma puoi provare, ad esempio, con i nomi dei metodi. IMHO receiveDroppedItems non è molto espressivo, perché elemento è davvero ambiguo e ricevere è anche in una lingua basata sul passaggio di messaggi.
Lo chiamerei processDroppedURLs . Non è più lungo, ma dice davvero quello che dovrebbe succedere. Se mi viene chiesto di implementare un tale metodo, penso "Oh, ok, quindi mi aspetto che elabori una raccolta di URL abbandonati" (supponendo che io sappia cosa significa drop in quel contesto, so tutto Ho bisogno). Anche se il tipo della collezione potrebbe essere definito come qualcosa di vago come NSFastEnumeration , mi aspetterei che for...in produca NSURL s. Per quanto riguarda le informazioni sull'unicità, probabilmente lo metterei piuttosto nella documentazione, piuttosto che nel nome del metodo, perché non è così vitale.

Quindi riassumendo: vuoi interfacce chiare, concise, quasi minimaliste con nomi di metodi espressivi, che creino barriere di astrazione tra l'ambito client corrente e l'ambito del servizio astratto, che siano chiare e semplici da entrambi i lati.

    
risposta data 02.05.2011 - 21:47
fonte
4

Dipende dal sovraccarico di invio di un messaggio e da quanto puoi semplificare gestendo solo una notifica alla volta.

Se il sovraccarico è elevato (ad esempio, il protocollo di rete) ed è abbastanza facile gestire più notifiche (che potrebbero certamente essere il caso dell'invio di più URL contemporaneamente), è possibile consentire anche multipli.

Se hai un sovraccarico basso (ad esempio, si tratta di messaggi scambiati all'interno di una singola macchina) c'è una quantità di meno motivazione per unire i messaggi.

    
risposta data 02.05.2011 - 19:08
fonte
1

Odio dirti, ma dipende.

Un caso che ho visto nell'uso comune è il J2EE HttpServletRequest.getParameterList() . Restituisce un Map<String, String[]> . Essendo, alcuni elementi del modulo HTML, come le caselle di selezione, possono avere più valori. Oppure, ci sono più elementi con lo stesso nome ma valori diversi (probabilmente una cattiva programmazione, ma ci sono casi validi). In questo caso, i progettisti dell'API hanno deciso che i valori dei mutiple erano abbastanza comuni da giustificare la forzatura dell'array su tutte le chiamate.

Guarda i modi più comuni in cui verrà chiamata la tua API. Se stai ricevendo più valori per un sacco di volte, probabilmente vale la pena farlo. Un'altra opzione potrebbe avere due metodi: uno per un valore singolo e uno per più.

    
risposta data 02.05.2011 - 19:33
fonte
1

Il metodo potrebbe richiedere un elenco di argomenti a lunghezza variabile; quindi può accettare solo uno o più di un oggetto (senza la necessità di creare un array per tenerli).

    
risposta data 02.05.2011 - 19:47
fonte
-1

Dipende dalla lingua che stai usando perché alcune lingue non permetteranno matrici eterogenee, quindi a meno che le tue funzioni non accolgano solo elenchi di stringhe o elenchi di altre cose o ti piaccia lanciare in tutto il luogo l'unica opzione è specificare un prodotto digita e usa quello come input. Inoltre, in generale, i tipi espliciti per input e output sono best practice.

    
risposta data 02.05.2011 - 19:10
fonte