Hagamos una apuesta. Estoy seguro de que, cuando vea la clase a continuación, verá un problema con ella:
class Pedido {
public String comprador;
public double valorTotal;
// otros atributos
}
Si. ¡Los atributos son todos públicos! Esto va exactamente en contra de una de nuestras primeras lecciones cuando aprendimos Java: los atributos deben ser privados y necesitamos de getters y setters para accederlos. Así que hagamos este cambio en el código.
class Pedido {
private String comprador;
private double valorTotal;
// otros atributos
public String getComprador() { return comprador; }
public void setComprador(String comprador) { this.comprador = comprador; }
public double getValorTotal() { return valorTotal; }
public void setValorTotal(double valorTotal) { this.valorTotal = ValorTotal; }
// otros getters y setters
}
Es mejor ahora, ¿verdad? Todavía no. De hecho, perdemos el gran principio detrás de la idea de colocar atributos como privados. La forma en que la claseOrdenes
en ese momento, podemos hacer cosas como:
Pedido p = new Pedido();
// muda valor do pedido para 200 reais!
p.setValorTotal(p.getValorTotal() + 200.0);
Pero, ¿dónde está el problema? Imagínese otras 10 clases que hacen lo mismo: de alguna manera, manejan el monto total del pedido.
Leyenda: Pedido Clase 1 Clase 2 Clase 3 Clase N Todas manipulan valor Total
Ahora imagina que la regla de negocio del pedido cambia: cada ítem comprado gana un descuento del 5% si su valor excede los 1000 reales. Implementar este cambio no será una tarea fácil. Necesitaríamos hacerlo en diferentes clases del sistema.
Leyenda: Pedido Clase 1 Clase 2 Clase 3 Clase N ¡Se deberá hacer el cambio en todas!
¿Cuánto tiempo tardaremos para cambiar el sistema? No sabemos exactamente dónde realizar los cambios, ya que se distribuyen por el código. Este, por cierto, es uno de los grandes problemas de códigos legados: es necesario hacer un cambio simple en tantas clases y, en la práctica, siempre olvidamos algún punto y nuestro sistema a menudo falla.
La clase Pedido no fue bien diseñada. Dimos acceso directo al atributo valorTotal
, un atributo importante de la clase. Tenga en cuenta que el modificador private en este caso no sirvió de nada, ya que también le dimos un setter. Intentaremos disminuir el acceso al atributo, creando métodos más claros para la operación de depósito:
class Pedido {
private String comprador;
private double valorTotal;
// outros atributos
public String getComprador() { return comprador; }
public double getValorTotal() { return valorTotal; }
public void agrega(Item item) {
if(item.getValor() < 1000) this.valorTotal += item.getValor();
else this.valorTotal += item.getValor() * 0.95;
}
}
Ahora, para agregar un item al Pedido, haremos uso de este nuevo comportamiento:
Pedido p = new Pedido();
p.agrega(new Item("Ducha Eléctrica", 500.0));
Pero, ¿cuál es la diferencia entre los dos códigos siguientes?
Item item = new Item("Super Refrigerador", 1500.0);
// antiguo
if (item.getValor() > 1000) {
c1.setValorTotal(c1.getValorTotal() + item.getValor() * 0.95);
}
else {
c1.setValorTotal(c1.getValorTotal() + item.getValor());
}
// nuevo
c1.agrega(item);
Veamos que en la primera línea de código, sabemos exactamente CÓMO funciona agregar un nuevo item al pedido: debemos tomar el valor total y agregar el nuevo valor con un 5% de descuento si es mayor que 1000. En la segunda línea de código, no sabemos cómo funciona este proceso.
Cuando sabemos QUÉ hace un método (igual que el método agrega, sabemos que agrega un item al pedido, debido a su nombre), pero no sabemos exactamente cómo lo hace, ¡decimos que este comportamiento es encapsulado!
Desde el momento en que las otras clases no saben cómo la clase principal hace su trabajo, ¡significa que los cambios sólo se llevarán a cabo en un lugar! Después de todo, ¡están ocultos (encapsulados)!
Leyenda: ¡agrega () está encapsulado! Pedido Clase 1 Clase 2 Clase 3 Clase N ¡el cambio ahora ocurre sólo en el Pedido!
Es decir, para implementar la nueva regla de negocios, bastaría con modificar un solo lugar:
public void agrega(Item item) {
if (item.getValor() > 1000) this.valorTotal += item.getValor();
else this.valorTotal += item.getValor() * 0.95;
// nueva regla de negocio aquí
}
Al final, la verdadera utilidad de private
es ocultar el acceso de atributos a los que se debe acceder de forma más inteligente. Pero mira que es inútil poner todos los atributos como private y crear getters y setters para todos. Dejamos que la encapsulación "se filtre" de la misma manera.
Oculta los atributos, pero piensa en comportamientos inteligentes para acceder a ellos. ¡Una excelente manera de averiguar si el comportamiento está encapsulado es mirar el código que lo usa! Si logramos decir qué hace el método, pero sin decir cómo lo hace, ¡entonces podemos afirmar que el comportamiento está encapsulado!
A menudo dejamos pasar estos principios. Si deseas volver a visitar estas y otras buenas prácticas de Orientación a Objetos con los instructores de Alura, hay más publicaciones aquí. ¿Quieres practicar todo esto con vídeo clases, respuestas de los instructores y corrección de tus ejercicios? ¡Consulta nuestros cursos en línea de Java!
Puedes leer también:
Cursos de Programación, Front End, Data Science, Innovación y Gestión.
Luri es nuestra inteligencia artificial que resuelve dudas, da ejemplos prácticos y ayuda a profundizar aún más durante las clases. Puedes conversar con Luri hasta 100 mensajes por semana
Paga en moneda local en los siguientes países
Cursos de Programación, Front End, Data Science, Innovación y Gestión.
Luri es nuestra inteligencia artificial que resuelve dudas, da ejemplos prácticos y ayuda a profundizar aún más durante las clases. Puedes conversar con Luri hasta 100 mensajes por semana
Paga en moneda local en los siguientes países
Puedes realizar el pago de tus planes en moneda local en los siguientes países:
País | |||||||
---|---|---|---|---|---|---|---|
Plan Semestral |
487.37
BOB |
69018.45
CLP |
308114.50
COP |
65.90
USD |
264.97
PEN |
1441.56
MXN |
2978.57
UYU |
Plan Anual |
738.82
BOB |
104627.36
CLP |
467081.02
COP |
99.90
USD |
401.68
PEN |
2185.32
MXN |
4515.32
UYU |
Acceso a todos
los cursos
Estudia las 24 horas,
dónde y cuándo quieras
Nuevos cursos
cada semana