Código como:
public Thing[] getThings(){
return things;
}
No tiene mucho sentido, ya que su método de acceso no está haciendo nada más que devolver directamente la estructura de datos interna. Es lo mismo que simplemente declara Thing[] things
ser public
. La idea detrás de un método de acceso es crear una interfaz que aísle a los clientes de los cambios internos y les impida manipular la estructura de datos real, excepto en formas discretas, según lo permita la interfaz. Como descubrió cuando se rompió todo el código de su cliente, su método de acceso no lo hizo, es solo código desperdiciado. Creo que muchos programadores tienden a escribir código como ese porque aprendieron en alguna parte que todo debe encapsularse con métodos de acceso, pero eso es por las razones que expliqué. Hacerlo solo para "seguir la forma" cuando el método de acceso no sirve para nada es solo ruido.
Definitivamente recomendaría su solución propuesta, que cumple algunos de los objetivos más importantes de la encapsulación: brindar a los clientes una interfaz sólida y discreta que los aísle de los detalles de implementación internos de su clase y no les permita tocar la estructura de datos interna espere en las formas que usted decida que son apropiadas: "la ley del privilegio menos necesario". Si observa los grandes marcos de OOP populares, como el CLR, el STL, el VCL, el patrón que ha propuesto está muy extendido, exactamente por esa razón.
¿Deberías hacer eso siempre ? No necesariamente. Por ejemplo, si tiene clases auxiliares o de amigos que son esencialmente un componente de su clase principal de trabajo y no están "orientadas al frente", no es necesario, es una exageración que agregará una gran cantidad de código innecesario. Y en ese caso, no usaría ningún método de acceso, no tiene sentido, como se explicó. Simplemente declare la estructura de datos de una manera que esté limitada solo a la clase principal que la usa, la mayoría de los idiomas admiten formas de hacerlo friend
, o declarándola en el mismo archivo que la clase de trabajador principal, etc.
El único inconveniente que puedo ver en su propuesta es que es más trabajo codificar (y ahora tendrá que volver a codificar sus clases de consumidor, pero debe / debe hacerlo de todos modos). Pero eso no es realmente un inconveniente - necesitas hacerlo bien, y a veces eso requiere más trabajo.
Una de las cosas que hace que un buen programador sea bueno es que saben cuándo vale la pena el trabajo extra y cuándo no. A la larga, poner el extra ahora dará sus frutos con grandes dividendos en el futuro, si no en este proyecto, en otros. Aprenda a codificar de la manera correcta y use su mente al respecto, no solo siga los formularios prescritos robóticamente.
Tenga en cuenta que las colecciones más complejas que las matrices pueden requerir que la clase adjunta implemente incluso más de tres métodos solo para acceder a la estructura de datos interna.
Si está exponiendo una estructura de datos completa a través de una clase que contiene, en mi opinión, debe pensar por qué esa clase está encapsulada, si no es simplemente para proporcionar una interfaz más segura: una "clase de envoltura". Estás diciendo que la clase que contiene no existe para ese propósito, así que tal vez hay algo que no está bien en tu diseño. Considere dividir sus clases en módulos más discretos y superponerlos.
Una clase debe tener un propósito claro y discreto, y proporcionar una interfaz para admitir esa funcionalidad, nada más. Puede que estés tratando de agrupar cosas que no estén juntas. Cuando haces eso, las cosas se romperán cada vez que tengas que implementar un cambio. Cuanto más pequeñas y discretas sean sus clases, más fácil será cambiar las cosas: piense en LEGO.
get(index)
,add()
,size()
,remove(index)
, yremove(Object)
. Usando la técnica propuesta, la clase que contiene esta ArrayList debe tener cinco métodos públicos solo para delegar en la colección interna. Y el propósito de esta clase en el programa probablemente no sea encapsular esta ArrayList, sino más bien hacer otra cosa. ArrayList es solo un detalle. [...]