Roque
Manuel Rueda Anastacio.
10/12/12
Índice
de contenido
Tabla de versiones
Versiones |
|||
Versión |
Fecha |
Autor |
Comentario |
0.1 |
10/12/2012 |
Roque Rueda |
Creado |
Objetivo
Ser
un apoyo fácil para incrementar acertar el mayor numero de preguntas
durante el desarrollo de entrevistas técnicas de desarrollo de
software.
Introducción
Este
documento proporciona un conjunto de conceptos y mi punto de vista
particular así como ejemplos para el apoyo durante las entrevistas
laborales para vacantes relacionadas con desarrollo de software. Se
realiza con la experiencia obtenida de entrevistas previas. En la
mayoría de las entrevistas de las que yo he sido parte; usualmente
se realizan las mismas cuestiones además, debido a que algunos de
los entrevistadores usualmente son desarrolladores de software,
tienen un conocimiento práctico en lenguajes sin embargo
sorprendentemente algunos de ellos pueden tener nociones equivocadas
de los conceptos más básicos.
1. Programación Orientada a Objetos
El
termino programación Orientada a Objetos, este termino que debiera
ser Análisis y Diseño Orientado a Objetos, se refiere a
tener una perspectiva de objetos (cosas, conceptos o entidades) para
el dominio del problema y su solución lógica. Ahora bien el dominio
del problema es la problemática que pretende solucionar (el problema
por el cual se debe desarrollar un producto de software) y la
solución lógica sera la especificaciones que debe cumplir el
sistema para solucionar la problemática. En un Análisis Orientado a
Objetos, los “objetos” son descritos en el dominio del problema,
mientras que en el Diseño esos “objetos” se convierten en
objetos lógicos de software que finalmente serán implementados en
un lenguaje orientado a objetos, por ejemplo Java o C#. La duda que
surge entonces ¿Qué es un Objeto? Un
objeto es una pieza de software que se ejecuta realizando operaciones
de un programa. Un objeto se define como una instancia de una clase
ya que la clase es la definición del los atributos y comportamiento
del objeto. Mientras que el objeto es en tiempo de ejecución el
elemento que realiza las acciones. Y eso no lleva a otra duda ¿Qué
es una clase? Una clase es un
documento (podemos decir código) que define como se menciona
anteriormente los objetos, podemos decir que es una orientación a
los datos ya que la clase define que datos contiene el objeto y que
operaciones puede realizar el objeto con los datos sin embargo esto
puede causar confusión. Una analogía es que la clase es el plano
arquitectónico y el objeto es la casa construida. Los siguientes
elementos son conceptos que intervienen en un diseño Orientado a
Objetos.
![]() |
Figura
1. Diagrama de un objeto
|
1.1. Encapsulamiento
El
encapsulamiento es la característica que un objeto tiene de ocultar
su información a los otros objetos, cualquier otro objeto solo se
puede acceder a los datos mediante la invocación de métodos. El
encapsulamiento brinda que los cambios en los datos de los objetos se
realicen de manera controlada y también dan la capacidad de ignorar
la implementación de las operaciones que realiza el objeto
centrándose solo en los valores resultado. Esto se podría
ejemplificar con un automóvil el cual al pisar el acelerador se
espera que incremente su velocidad el como sea llevada a cabo la
operación (motor, combustible, ignición), para el cliente de la
operación solo le interesa que se incremente la velocidad no como se
lleve a cabo ahí es donde el encapsulamiento resulta de utilidad.
1.2. Abstracción
Es
el proceso en el que los datos se definen para representar una imagen
o forma que permita obtener un significado que existe en el dominio
del problema, sin entrar a un nivel de implementación. La
abstracción permite descomponer la problemática en partes mas
pequeñas. Permitiéndonos dividir la implementación (como se
llevara a cabo) de la definición (que hay que llevar a cabo).
En
un lenguaje como Java una clase es la definición del comportamiento
y los datos. Una clase no se puede utilizar directamente. Un objeto
es la instancia de la clase y es el objeto el que realiza las
operaciones.
1.3 Polimorfismo
Es
la capacidad que tienen las variables de contener objetos de
diferentes clases, usualmente se dice que los objetos adquieren
diferentes formas sin embargo son las variables que los contienen las
que pueden adquirir valores de diversas clases. Si una clase Hijo
es una subclase de la clase Padre entonces
un método que espere un parámetro un objeto de clase Padre
también puede ser invocado con un parámetro de la clase Hijo.
El polimorfismo se da en lenguajes como Java o C# de 4 maneras la
clase padre, la interfaz que implementa, la clase Object y el mismo.
Ejemplo:
public interface Person{
void comer();
}
public class Padre
implements Person
{
public void saludar(String
nombre){
System.out.println(“Hola
desde padre: ” + nombre);
}
public void comer(){
System.out.prinln(“Comiendo
padre... c:”);
}
}
public class Hijo extends
Padre{
public String toString(){
// Metodo de la clase
Object
return “Hola soy un
hijo”;
}
}
/* Ejemplo de codigo */
public static void main
(String[] args){
// Digamos que queremos
crear un objeto Padre
Padre p = new Padre();
// Al existir herencia se
crea una relación es un (is a)
// por lo tanto se puede
decir que un Hijo es un Padre
p = new Hijo(); // se
asigna un hijo en una
// variable de tipo
Padre
p.saludar(“Roque”); //
p contiene un hijo
// ya que hereda los
metodos se puede invocar el metodo
// saludar de la clase
padre
Persona per = p; // Se
asigna la variable per de tipo
// Persona el valor
contenido en la varable p la cual
// apunta a un objeto de
tipo Hijo el cual es un Padre
// debemos recordar que
tambien al implementar la interfaz
// se obtiene la relacion
es un por lo que se puede decir
// que un Hijo tambien es
una Persona.
per.comer(); // Esto es
legal!
System.out.println(per); //
El metodo println espera un
// parametro de tipo Object
y ya que todo es un objeto
// esta es aceptada
Hijo h = (Hijo) per; //
Esto es riesgoso pero es legal
// la conversion hacia
arriba en la jerarquia de clases
// no requiere el cast
}
1.4. Herencia
Permite
que las clases sean basadas en otras. Si una clase “A” hereda de
otra clase llamada “B” se dice que la clase “A extiende a B”.
Por ejemplo se puede definir una clase base que almacene un archivo y
posteriormente esa clase sea extendida por otra clase para que se
notifique al usuario de un archivo almacenado (agregar nueva
funcionalidad).
1.5 Delegación
Delegación
es cuando cedes la responsabilidad de alguna tarea a otra clase o
método. Si se requiere utilizar esa funcionalidad en otra clase pero
no se quiere cambiar la funcionalidad se utiliza delegación en lugar
de herencia (se prefiere la agregación/composición a la
extensión/herencia).
1.6 Composición
La
composición se refiere a la representación de una familia de
comportamiento mediante un conjunto de objetos. Se programa
utilizando una interfaz y cualquier clase que implemente esta
interfaz podrá ser definida.
En
la composición los objetos que componen el objeto compuesto dejan de
existir tan pronto como el objeto compuesto lo haga.
1.7 Agregación
La
agregación permite invocar el comportamiento de otra clase sin la
limitacion de tiempo de vida de ese comportamiento. Se puede decir
que la agregación es cuando el comportamiento es invocado desde un
objeto pero este no deja de existir cuando el objeto es terminando.
Ejemplo: Salida estandar.
public class
Parte {
int sumar(int
numero, int otroNumero) {
return numero
+ otroNumero; // Sumar
}
}
public class
Composicion {
Parte parte;
Composicion()
{
parte = new
Parte();
}
void
imprimirSum(int numero, int otroNumero) {
System.out.println(parte.sumar(numero,
otroNumero));
}
}
/* Ejemplo de codigo */
public static
void main (String[] args) {
Composicion c
= new Composicion ();
c.imprimirSum();
// El objeto
parte deja de existir en cuanto el objeto
// composición
lo hace
}
// Agregación
public class
Parte2 {
int sumar2(int
numero, int otroNumero) {
return numero
+ otroNumero; // Sumar
}
}
public class
Agregacion {
Parte2 parte;
void
imprimirSum(int numero, int otroNumero) {
if(parte !=
null) {
System.out.println(parte.sumar(numero,
otroNumero));
}
}
public void
setParte(Parte2 parte) {
this.parte =
parte;
}
}
/* Ejemplo de codigo */
public static
void main (String[] args) {
Agregacion a =
new Agregacion ();
Parte2 p = new
Parte2 ();
a.setParte(p);
a.imprimirSum();
// El objeto
parte puede continuar existiendo después de su uso
}
2. Interfaces y clases Abstractas
Una
clase se compone de dos partes la interfaz y la implementación.
Entendemos por interfaz la definición (firma de métodos) y la
implementación como el código que realiza la ejecución de las
acciones. ¿Qué
beneficios se obtienen de las interfaces?
Un diseño por contratos, se dice por contratos ya que se asume que
ambas partes de la transacción comprenden que acciones generan que
comportamiento y cumplen ese contrato.
Una
interfaz permite generar un diseño por contratos, la diferencia
entre una clase abstracta y una interfaz es que una clase abstracta
puede contener implementación mientras que en una interfaz
unicamente se cuenta con la definición de la firma de los métodos.
Es por eso que en una clase abstracta existe herencia mientras que en
una interfaz solo existe implementación.
Un
sistema debe contar con una alta cohesión, la cohesión es la medida
en la que las clases están relacionadas y que tan centrada son las
responsabilidades de las clases. Un elemento es cohesivo a medida que
cambia el elemento entero cuando el sistema necesita cambiar. Un
diseño orientado a objetos es beneficioso el asignar
responsabilidades para obtener una cohesión alta. Por lo que se
deben evitar clases que tienen diferentes responsabilidades.
Dos
elemento están acoplados a medida en el que los cambios de una parte
involucran cambios en el otro elemento. El acoplamiento entre los
elemento es un conductor de los cambios.
Se
debe hablar solo a los amigos inmediatos.
Las
entidades de software como las clases, módulos y funciones deben ser
abiertos a extensiones pero cerrados a modificaciones. Este
principio nos indica que se debe crear código que pueda aceptar
nuevas extensiones sin que se deba modificar el código con el que ya
se cuenta.
Un
ejemplo es cuando una clase llama internamente a una clase abstracta
para obtener cierto comportamiento. En tiempo de ejecución se provee
de la implementación de la clase abstracta los que nos permite
posteriormente proporcionar una nueva implementación para obtener
nuevo comportamiento del código ya existente.