¿Cuál es la diferencia entre "a" y "como" prefijos de nombre de método como
- Listar(),
- asList (),
- etc ...
¿Cuándo usar cuál al diseñar un método?
¿Cuál es la diferencia entre "a" y "como" prefijos de nombre de método como
¿Cuándo usar cuál al diseñar un método?
Respuestas:
Se toXYZ()
espera que una función realice una conversión y devuelva un nuevo objeto independiente (aunque la inmutabilidad permite la optimización, java.lang.String.toString()
solo devuelve el objeto).
Como ejemplo, en C ++ tenemos std::bitset::to_ulong()
que puede fallar fácilmente, y una gran cantidad de to_string()
todos haciendo una conversión (más o menos) compleja y asignando memoria.
Por asXYZ()
otro lado, se espera que una función devuelva una vista (potencialmente diferente) de la fuente, haciendo un trabajo mínimo.
Como ejemplo, en C ++ tenemos el std::as_const()
que solo devuelve una referencia constante, y el más involucrado std::forward_as_tuple
que también se refiere a sus argumentos por referencia.
std::to_string(x)
crea un nuevo objeto de cadena, pero std::as_const(x)
crea una referencia (una vista) del objeto existente.
Honestamente, puede ser solo nombrar inconsistencia. Si vistazo a los objetos de la biblioteca estándar en Smalltalk, por ejemplo, todos los métodos que hacen "conversiones complejas" o "retorno representaciones simples en otro tipo" se puede anteponer as
, como en asString
, asFloat
, asSeconds
, y el método estándar para convertir cualquier cosa a cualquier otra cosa, as: aClass
.
En Ruby, los mismos tipos de métodos tienen el prefijo to_
, como en to_s
, to_a
, to_h
, abreviatura de string
, array
y hash
respectivamente.
Ninguna de las bibliotecas estándar parece diferenciar entre diferentes tipos de conversiones, probablemente porque debería considerarse como un detalle de implementación.
Sin embargo, en Java vemos mucha confusión. Como usted ha mencionado, hay toString
, asList
y así sucesivamente. Creo que estos son solo una inconsistencia de nombres, porque si intenta definir un significado diferente para cada prefijo, siempre encontrará un contraejemplo en otro lugar de la biblioteca estándar.
En cualquier caso, diría que lo importante es que usted y su equipo elijan un prefijo y lo usen de manera consistente en todo el código. La consistencia es la clave, por lo que las personas no deben preguntarse, como tenía que hacerlo.
toString
crea una nueva cadena completamente desconectada del objeto (y no hay otra forma debido a la inmutabilidad). Lo mismo ocurre, por ejemplo, for Collection#toArray
, while Arrays#asList
devuelve una vista de la matriz, que está conectada bidireccionalmente (la mutación de la matriz cambia la lista y viceversa). Entonces, es bastante consistente, aunque puede haber excepciones. Elegir un prefijo estaría mal. Si lo hubiera Arrays#toList
, entonces esperaría que creara una nueva lista con una nueva matriz subyacente.
Si bien ya hay una respuesta aceptada, parece centrarse en C ++, mientras que la pregunta está etiquetada con Java . En Java, el primer ejemplo que viene a la mente para este tipo de cosas es Arrays.asList , que devuelve, esencialmente, una vista de una matriz, envuelta en una lista. Sin embargo, la matriz subyacente y la lista todavía están conectadas; los cambios en la matriz se reflejan en la lista y viceversa. Sin embargo, la matriz devuelta por el método toArray de la lista es independiente de la matriz original y de la lista:
String[] wordArray = {"one", "fine", "day"};
List<String> wordList = Arrays.asList(wordArray);
// changes to the array are visible in the list
System.out.println(wordList); // prints "[one, fine, day]"
wordArray[1] = "horrible";
System.out.println(wordList); // prints "[one, horrible, day]"
// changes to the list are visible in the array
wordList.set(1, "beautiful");
System.out.println(wordArray[1]); // prints "beautiful"
// but changes to the list or array don't affect the
// result from the list's toArray method.
String[] moreWords = wordList.toArray(new String[] {});
wordList.set(0, "the");
wordArray[1] = "best";
for (int i=0; i<3; i++) {
System.out.println(moreWords[i]); // prints "one", "beautiful", and "day"
}
Dicho todo esto, no hay garantía de que todos los desarrolladores de bibliotecas sigan esta convención, por lo que aún debe verificar la documentación para averiguar si este es el comportamiento que obtendrá de un código desconocido.
El otro lugar que he visto como ... () métodos utilizados con frecuencia es en la conversión de tipos a subtipos. Por ejemplo, si tiene un conjunto de subtipos enumerados, entonces podría terminar con un código como:
/**
* Every Node is either an ANode or a BNode.
*/
interface Node {
/**
* Returns this Node as an ANode.
*
* @return this node
*/
default ANode asANode() {
if (this instanceof ANode) {
return (ANode) this;
}
else {
throw new UnsupportedOperationException();
}
// Or, in Java8 style, perhaps:
// return Optional.of(this)
// .filter(ANode.class::isInstance)
// .map(ANode.class::cast)
// .orElseThrow(UnsupportedOperationException::new);
}
/**
* Returns this Node as a BNode.
*
* @return this node
*/
default BNode asBNode() {
if (this instanceof BNode) {
return (BNode) this;
}
else {
throw new UnsupportedOperationException();
}
}
}
La diferencia que noté (justo ahora al pensarlo) es
Entonces vemos AsInteger y AsString y vemos ToArray y ToStringList.
Implica una conversión, que tiene sentido (es un movimiento, un proceso). Como implica una representación, una forma de expresar el objeto original.
Otra forma de mirar esto:
Y luego hay que tratar con el "arte previo" (o legado). Antes de que los idiomas fueran completamente OO desde cero, tenía funciones de biblioteca como StrToInt () e IntToStr (). Realizaron conversiones, eran operaciones, por lo que tenía sentido llamarlos SomethingToSomethingelse (). Después de todo, To es más activo que As. Estoy particularmente pensando en Delphi aquí.
Cuando C # se diseñó con la ambición de ir OO hasta el final, tenía sentido tener un método en el objeto ahora entero que convertiría el entero en una cadena. Aunque también tenemos una clase Convert, la conversión a cadena es tan común que se hizo un método virtual en el objeto. Los diseñadores pueden haber pensado que ToString sería más familiar para las personas del viejo paradigma y quizás es por eso que obtuvimos un método virtual ToString () y no una propiedad virtual AsString.
toString()
?