Basta fazer assim
(this.negociacoes.list() as Array<Negociacao>).pop();
Neste caso para mim o tipo ReadonlyArray se torna inútil para encapsular uma propriedade. Apenas a clonagem via spread operator se mostrou eficaz.
Basta fazer assim
(this.negociacoes.list() as Array<Negociacao>).pop();
Neste caso para mim o tipo ReadonlyArray se torna inútil para encapsular uma propriedade. Apenas a clonagem via spread operator se mostrou eficaz.
Olá, Pedro, tudo bem?
Muito interessante a sua observação! Isso me fez pensar um pouco e elenquei vantagens e desvantagens de cada abordagem.
Como você pontuou, usando o spread operator nós garantimos que a referência do array não seja acessada. Porém, em NegociacaoController
, quando digitamos this.negociacoes.lista()
, mesmo que o pop()
não modifique o array privado negociacoes
da classe Negociacoes
, ele ainda aparece como sugestão no autocomplete.
Então há a possibilidade de um(a) desenvolvedor(a) com pouco conhecimento do projeto utilizar esse método e não entender porque não está funcionando.
Com essa abordagem, os métodos de escrita de arrays nem mesmo aparecem ou funcionam, então isso já pode ser uma dica para a pessoa que for trabalhar no projeto de que não podemos alterar esse array (além do tipo ReadonlyArray
ser semântico). Mas novamente, como você disse, nada impede a pessoa de escrever this.negociacoes.list() as Array<Negociacao>
, mas na minha visão, a pessoa que souber fazer isso deve ter mais conhecimento da linguagem e provavelmente sabe que é algo mais perigoso de se fazer.
Ainda assim, não é garantido que o array não possa ser modificado.
Elencados esses pontos, acredito que será uma escolha do(a) desenvolvedor(a) qual abordagem utilizar.
Espero ter ajudado! Abraços e bons estudos :)
Olá Antônio, ótimas pontuações.
Quando se trata de encapsulamento eu sempre gosto de pensar como se o desenvolvedor que for consumir minha função ou classe não pudesse ver o que acontece lá dentro. Eu posso estar escrevendo por exemplo uma biblioteca que será publicada.
Então partindo deste princípio pra mim a abordagem usando spread operator é a mais adequada para a maioria dos casos, pois assim o desenvolvedor do outro lado não conseguirá "quebrar" minha implementação.
E somando a sua sugestão de que o programador pode não ter muito conhecimento do projeto, talvez nomear o método de cloneLista()
em vez somente lista()
pudesse auxiliar.
Olá novamente, Pedro!
Na verdade acabei de ter uma ideia, nada nos impede de unir as duas abordagens! Assim:
lista(): ReadonlyArray<Negociacao> {
return [...this.negociacoes];
}
Assim, a propriedade privada negociacoes
não corre o risco de ser alterada, e os métodos de alteração do array também não serão sugeridos no autocomplete.
E somando a sua sugestão de que o programador pode não ter muito conhecimento do projeto, talvez nomear o método de cloneLista() em vez somente lista()pudesse auxiliar.
Essa também é uma ótima ideia, assim a pessoa terá uma dica melhor de porque os métodos de alteração não alteram o array original.
Bons estudos!