Articulo de referencia

Método en cascada

En la programación orientada a objetos , la cascada de métodos es una sintaxis que permite llamar a varios métodos sobre el mismo objeto. Esto se aplica especialmente en las int...

En la programación orientada a objetos , la cascada de métodos es una sintaxis que permite llamar a varios métodos sobre el mismo objeto. Esto se aplica especialmente en las interfaces fluidas .

Por ejemplo, en Dart , la cascada:

a .. b () .. c ();

es equivalente a las llamadas individuales:

a . b (); a . c ();

La cascada de métodos es mucho menos común que el encadenamiento de métodos ; solo se encuentra en un puñado de lenguajes orientados a objetos, mientras que el encadenamiento es muy común. Se puede implementar una forma de cascada utilizando el encadenamiento, pero esto restringe la interfaz; véase la comparación con el encadenamiento de métodos más adelante.

Solicitud

El uso de cascadas es una técnica sintáctica que elimina la necesidad de enumerar el objeto repetidamente. Esto se utiliza especialmente en interfaces fluidas , que presentan múltiples llamadas a métodos sobre un único objeto.

Esto resulta particularmente útil si el objeto es el valor de una expresión larga, ya que elimina la necesidad de enumerar la expresión repetidamente o de usar una variable temporal . Por ejemplo, en lugar de enumerar una expresión repetidamente:

a . b (). c (); a . b (). d ();

o utilizando una variable temporal:

n = a . b (); n . c (); n . d ();

La estructura en cascada permite escribir la expresión una sola vez y usarla repetidamente:

a . b ().. c () .. d ();

Comparación con el encadenamiento de métodos

Dada una llamada a un método a.b(), después de ejecutar la llamada, la cascada de métodos evalúa esta expresión en el objeto de la izquierdaa (con su nuevo valor, si ha sido modificado), mientras que el encadenamiento de métodos evalúa esta expresión en el objeto de la derecha .

Encadenamiento

La siguiente cadena (en C++):

a . b (). c ();

es equivalente a la forma simple:

b = a . b (); b . c ();
Cascada

La siguiente cascada (en Dart):

a .. b () .. c ();

es equivalente a la forma simple:

a . b (); a . c ();

La cascada se puede implementar en términos de encadenamiento, haciendo que los métodos devuelvan el objeto de destino (receptor, this) self. Sin embargo, esto requiere que el método ya esté implementado de esta manera, o que el objeto original esté envuelto en otro objeto que haga esto, y que el método no devuelva algún otro valor potencialmente útil (o nada si eso sería más apropiado, como en los setters). En las interfaces fluidas, esto a menudo significa que los setters devuelven esto en lugar de nada.

Idiomas

Pascal

Dentro de la instrucción `with`, los componentes (campos) de la variable de registro especificada por la cláusula `with` pueden denotarse únicamente por su identificador de campo, es decir, sin anteponerles la denotación de la variable de registro completa. La cláusula `with` abre efectivamente el ámbito que contiene los identificadores de campo de la variable de registro especificada, de modo que estos identificadores de campo pueden aparecer como identificadores de variable.

con fecha hacer si mes = 12 entonces comenzar mes := 1 ; año := año + 1 fin sino mes := mes + 1{ es equivalente a }Si fecha.mes = 12 , entonces comienza fecha.mes : = 1 ; fecha.año : = fecha.año + 1 , de lo contrario fecha.mes : = fecha.mes + 1

Charla informal

Las cadenas y cascadas de métodos se introdujeron en Smalltalk ; la mayoría de los lenguajes orientados a objetos posteriores han implementado cadenas, pero pocos han implementado cascadas. En Smalltalk, el operador punto y coma se puede usar para enviar diferentes mensajes al mismo objeto: [ 1 ]

self listPane parent color: Color black ; height: 17 ; width: 11

Compárese con declaraciones separadas, terminadas con un punto, que también utilizan una variable para la abreviatura:

| padre | padre := self listPane padre . color del padre : Color negro . altura del padre : 17 . ancho del padre : 11 .

Una sutileza es que el valor de una llamada a un método ("mensaje") en una cascada sigue siendo el valor ordinario del mensaje, no el receptor. Esto es un problema cuando se desea el valor del receptor, por ejemplo, al construir un valor complejo. Esto se puede solucionar enviando un yourselfmensaje que simplemente devuelva el receptor. [ 2 ] Por ejemplo, el método "agregar un objeto a una colección" ( Collection>>add: anObject) devuelve el objeto que se agregó, no la colección. Por lo tanto, para usar esto en una cascada en una instrucción de asignación, la cascada debe terminar con yourself, de lo contrario el valor será solo el último elemento agregado, no la colección en sí:

todos := ColecciónOrdenada nuevo agregar: 5 ; agregar: 7 ; tú mismo .

Tenga en cuenta que esto yourselfno es especial en Smalltalk: simplemente yourselfestá definido en la biblioteca estándar, por ejemplo, en una clase Objecto en algún lugar similar:

Objeto >> tú mismo ^ sí mismo

Esto contrasta con los de Smalltalk selfy super(y thisContext), que están definidos dentro del propio lenguaje y, por lo tanto, solo pueden ser reemplazados o alterados mediante un cambio en el compilador .

Visual Basic

Visual Basic utiliza esta Withinstrucción para habilitar un número arbitrario de llamadas a métodos o accesos a propiedades en el mismo objeto:

Con ExpressionThatReturnsAnObject . SomeFunction ( 42 ) . Property = value End With

With..End WithEn Visual Basic, los bloques se pueden anidar:

Con ExpressionThatReturnsAnObject . SomeFunction ( 42 ) . Property = value Con . SubObject . SubProperty = otherValue . AnotherMethod ( 42 ) Fin Con Fin Con

Dardo

Entre los lenguajes más recientes, Dart implementa cascadas, utilizando una operación de invocación de método en cascada con doble punto ... A diferencia de Smalltalk, en Dart el valor de una invocación de método en cascada es el receptor (objeto base), no el valor de la invocación de método (sin cascada), y por lo tanto no hay necesidad de yourself. Dart utiliza propiedades y, por lo tanto, en lugar de utilizar la sintaxis de método para los getters y setters ( foo.getBar(); foo.setBar(b);), utiliza la sintaxis de valor de campo/asignación ( foo.bar; foo.bar = b;), y las cascadas funcionan con asignaciones:

a .. cadena = '¡Hola mundo!' .. hecho = verdadero ;

es equivalente a:

a.string = ' ¡ Hola mundo ! ' ; a.done = true ;

Lisp y dialectos

La dotomacro integrada se puede usar en Clojure para llamar a varios métodos en el mismo objeto sin vincularlo a una variable, lo cual es útil principalmente para operar con objetos mutables del lenguaje anfitrión.

( doto ( java.util.ArrayList. ) ( .add 1 ) ( .add 3 ) ( println )) ​​;no se limita a métodos ;;; se expande a código equivalente a ( let [ l ( java.util.ArrayList. )] ( .add l 1 ) ( .add l 3 ) ( println l ) l ) ; la forma se evalúa a la primera entrada

Existen macros similares, o pueden definirse fácilmente, en otros lenguajes Lisp como Common Lisp .

Referencias

  1. Beck 1997 , "Cascada", págs. 183–185.
  2. Beck 1997 , "Yourself", págs. 186–188.
  • Beck, Kent (1997). Patrones de mejores prácticas de Smalltalk . Prentice Hall. ISBN 978-0134769042.
Dardo
  • " Cascadas de métodos en Dart ", Gilad Bracha, 17 de febrero de 2012
  • Hito 1 Cambios en el idioma , " Cascadas ", Bob Nystrom, julio de 2012 (actualizado en marzo de 2013)