Les avantages et les inconvénients de la méthode de chaînage et d'une possibilité de remplacer tous de retour void paramètres par l'objet lui-même
Je suis surtout intéressé à la Java, mais je pense que c'est une question d'ordre général. Récemment, j'ai travaillé avec Arquillian cadre (ShrinkWrap
) qui utilise beaucoup de chaînage de méthode. Autre exemple de chaînage de méthode sont des méthodes dans StringBuilder
, StringBuffer
. Il y a des avantages évidents de l'utilisation de cette approche: réduit le niveau de verbosité est l'un d'entre eux.
Maintenant, je me demandais, pourquoi ne pas toutes les méthodes qui ont void
paramètre de retour mis en œuvre comme chainable? Il doit être évident et objectif inconvénient dans le chaînage. Parce que si toutes les méthodes sont chainable, je peux encore choisir de ne pas l'utiliser.
Je ne suis pas demandant de modifier le code existant en Java, ce qui pourrait casser quelque chose quelque part, mais l'explication pourquoi n'était-il pas utilisé serait agréable aussi bien. Je me suis poser plus de questions à partir d'un futur cadre (écrit en Java) de conception de point de vue.
J'ai trouvé une question similaire, mais l'original asker est en train de me demander pourquoi il EST considéré comme une bonne pratique: Le chaînage de méthode - pourquoi est-il une bonne pratique, ou pas?
Alors qu'il ya des réponses disponibles, je ne suis toujours pas sûr de ce que sont tous les avantages et les inconvénients de chaînage et de savoir s'il serait utile d'avoir toutes les méthodes void chainable.
Vous devez vous connecter pour publier un commentaire.
Inconvénients
exemple, je ne vous attendez pas à être aussi une méthode mutateur. Par exemple, si
un vecteur a une échelle de méthode et si elle a un retour, je présume
elle renvoie un nouveau vecteur mis à l'échelle par l'entrée, si elle n'est pas le cas, alors je
s'attend à l'échelle interne.
Avantages
Il permet équation mathématique style de code à écrire plein d'équations sans la nécessité pour les multiples objets intermédiaires (conduisant à une surcharge inutile), par exemple, sans chaînage de méthode du vecteur triple cross du produit (comme un aléatoires exemple) doivent être écrits soit en tant que
qui a l'inconvénient de créer un objet intermédiaire qui doit être créé et les ordures collectées, ou
qui évite la création d'objets intermédiaires mais est profondément incertaine, le nom de la variable
tripleCrossProduct
est en fait un mensonge jusqu'à ce que la ligne 3. Toutefois, si vous avez de la méthode de chaînage de ce qui peut être écrit de façon concise dans des conditions normales manière mathématique sans créer d'inutiles objets intermédiaires.Tout cela suppose que vector1 est sacrificiel et n'aurez plus jamais besoin d'être utilisé de nouveau
Et bien sûr l'avantage évident; la brièveté. Même si vos activités ne sont pas liées au manoir de mon exemple ci-dessus, vous pouvez toujours éviter les références à l'objet
NB
MyVector3d
n'est pas utilisé comme une véritable classe de Java, mais est supposé effectuer la croix produit lorsque.multiply()
méthodes sont appelées..cross()
n'est pas utilisé, de sorte que l '"intention" est plus clair pour ceux qui ne connaissent pas du calcul vectorielNB Amit la solution a été la première réponse à l'utilisation de plusieurs lignes de la méthode de chaînage, je l'inclus dans le cadre de la quatrième puce pour l'exhaustivité
Chaînage de méthode est une façon de mettre en œuvre couramment interfaces, quel que soit le langage de programmation. Principal avantage de celui-ci (code lisible) vous dit exactement quand l'utiliser. Si il n'y a aucun besoin particulier pour le code lisible, mieux éviter de l'utiliser, à moins que l'API est naturellement conçu pour retourner le contexte ou l'objet comme un résultat de la méthode des appels.
Étape 1: Interface Fluide vs de Commande de Requête API
Interface fluide doit être examinée au regard de commande de requête de l'API. Pour mieux comprendre tout cela, permettez-moi d'écrire une balle-définition de la liste de la commande de requête API ci-dessous. En termes simples, c'est juste une norme orientée objet approche de codage:
Command
. La commande ne retourne pas de valeur.Query
. Requête ne pas modifier les données.À la suite de la commande de requête API vous donnera les avantages comme:
Étape 2: Interface Fluide sur le dessus de la Commande de Requête API
Mais la commande de requête API existe pour une raison, et en effet, se lit mieux. Alors comment pouvons-nous avoir les avantages des deux fluent interface et de commande de requête API?
Réponse: interface fluide doit être mis en œuvre sur le dessus de la commande de requête de l'API (par opposition au remplacement de la commande de requête API par l'interface fluide). Pensez à une interface fluide comme une façade de plus de la commande de requête de l'API. Et après tout, il est appelé couramment "interface" - un lisible ou commodité interface - dessus de la norme (commande de requête à l'API.
Habituellement, après la commande de requête API est prêt (écrit, probablement de l'unité testée, poli pour résoudre facilement), vous pouvez écrire couramment le logiciel de l'interface de la couche sur le dessus de cela. En d'autres termes, interface fluide, accomplit ses fonctions en utilisant la commande de requête de l'API. Ensuite, utilisez l'interface fluide (avec la méthode de chaînage) où vous voulez la commodité et la lisibilité. Cependant, une fois que vous voulez comprendre ce qui se passe réellement (par exemple, lors du débogage d'une exception), vous pouvez toujours vous plonger dans la commande de requête à l'API bon vieux code orienté objet.
L'inconvénient que j'ai trouvé de l'aide de la méthode de chaînage est de déboguer le code quand
NullPointerException
ou de tout autreException
qui se passe. Supposons que vous avez de code suivant:String test = "TestMethodChain";
test.substring(0,10).charAt(11); //This is just an example
Alors vous obtiendrez String index out of range: exception lors de l'exécution de code ci-dessus. Lorsque vous obtenez en temps réel des situations et de telles choses arrivent, puis vous obtenez à la ligne à laquelle l'erreur s'est passé, mais pas de quelle partie de enchaînés méthode qui l'a causé. Il doit donc être utilisées de façon judicieuse, où il sait que les données seront toujours venir ou les erreurs sont traitées correctement.
Ça a ses avantages aussi, comme vous n'a pas besoin d'écrire plusieurs lignes de code et l'utilisation de plusieurs variables.
De nombreux frameworks/outils à utiliser comme des Bulldozers et lorsque je l'ai utilisé pour déboguer le code, j'ai dû regarder à travers chaque partie de la chaîne de trouver ce qui a causé l'erreur.
Espère que cette aide.
Ce modèle est utile quand il s'agit de la série de mise à jour doit être faite sur le même objet et les opérations de mise à jour n'avez pas besoin de retourner tout état de mise à jour. Pour exemple, j'ai utilisé ce modèle dans certains api que j'ai écrit pour couche de base de données. Pour aller chercher quelques lignes en fonction de nombreux critères de nombreuses conditions doivent être ajoutées à la clause where. L'utilisation de ce modèle les critères peuvent être ajoutés comme suit.
En fin de compte, il améliore la lisibilité du code.
Comme vous pouvez le lire sur Interface fluide par Martin Fowler
Sommairement
la Commande de Requête de la Responsabilité de la Ségrégation (CQRS) principe de conception.
parle de ces opérations, pense à eux en tant interne DSLs
API et peuvent ne pas être en mesure de révéler l'intention du client/de la responsable de
le code
Si vous préférez immutabilité et de la programmation fonctionnelle, vous ne jamais revenir
void
.Une fonction sans valeur de retour n'est appelée que pour ses effets secondaires.
Bien sûr il y a des situations où ce n'est pas le cas, mais une fonction retournant
void
pourrait être considéré comme un indice de l'essayer d'une manière différente.Personnellement, je pense que c'est un très bon modèle, mais il ne devrait pas être utilisé partout. Considérons une situation où vous avez un
copyTo(T other)
méthode. Normalement, vous attendez qu'il ne retourne rien, mais si c'était pour retourner un objet de même type, dont l'objet attendez-vous? Ce type de problème peut être éclairci avec de la documentation, mais il est encore ambiguë sur la méthode signiature.Une somme de travail considérable. Surtout lorsque l'héritage est impliqué. Jetez un oeil à ce grand article sur le générateur de modèle
Il fait beaucoup de sens pour la mettre en œuvre lorsque vous vous attendez à ce que les clients feront appel à plusieurs méthodes sur la même instance de manière séquentielle par exemple, le générateur de modèle, des objets immuables, etc. Mais à mon avis, dans la plupart des cas, il n'est pas vraiment la peine l'effort supplémentaire.
Objets ont des attributs et des méthodes. Chaque méthode répond à une partie de l'objectif global de l'objet. Certains type de méthodes, comme les constructeurs et les getters et les setters, effectuez la gestion du cycle de vie des attributs et de l'objet lui-même. D'autres méthodes de retour à l'état de l'objet et ses attributs. Ces méthodes sont normalement non nulle.
Méthodes Void sont de deux types:
1. concernant la gestion du cycle de vie de l'objet ou les attributs.
2. ayant une sortie qui est entièrement géré à l'intérieur de la méthode et ne devrait pas provoquer un état de changement de n'importe où ailleurs.
ad 1. Ils appartiennent au fonctionnement interne de l'objet.
ad 2. Les informations de paramètres est utilisée pour exécuter un travail dans la méthode. Après la méthode a terminé il n'y a pas eu de modification de l'effet sur l'objet lui-même, ni sur le statut interne de l'un des paramètres.
Mais pourquoi devriez-vous faire une méthode retournant void et pourquoi pas, par exemple, une valeur de type boolean (succès ou pas)? La motivation pour une méthode de retour void (comme dans un setter), c'est que la méthode est censée avoir aucun effet secondaire. Renvoie true ou false pourrait être un effet secondaire. Nulle implique que la méthode n'a aucun effet secondaire lorsque la méthode est exécutée comme prévu. Un vide, une méthode retournant une exception est bon, parce qu'une exception n'est pas un effet secondaire du traitement normal d'une méthode.
Une méthode retournant void implique qu'il est par définition un cas isolé méthode de travail. Une chaîne de méthodes void est une chaîne de couplage lâche méthodes, parce qu'aucune autre méthode ne peut s'appuyer sur les résultats de son prédécesseur comme aucune méthode n'a aucun résultat. Il est un modèle de conception pour cela, à savoir la Chaîne de Responsabilité motif de conception. Le chaînage de différents enregistreurs est un exemple classique et l'appel à des filtres suivants au sein de la servlet api.
À la chaîne vide méthodes de manière significative implique que l'objet partagé, sur lequel ces méthodes de travail est après chaque étape dans un état qui est compréhensible par le vide de la méthode de travail sur l'objet. Tous les appels ultérieurs ne peut pas se fonder sur les résultats de son prédécesseur, ni influencer le travail de l'ensemble des appels après son propre appel. La meilleure façon vous pouvez vous assurer que est de ne pas les laisser modifier l'état interne de l'objet (comme l'enregistreur exemple), ou de permettre à chaque changement de méthode d'une autre partie de l'état interne de l'objet.
Méthodes Void être enchaîné sont, à mon avis, seules les méthodes qui ont la saveur de 2 et de partager un certain type de traitement. Je ne voudrais pas la chaîne vide méthodes concernant le cycle de vie de la classe, car chaque méthode est un changement d'une partie différente de l'ensemble de l'état de l'objet. La présence de ces méthodes peuvent changer avec le temps tout changement de conception de la classe, donc j'ai pas de conseil à la chaîne de ces méthodes. En outre, toutes les exceptions levées par le premier type de méthodes void indépendants les uns des autres, même si on peut s'attendre à ce que les exceptions levées par l'enchaînement des méthodes void de saveur 2 le partage d'un certain type de traitement ont quelque chose en commun.