Código limpio
bicentricApuntes11 de Diciembre de 2019
2.913 Palabras (12 Páginas)154 Visitas
6
Objetos y
estructuras de daios
Hay una razon para que las variables sean privadas. No queremos que nadie mas dependa de ellas. Queremos poder cambiar su tipo o implementaciOn cuando deseemos. Entonces, ipor que tantos programadores anaden automaticamente metodos de estable-
cimiento y recuperaciOn que muestran sus variables privadas como si fueran publicas?
Abstraccion de datos
Fijese en la diferencia entre los listados 6.1 y 6.2. Ambos representan los datos de un punto cartesiano, pero uno muestra su implementacion y otro la oculta totalmente.
Llstado 6.1. Punto concreto.
public class Point
public double x; public double y;
Llstado 6.2. Punto abstracto.
public interface Point (
double getX();
double getY();
void setCartesian(double x, double y); double getR();
126
•
Capitulo 6
double getTheta();
void setPolar(double r, double theta);
Lo mejor del listado 6.2 es que no hay forma de saber si la implementacien esta en coordenadas rectangulares o polares. iPuede que en ninguna! Y alin asi la in terfaz repre-
senta sin lugar a dudas una estructura de datos.
Pero representa algo mas que una estructura de datos. Los metodos refuerzan una politica de acceso. Puede leer las coordenadas de forma independiente pero debe esta-
blecerlas de forma conjunta como operaciOn atomica.
El listado 6.1, por su parte, se implementa claramente en coordenadas rectangulares y nos oblige a manipularlas de forma independiente, to que muestra la implementacion. De hecho, la mostraria igualmente aunque las variables fueran privadas y usaramos
metodos variables de establecimiento y recuperaci6n. Para ocultar la implementacien no basta con aiiadir una capa de funciones entre las variables. Se basa en la abstracci6n. Una clase no fuerza sus variables a travel de metodos de establecimiento y recuperacion. Por el contrario, muestra interfaces abstractas que permiten a sus usuarios manipular la esencia de los datos sin necesidad de conocer su implementacion.
Fijese en los listados 6.3 y 6.4. El primer° usa terminos concretos para indicar el nivel de combustible de un vehiculo mientras que el segundo lo hace con la abstraccion del porcentaje. En el caso concreto, podernos estar seguros de que se trata de metodos de acceso de variables. En el caso abstracto, desconocemos la forma de los dates.
Ustado 6.3. Vehiculo concreto.
public interface Vehicle
double getFuelTankCapacityInGallons();
double getGallonsOfGasoline(!:
Ustado 6.4. Vehiculo abstracto.
public interface Vehicle i
double getPercentFuelRemaining();
En ambos cases, la segunda opci6n es preferible. No queremos mostrar los detalles de los datos, sino expresarlos en terminos abstractos. Esto no se consigue simplemente mediante interfaces o metodos de establecimiento y recuperaci6n. Hay que meditar seria-
mente la forma optima de representar los datos que contiene un objeto. La peor opcion es anadir metodos de establecimiento y recuperacion a ciegas.
Antisimétrica de datos y objetos
Estos dos ejemplos ilustran la diferencia entre objetos y estructuras de dates. Los
objetos ocultan sus datos tras abstracciones y muestran funciones que operan en dichos
datos. La estructura de datos muestra sus datos y carece de funciones con significado.
Ohjetos y estructuras de dates 127
Vuelva a leerlos. Fíjese en la naturaleza complementaria de las dos definiciones. Son virtualmente opuestas. Puede parecer una diferencia menor, pero tiene importantes implicaciones.
Fíjese en el ejemplo del listado 6.5. La clase Geometry opera en las tres clases de formas, que son sencillas estructuras de datos sin comportamiento. Todo él comportamiento se encuentra en la clase Geometry.
Ustado B.S. Forma mediante procedimientos.
public class Square (
public Point topLeft; public double side;
public class Rectangle (
public Point topLeft; public double height; public double width;
public class Circle (
public Point center; public double radius;
public class Geometry {
public final double PI - 3.141592653589 93;
public double area(Object shape) throws NoSuchshapeException
if (shape instanceof Square)
Square s (Square)shape;
return s.side • s.side;
else if (shape instanceof Rectangle)
Rectangle r - (Rectangle)shape;
return r.height • r.width;
else if (shape instanceof Circle)
Circle c = (Circle)shape;
return PI . c.radius c.radius;
throw new NoSuchShapeException();
Los programadores orientados a objetos se quejarán de que es un ejemplo de procedimiento, y tienen razón. Imagine que pasaría si añadimos función perimeter () a Geometry. iLas clases de formas no se verian afectadas! iY las demas dases que depen-
dieran de las formas tampoco! Por otra parte, si ariado una nueva forma, tendrIa que cambiar todas las funciones de Geometry. Vuelvalo a leer. Comprobara que las dos condiciones son diametralmente opuestas.
1_3 Capftulo 6
Fijese ahora en la solucion orientada a objetos del listado 6.6. Aqui, el metodo area ( ) es polimorfico. No se necesita una lase Geometry. Por tanto, si arlado una nueva forma, ninguna de las funciones existentes se ven afectadas, pero si ariado otra funcion, habra que cambiar todas las formas'.
Llstado 6.6. Formas polimorficas.
public class Square implements Shape i
private Point topLeft;
private double side;
public double area() i
return side.side;
public class Rectangle implements Shape I
private Point topLeft;
private double height; private double width;
public double area() I
return height width;
• I
public class Circle implements Shape I
private Point center;
private double radius;
public final double PI - 3.141592653589793;
public double area()
return PI radius radius;
De nuevo, vemos la naturaleza complementaria de estas dos definiciones: totalmente contrarias. Esto ilustra la dicotomía fundamental entre objetos y estructuras de datos:
El código por procedimientos (el que usa estructuras de datos) facilita la inclusión de nuevas funciones sin modificar las estructuras de datos existentes. El código orientado a objetos, por su parte, facilita la inclusión de nuevas clases sin cambiar las funciones existentes.
El complemento también es cierto:
El código por procedimientos dificulta la inclusión de nuevas estructuras de datos ya que es necesario cambiar todas las funciones. El código orientado a objetos dificulta la inclusión de nuevas funciones ya que es necesario cambiar todas las clases.
...