2010-04-21 21 views
6

Aujourd'hui, je suis arrivé à un paradoxe fondamental du style de programmation objet, des types concrets ou des interfaces.Types de béton ou Interfaces pour les types de retour?

Quel est le meilleur choix pour le type de retour d'une méthode: un type concret ou une interface?

Dans la plupart des cas, j'ai tendance à utiliser des types de béton comme type de retour pour les méthodes. parce que je crois qu'un type de béton est plus flexible pour une utilisation ultérieure et expose plus de fonctionnalités.

Le côté obscur de ceci: Couplage. L'angélique: Un type concret contient en soi l'interface que vous alliez retourner au départ, et des fonctionnalités supplémentaires.

Quelle est la règle de votre pouce?

Existe-t-il un principe de programmation pour cela?


BONUS: Ceci est un exemple de ce que je veux dire ReadOnlyCollection or IEnumerable for exposing member collections?

Répondre

4

Mes règles empiriques:

1) Dans un premier temps, j'ai la méthode retourne le type d'interface, parce que son toujours facile de changer au type de béton plus tard si nécessaire. Plus difficile de revenir dans l'autre sens.

2) Même si la méthode est déclarée renvoyer le type de béton, je coderez les appelants d'utiliser le type d'interface lorsque cela est possible:
InterfaceType i = xyz.methodThatReturnsConcreteType();.

3) Que je possède le code d'appel fait une différence trop (interne vs API publiques):

  • Si je possède le code qui appelle la méthode en question (c.-à-API interne), le plus disposé Je dois retourner le type concret.
  • Si je ne contrôle pas le code qui appelle cette méthode (par exemple API publique), plus je suis susceptible de renvoyer le type d'interface à la place. Le retour du type de béton est un engagement et, d'une manière générale, moins je promets, plus c'est facile.

Autres considérations:

  • test peut être plus facile avec des interfaces que je peux utiliser un objet fantaisie qui implémente l'interface.
  • Il y a une petite chance que je voudrais revenir un proxy object (maintenant je suis atteint vraiment des excuses)

En résumé,

  • Je généralement retourne le type d'interface parce que je pense que les avantages du couplage libre l'emportent sur la commodité d'avoir un accès complet au type de béton.
  • Cependant, je ne suis pas opposé à la commutation à retourner le type de béton au cas par cas chaque fois que la commodité l'emporte sur les avantages de couplage lâche.
7

Règle générale, dans les types de retour, être un aussi précis que possible, dans les types de paramètres soit aussi non spécifique possible. Préférez aussi les interfaces, puisque vous pourrez éventuellement échanger votre implémentation si nécessaire, sans changer les clients de votre API.

+0

Merci pour votre avis Dominik +1 – SDReyes

+0

Un 'MyCustomExtendedArrayList' est plus spécifique que' List'. Que voulez-vous retourner? – BalusC

+2

@BalusC: Cela dépend si c'est juste une autre implémentation de List ou il offre quelques méthodes personnalisées. Quel sens cela donnerait-il de retourner une classe spécialisée, si elle ne peut être utilisée que par le casting? – Dominik

1

Question intéressante. Je crois que vous devez vous demander comment les données de retour peuvent être utilisées. Utilisation de l'analogie de voiture ancienne si vous en aviez

public AccelerationResponse PressAccelerator(float force) {} 

Il est probable que vous souhaitiez renvoyer une interface plutôt qu'une classe. Vous pourriez interpréter cette réponse différemment selon certaines conditions.

Si vous êtes certain que votre retour ne peut être utilisé que de la manière prévue par l'implémentation concrète, il est logique d'utiliser cette classe. Je ne suis pas sûr d'un principe largement accepté, mais ma règle générale est que si le type de retour peut être réutilisé dans différentes implémentations, une interface a plus de sens.

+0

Merci Jeremy, spécialement pour le "... si le type de retour peut être réutilisé dans différentes implémentations, une interface a plus de sens" partie +1 – SDReyes