Código como:
public Thing[] getThings(){
return things;
}
Não faz muito sentido, pois seu método de acesso não está fazendo nada além de retornar diretamente a estrutura de dados interna. Você também pode simplesmente declarar Thing[] things
ser public
. A idéia por trás de um método de acesso é criar uma interface que isola os clientes de alterações internas e os impede de manipular a estrutura de dados real, exceto de maneiras discretas, conforme permitido pela interface. Como você descobriu quando todo o código do seu cliente quebrou, seu método de acesso não fez isso - é apenas um código desperdiçado. Eu acho que muitos programadores tendem a escrever código assim porque aprenderam em algum lugar que tudo precisa ser encapsulado com métodos de acesso - mas foi por isso que expliquei. Fazer isso apenas para "seguir a forma" quando o método de acesso não serve a nenhum propósito é apenas ruído.
Definitivamente, eu recomendaria sua solução proposta, que cumpre alguns dos objetivos mais importantes do encapsulamento: Oferecer aos clientes uma interface robusta e discreta que os isole dos detalhes de implementação interna da sua classe e não permita que eles toquem na estrutura de dados interna espere da maneira que você decidir ser apropriada - "a lei do privilégio menos necessário". Se você observar as grandes estruturas populares de OOP, como o CLR, o STL, o VCL, o padrão que você propôs é generalizado, exatamente por esse motivo.
Você sempre deve fazer isso? Não necessariamente. Por exemplo, se você tem classes auxiliares ou amigas que são essencialmente um componente da sua classe principal de trabalhadores e não são "voltadas para a frente", isso não é necessário - é um exagero que adicionará muito código desnecessário. E, nesse caso, eu não usaria um método de acesso - não faz sentido, conforme explicado. Apenas declare a estrutura de dados de uma maneira que tenha como escopo apenas a classe principal que a usa - a maioria dos idiomas suporta maneiras de fazer isso - friend
ou declare-a no mesmo arquivo da classe principal de trabalho, etc.
A única desvantagem que vejo na sua proposta é que é mais trabalhoso codificar (e agora você terá que re-codificar suas classes de consumidor - mas você precisa / teve que fazer isso de qualquer maneira.) Mas isso não é realmente uma desvantagem - você precisa fazer o que é certo, e às vezes isso exige mais trabalho.
Uma das coisas que torna um bom programador bom é que eles sabem quando o trabalho extra vale a pena e quando não vale. A longo prazo, colocar o extra agora renderá grandes dividendos no futuro - se não neste projeto, então em outros. Aprenda a codificar da maneira certa e use sua mente para isso, não apenas siga roboticamente os formulários prescritos.
Observe que coleções mais complexas que matrizes podem exigir que a classe envolvente implemente ainda mais de três métodos apenas para acessar a estrutura de dados interna.
Se você está expondo uma estrutura de dados inteira por meio de uma classe que contém, na IMO, é necessário pensar no porquê dessa classe ser encapsulada, se não for apenas para fornecer uma interface mais segura - uma "classe de wrapper". Você está dizendo que a classe que contém não existe para esse fim - então talvez haja algo errado no seu design. Considere dividir suas aulas em módulos mais discretos e colocá-los em camadas.
Uma classe deve ter um objetivo claro e discreto e fornecer uma interface para suportar essa funcionalidade - nada mais. Você pode estar tentando juntar coisas que não pertencem uma à outra. Quando você faz isso, as coisas vão quebrar toda vez que você precisa implementar uma mudança. Quanto menores e mais discretas forem suas aulas, mais fácil será mudar as coisas: pense em LEGO.
get(index)
,add()
,size()
,remove(index)
, eremove(Object)
. Usando a técnica proposta, a classe que contém esse ArrayList deve ter cinco métodos públicos apenas para delegar à coleção interna. E o objetivo dessa classe no programa provavelmente não está encapsulando esse ArrayList, mas fazendo outra coisa. O ArrayList é apenas um detalhe. [...]