Qual é a diferença entre os prefixos "to" e "as" do nome do método, como
- listar(),
- asList (),
- etc ...
Quando usar qual ao projetar um método?
A toXYZ()
função é esperado para fazer uma conversão, e para retornar uma nova independente objeto (embora imutabilidade permite a otimização, java.lang.String.toString()
apenas retorna o objeto).
Como exemplo, em C ++, temos o std::bitset::to_ulong()
que pode falhar facilmente e toda uma infinidade de to_string()
, todos fazendo uma conversão (mais ou menos) complexa e alocando memória.
Uma asXYZ()
função, por outro lado é esperado para retornar uma visão (potencialmente diferente) da fonte, fazendo o mínimo de trabalho.
Como exemplo, em C ++, temos o std::as_const()
que apenas retorna uma referência constante e o mais envolvido, std::forward_as_tuple
que também se refere a seus argumentos por referência.
std::to_string(x)
cria um novo objeto de seqüência de caracteres, masstd::as_const(x)
cria uma referência (uma exibição) do objeto existente.Honestamente, pode ser apenas nomear inconsistência. Se olhar para objetos de biblioteca padrão em Smalltalk, por exemplo, todos os métodos que fazem "conversões complexas" ou "retornar representações simples em outro tipo" são prefixados com
as
, como emasString
,asFloat
,asSeconds
, e o método padrão para converter qualquer coisa para qualquer outra coisa,as: aClass
.Em Ruby, os mesmos tipos de métodos têm o prefixo
to_
, como emto_s
,to_a
,to_h
, para curtostring
,array
ehash
respectivamente.Nenhuma das bibliotecas padrão parece diferenciar entre diferentes tipos de conversões, provavelmente porque deve ser considerada como um detalhe de implementação.
No entanto, em Java, vemos muitas confusões. Como você mencionou, há
toString
,asList
e assim por diante. Acredito que essas são apenas uma inconsistência de nomes, porque se você tentar definir um significado diferente para cada prefixo, sempre encontrará um contra-exemplo em algum outro lugar da biblioteca padrão.Portanto, em qualquer caso, eu diria que o importante é que você e sua equipe escolham um prefixo e o usem consistentemente em todo o código. A consistência é a chave, para que as pessoas não se perguntem como você precisava.
fonte
toString
cria uma nova string totalmente desconectada do objeto (e não há outra maneira por causa da imutabilidade). O mesmo vale, por exemplo, paraCollection#toArray
, enquantoArrays#asList
retorna uma visão da matriz, que é bidirecionalmente conectada (a mutação da matriz altera a lista e vice-versa). Portanto, é bastante consistente, embora possa haver exceções. Escolher um prefixo estaria errado. Se houvesseArrays#toList
, esperaria criar uma nova lista com uma nova matriz subjacente.Embora já exista uma resposta aceita, parece focar em C ++, enquanto a pergunta está marcada com java . Em Java, o primeiro exemplo que vem à mente para esse tipo de coisa é Arrays.asList , que retorna, essencialmente, uma visão de uma matriz, agrupada em uma lista. A matriz subjacente e a lista ainda estão conectadas; as alterações na matriz são refletidas na lista e vice-versa. No entanto, a matriz retornada pelo método toArray da lista é independente da matriz original e da lista:
Dito isso, não há garantia de que todos os desenvolvedores de bibliotecas sigam essa convenção; portanto, você ainda precisa verificar a documentação para descobrir se esse é o comportamento que você obterá do código desconhecido.
O outro lugar que eu vi como métodos ... () usado com freqüência é nos tipos de downcast para subtipos. Por exemplo, se você tiver um conjunto enumerado de subtipos, poderá acabar com um código como:
fonte
A diferença que notei (agora pensando nisso) é
Então, vemos AsInteger e AsString e ToArray e ToStringList.
Implica uma conversão, que faz sentido (é um movimento, um processo). Como implica uma representação, uma maneira de expressar o objeto original.
Outra maneira de olhar para isso:
E depois há "arte anterior" (ou legado) para lidar. Antes que os idiomas fossem totalmente OO desde o início, você teria funções de biblioteca como StrToInt () e IntToStr (). Eles realizaram conversões, eram operações, por isso fazia sentido chamá-los de SomethingToSomethingelse (). Afinal, To é mais ativo que As. Estou pensando particularmente em Delphi aqui.
Quando o C # foi projetado com a ambição de fazer OO até o fim, fazia sentido ter um método no objeto agora inteiro que converteria o número inteiro em uma string. Embora também tenhamos uma classe Convert, a conversão em string é tão comum que se tornou um método virtual no objeto. Os designers podem ter imaginado que o ToString seria mais familiar para as pessoas do antigo paradigma e talvez seja por isso que obtivemos um método virtual ToString () e não uma propriedade virtual AsString.
fonte
toString()
?