02-Java OO
02-Java OO
PRESENTACI0N
Java es un Lenguaje Orientado a Objetos, desde el primer programa, por más simple
que este sea, estarás implementado una clase; entre sus principales características
podemos mencionar:
▪ Seguro, porque elimina aspectos como los punteros, que pueden utilizarse para
acceder a secciones de la memoria no permitida.
A esto tenemos que agregarle una gran cantidad de librerías y recursos para
desarrollar todo tipo de aplicaciones, desde las más sencillas, como las de consola,
aplicaciones de entorno gráfico, y las más avanzadas, como componentes,
aplicaciones Web, aplicaciones móviles, aplicaciones distribuidas, etc.
La madures que ha alcanzado Java a lo largo del tiempo, lo hacen el lenguaje preferido
por empresas que realizan desarrollo serio, y en nuestro medio son cada vez más las
empresas que lo utilizan.
Para hacer Desarrollo Empresarial se aplica JDBC, Servlets, JSP, JSTL, EJB,
Patrones de Software, framework como Spring, etc.
INDICE
CAPÍTULO 1 INTRODUCCIÓN A GIT Y GITHUB .................................................................................................... 9
INTRODUCCIÓN ............................................................................................................................................ 30
BREVE HISTORIA ........................................................................................................................................... 31
¿QUÉ ES JAVA? .............................................................................................................................................. 33
¿QUÉ APLICACIONES HAY EN EL SDK? ............................................................................................................ 34
COMPILACIÓN: JAVAC ..................................................................................................................................... 35
EJECUCIÓN DE APLICACIONES: JAVA ............................................................................................................... 36
CONCEPTOS GENERALES ............................................................................................................................... 37
Comentarios ............................................................................................................................................. 37
Identificadores.......................................................................................................................................... 38
Palabras reservadas ................................................................................................................................. 38
Tipos de datos primitivos .......................................................................................................................... 39
DECLARACIONES DE VARIABLES .................................................................................................................... 41
CONSTANTES ................................................................................................................................................ 42
ASIGNACIONES ............................................................................................................................................. 43
STRINGS ........................................................................................................................................................ 45
OPERADORES ................................................................................................................................................ 47
ESTRUCTURAS DE CONTROL DE FLUJO .......................................................................................................... 48
Condicionales ........................................................................................................................................... 48
Bucles ....................................................................................................................................................... 50
EL MÉTODO MAIN........................................................................................................................................... 52
TRABAJANDO CON ARREGLOS ....................................................................................................................... 54
Definición ................................................................................................................................................. 54
Arreglos multidimensionales ..................................................................................................................... 56
CADENAS ...................................................................................................................................................... 58
Construcción de cadenas. ......................................................................................................................... 58
Concatenación .......................................................................................................................................... 59
Operaciones con cadenas ......................................................................................................................... 59
Arreglos de cadenas ................................................................................................................................. 63
Capítulo 1
Introducción a Git y GitHub
OBTENER EL SOFTWARE
Te recomiendo que instales GIT FOR WINDOWS, la ruta es la siguiente:
https://git-for-windows.github.io/
Git-2.6.1-64-bit.exe
Es posible que en este momento que estás leyendo este documento ya exista una
nueva versión.
PROCESO DE INSTALACIÓN
Durante el proceso de instalación debes integrarlo con la consola de Windows.
2. Ventana de licencia del software, solo debes hacer click en el botón Next.
COMANDOS INICIALES
Todos los comandos se deben ejecutar en la consola de Windows. Personalmente,
tengo una carpeta GitHub donde tengo todos mis repositorios que mantengo en
GitHub.
E:\GitHub>git
usage: git [--version] [--help] [-C <path>] [-c name=value]
[--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
[-p | --paginate | --no-pager] [--no-replace-objects] [--bare]
[--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
<command> [<args>]
E:\GitHub>git --version
git version 2.6.1.windows.1
Registra tu nombre
Es muy importante que registres tu nombre para saber quién o quienes estan
registrando cambios en el repositorio.
La sintaxis es la siguiente:
La sintaxis es la siguiente:
EDITAR REPOSITORIO
Crea un archivo
En la carpeta demo del repositorio procede a crear un archivo nuevo de nombre
info.txt, y registra información sobre información que registraras en tu repositorio.
git status
E:\GitHub\demo>git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: .gitignore
Untracked files:
(use "git add <file>..." to include in what will be committed)
info.txt
no changes added to commit (use "git add" and/or "git commit -a")
E:\GitHub\demo>git add .
Para confirmar la lista de archivos preparada con git add, se debe utilizar el comando
git commit.
E:\GitHub\demo>git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
(use "git push" to publish your local commits)
nothing to commit, working directory clean
En este caso indica que el repositorio está adelantado 1 commit con respecto a
repositorio origen, y se debe utilizar git push para subir los cambios.
Cuando ejecutas este comando te solicita tu cuenta de usuario y clave, salvo que ya
se encuentre configurado, como es mi caso.
E:\GitHub\demo>git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean
En estas situaciones debes usar el comando git pull para actualizar tu repositorio local.
El archivo que ha cambiado es info.txt, he indica que una fila se ha insertado, pero,
también una fila se ha eliminado, a continuación, tienes el script para consultar el
contenido del archivo info.txt:
E:\GitHub\demo>type info.txt
Este repositorio es demostrativo.
Sirve para ilustrar el uso de Git y GitHub.
Esto ha sido una introducción a Git y GitHub, suficiente para utilizarlo como repositorio
en los cursos de programación, pero si lo que necesitas es usarlo para control de
versiones te recomiendo que consultes el material oficial de Git.
Capítulo 2
FUNDAMENTOS DE JAVA
INTRODUCCIÓN
Java es un lenguaje de programación orientado a objetos desarrollado por SUN cuya
sintaxis está basada en C++, por lo que todos aquellos que estén acostumbrados a
trabajar en este lenguaje encontrarán que la migración a Java se produce de forma
sencilla y podrán verlo como su evolución natural: un lenguaje con toda la potencia de
C++ que elimina todas las estructuras que inducían a confusión y que aumentaban la
complejidad del código y que cumple todos los requerimientos actualmente del
paradigma de programación orientada a objetos.
BREVE HISTORIA
Java no surgió inicialmente como un lenguaje de programación orientado a la web.
Los orígenes se remontan al año 1991 cuando Mosaic (uno de los primeros browsers)
o la World Wide Web no eran más que meras ideas interesantes. Los ingenieros de
Sun Microsystems estaban desarrollando un lenguaje capaz de ejecutarse sobre
productos electrónicos de consumo tales como electrodomésticos.
incorporando nuevos elementos. Según Sun esta era la primera versión realmente
profesional. En mayo del 2000 se lanza la versión 1.3 del J2SE (Java 2 Standar
Edition), luego tenemos la versión 1.4, 1.5 (Java 5.0), 1.6 (Java 6), 1.7 (Java 7) y 1.8
(Java 8).
¿QUÉ ES JAVA?
COMPILACIÓN: javac
Para generar el archivo .class, que es el bytecode que recibe el entorno de ejecución,
se usa el compilador javac que recibe el código fuente en un archivo con extensión
.java. Para compilar una aplicación basta con compilar la clase principal, aquella
donde está el método main, y después de forma automática se va llamando para
compilar todas las clases que necesite. Estas clases deben ser accesibles a través de
la variable de entorno CLASSPATH.
/**
*
* @teacher Eric Gustavo Coronel Castillo
* @blog www.desarrollasoftware.com
* @email [email protected]
* @youtube www.youtube.com/DesarrollaSoftware
* @facebook www.facebook.com/groups/desarrollasoftware/
* @cursos gcoronelc.github.io
*/
public class HolaUNI {
public static void main(String[] args) {
System.out.println("Hola UNI!");
}
}
CONCEPTOS GENERALES
En Java todos los programas se construyen a partir de clases, dentro de esas clases
encontramos declaraciones de variables (instrucciones atómicas) y procedimientos o
funciones (conjuntos de instrucciones).
Comentarios
Los comentarios son cadenas de texto que el programa usa para entender y hacer
inteligible su código a otros. Los comentarios son ignorados por el compilador. Java
tiene tres tipos de comentarios como los que ilustraremos en el siguiente programa:
/**
*
* @teacher Eric Gustavo Coronel Castillo
* @blog www.desarrollasoftware.com
* @email [email protected]
* @youtube www.youtube.com/DesarrollaSoftware
* @facebook www.facebook.com/groups/desarrollasoftware/
* @cursos gcoronelc.github.io
*/
public class HolaUNI {
Identificadores
Los identificadores se usan para nombrar y referirnos a las entidades del lenguaje
Java, entidades tales como clases, variables o métodos. Java es sensible a la
diferenciación de mayúsculas y minúsculas, así pues una variable contador no es la
misma que otra Contador y pueden, aunque no sea aconsejable, coexistir sin
problemas. Un identificador tampoco puede ser igual a una palabra reservada.
Palabras reservadas
Las palabras reservadas por el lenguaje Java son las que se muestran a continuación.
Al final de este curso conoceremos el significado de la mayoría de ellas:
void var
▪ Enteros
▪ Caracteres: char
▪ Booleanos: boolean
DECLARACIONES DE VARIABLES
Una variable es una estructura que se referencia mediante un identificador que nos
sirve para almacenar los valores que usamos en nuestra aplicación. Para usar una
variable debemos declararla previamente de un tipo. Veamos algunos ejemplos:
boolean b;
int numero
float decimal=43.32e3f
int contador=0;
char c='a';
CONSTANTES
El concepto de constante no puede entenderse estrictamente en el paradigma de
orientación a objetos y por ello en Java no existen las constantes propiamente dichas.
Esto se explicará con más detalle cuando pasemos al capítulo de orientación a
objetos, por el momento diremos que lo más parecido que tenemos a una constante
es una variable de clase no modificable que se declara de la siguiente manera:
Por ejemplo:
ASIGNACIONES
El operador de asignación, como ya hemos visto en las inicializaciones de variables,
es el "=", por ejemplo:
bool javaEsGenial;
javaEsGenial=true;
int edad;
edad=22;
byte -> short -> int -> long -> float -> double
También puede hacerse en forma explícita cuando tiene que ser al revés mediante un
casting, siendo responsabilidad del programador la posible pérdida de información ya
que Java no producirá ningún error. Por ejemplo:
float radio;
radio = 5; // no es necesaria la conversión explícita de int a float
int perimetro;
perimetro = radio * 2 * PI; // error! no se puede guardar en un int
// el resultado de una operación con float
perimetro = (int) (radio * 2 * PI) // Ahora es correcto porque el
// casting fuerza la conversión
STRINGS
Ante todo, dejar claro que los strings no son tipos primitivos en Java. Son una clase
implementada en la biblioteca estándar, aunque con ciertas funcionalidades que
hacen que su uso sea comparable al de los tipos primitivos en ciertos aspectos.
Podemos declarar e inicializar strings como:
OPERADORES
Java define operadores aritméticos, relacionales, lógicos de manipulación de bits, de
conversión de tipo, de clase, de selección y de asignación. No debe preocuparse si
ahora no queda claro el significado de alguno de ellos
{
bloqueCuerpo
}
Condicionales
Permiten desviar el flujo de ejecución por una rama u otra dependiendo de la
evaluación de una condición. Existen dos estructuras condicionales, el if :
if (condición1)
{bloque1}
[else if (condición2)
{bloque2}
...]
[else
{bloqueN}]
Que puede tener una o más ramas que evalúen condiciones y opcionalmente un else
cuyo bloque se ejecutará sólo si no se ha cumplido ninguna de las condiciones
anteriores. Toda condición (en esta estructura y en adelante) debe evaluarse a un
valor booleano no pudiéndose utilizar valores enteros como en C/C++. La otra
estructura condicional es el switch que permite elegir un bloque en función del valor
de una variable de referencia:
switch (variableReferencia) {
case valor1:
{bloque1}
[case valor2:
{bloque2}
...]
[default:
{bloqueN}
]
}
variableReferencia sólo puede ser una expresión que evalúe a los tipos primitivos
enteros o char. Se evalúa la expresión y sucesivamente se va comprobando que
coincida con alguno de los valores, en caso de que así sea se ejecuta el bloque
correspondiente. Hay que tener en cuenta que la última instrucción de cada bloque
debe ser un break porque en caso contrario el flujo del programa seguiría por la
primera instrucción del siguiente bloque y así sucesivamente (esto puede ser útil en
alguna circunstancia, pero no es deseable generalmente). Si variableReferencia no
coincide con ninguna de los valores del case, se ejecutará, caso de existir, el bloque
correspondiente al default; en caso contrario, simplemente se seguiría con la próxima
instrucción después del switch.
Bucles
Los bucles son estructuras iterativas que ejecutan un cierto bucle mientras se da una
cierta condición. Java dispone de tres tipos de bucles. Tenemos en primer lugar el
while:
while (condicion){
bloque
Que ejecutará el código del bloque mientras condición se evalúe a cierto. La sentencia
do ..while:
do{
bloque
}while (condicion)
Es muy similar sólo que garantiza que el bloque se ejecutará al menos una vez, ya
que la evaluación de la condición se produce después de la ejecución del bloque.
Finalmente tenemos el clásico for:
for(inicializazion;condicion;incremento)
{
bloque
}
Que de forma análoga permite ejecutar un bloque mientras se da una cierta condición.
El for tiene de particular que la inicialización (generalmente un contador) y el
incremento queda encapsulado en la misma estructura. Es útil para recorrer
estructuras de datos secuenciales. La palabra reservada break en cualquiera de los
tres bucles fuerza la salida del bucle pasándose a ejecutar la siguiente instrucción
después del mismo. La sentencia continue fuerza el abandono de la iteración actual
haciendo que se ejecute la siguiente; también para todos los tipos de bucle.
EL MÉTODO main
El método main es la primera operación que se ejecuta en un programa Java, el que
se encarga de poner todo en marcha, y sólo puede haber uno. Su declaración es como
sigue: public static void main(String[]args) y siempre debe ser
exactamente así, ya que si modificamos (u olvidamos) alguno de los modificadores
Java no lo interpreta como el método main y cuando intentáramos ejecutar la
aplicación obtendríamos un error que precisamente nos diría esto más o menos: “no
puedo ejecutar el programa porque no existe un método main”. Como puede observar,
el método main siempre recibe un parámetro que es un array de String.
Este array contiene los parámetros que opcionalmente le hemos podido pasar por la
línea de comandos. ¿Qué significa esto? Habitualmente cuando ejecutamos un
programa lo hacemos de la siguiente manera:
En este caso hemos llamado a nuestra aplicación y le hemos pasado tres parámetros,
p1, p2 y p3, que se almacenan precisamente en el parámetro args del método main.
Para acceder a ellos nada más fácil que hacer:
Tener en cuenta que args es un array de String’s por lo que aunque nosotros pasemos
desde la línea de parámetros números, estos son interpretados como String y si
queremos el int, por ejemplo, correspondiente a esa representación tendremos que
aplicar el método de conversión adecuado.
Definición
Un arreglo es una colección de variables del mismo tipo. La longitud de un arreglo es
fija cuando se crea.
Se declara el arreglo
Inicialmente la variable referencia un valor nulo potencias-> null
int[] potencias; //forma más usada
int potencias[];
Se crea el arreglo
Se requiere la longitud del arreglo potencias-> 0
potencias = new int[4];
0
En caso de variables primitivas se inician en 0 o false. Las
primitivas no se pueden operar con el valor null. 0
En caso de variables referencia se inician en null. No 0
referencian a ningún objeto.
Los arreglos son muy usados para buscar datos, especialmente si se conocen sus
valores cuando se crean.
Arreglos multidimensionales
Se trata de arreglos de arreglos y se declara de la siguiente forma:
Ejemplo:
Definir una matriz de enteros colocando como valores la suma de su número de fila y
columna en la matriz:
{
int n= 10;
int p= 20;
double[][] m = new double[n][p];
for (int i= 0; i<n; i++)
for (int j= 0; j<p; j++)
m[i][j]= i+j;
}
CADENAS
Una cadena es una secuencia de caracteres. La librería String (o clase String) se usa
para definir todas las cadenas en Java. Las cadenas se delimitan con comillas dobles.
System.out.println("Hola Mundo.");
String camara = "Camara";
String luces = camara + " Accion";
String vacio = "";
Construcción de cadenas.
También se puede usar la siguiente sintaxis para construir cadenas.
Concatenación
Para concatenar cadenas puede usar lo siguiente:
// Usando el operador +
System.out.println(" Nombre = " + nombreDocente );
// 012345678901234567890123
String nombre = "Gustavo Coronel Castillo";
String subCadena = nombre.substring(8,15);
System.out.println(subCadena);
// 01234567890123456789012345
String blog = "www.desarrollasoftware.com";
int posicion1 = blog.indexOf("soft");
int posicion2 = blog.indexOf("r",7);
int posicion3 = blog.indexOf("t");
Arreglos de cadenas
Un arreglo de cadenas también sigue los pasos de creación de arreglos.
Capítulo 3
PROGRAMACIÓN
ORIENTADA A OBJETOS
UN NUEVO PARADIGMA
▪ OO es un nuevo paradigma de diseño y programación.
OBJETO
Definición
▪ Definición filosófica: Es una entidad que se puede reconocer.
Un Cliente tiene atributos, por ejemplo: nombre, dirección, crédito. Un Cliente tiene
comportamiento, por ejemplo: alquilar una película, pagar una factura, devolver una
película.
Encapsulamiento
El encapsulamiento oculta como las cosas funcionan dentro de un objeto. Solo nos
comunicamos con el objeto a través sus métodos. Los métodos son una interfaz que
permite ignorar como están implementados. No es posible evadir el encapsulamiento
en OO
Persona
getEdad
Cliente getNombre edad
o Mensaje getDireccion nombre
Transmisor getEdad() setEdad direccion
setNombre
setDireccion
Composición de objetos
Los objetos están compuestos de otros objetos. Los objetos son partes de otros
objetos. Esta relación entre objetos se conoce como Agregación o Composición,
según sea el caso.
CLASES
Una clase es un molde para crear objetos. Para definir una clase se tiene que indicar
las operaciones y atributos. Los objetos son instancias de la clase. Cuando se crea un
cajero automático no se requiere indicar sus operaciones y atributos.
cambiarDireccion() cambiarPrecio()
HERENCIA
Entre diferentes clases puede haber similitudes. La herencia es una relación entre
clases donde una es padre de otra. Las propiedades comunes definen la superclase.
Clase padre. Las subclases heredan estas propiedades. Clase hija. Un objeto de una
clase hija es un-tipo-de una superclase. Un Helicóptero es un tipo de Nave Aérea.
Dirigible
Helicóptero
Jumbo
Globo
POLIMORFISMO
Significa que la misma operación se realiza en diferentes tipos de objetos de diferente
forma. Estas operaciones tienen el mismo significado, comportamiento. Internamente
cada operación se realiza de diferente forma.
Abordar pasajeros
Tren Helicóptero
Barco
Definición de clase
Una clase es un molde para crear múltiples objetos que encapsulan datos y
comportamiento.
Paquetes
Un paquete es un contenedor (agrupador) de clases que están relacionadas
lógicamente. Un paquete tiene sus clases en un mismo directorio. Varias clases
pueden tener el mismo nombre, pero en diferente paquete.
Modificadores de acceso
Java controla el acceso a las variables y métodos a través de modificadores de acceso
como: private, public y protected. Un elemento público puede invocarse en cualquier
clase. Un elemento sin modificador solo se puede invocar desde el mismo paquete.
Un elemento protegido solo se invocar en clases heredadas. Un elemento privado no
puede ser invocado por otra clase.
Creación de objetos
Cada objeto es una instancia de alguna clase.
Pelicula
private String titulo;
Odisea 2001 El Padrino
private String tipo;
Public void mostrarDetalles() Ciencia Drama
public void obtenerTitulo() Ficcion
Drama
0 null
int i; i Pelicula pelicula1; pelicula1
3 Días de
Pelicula pelicula2;
int j = 3; j pelicula2 Radio
pelicula2 = new Pelicula();
La referencia null
Asignando referencias
Se puede asignar una variable referencia a otra, el resultado es dos referencias al
mismo objeto.
MÉTODOS
Definición
Los métodos definen el comportamiento de los objetos.
Argumentos
En la definición del método se indica el tipo y el nombre de los argumentos del método.
Valores de retorno
Se usa la sentencia return para salir del método retornando un valor. No se requiere
return si el tipo de retorno es void.
Invocando métodos
Se utiliza el operador punto para invocar el método de una clase, si el método es de
la misma clase, no se requiere el calificador de la clase.
Pelicula.java
PruebaPeliculas.java
ENCAPSULAMIENTO
Las variables de instancia de una clase deberían ser declaradas como privadas. Solo
un método debería acceder a las variables privadas. No se debe acceder a las
variables de instancia directamente, sino a través de un método.
/**
*
* @teacher Eric Gustavo Coronel Castillo
* @blog www.desarrollasoftware.com
* @email [email protected]
* @youtube www.youtube.com/DesarrollaSoftware
* @facebook www.facebook.com/groups/desarrollasoftware/
* @cursos gcoronelc.github.io
*/
public class Pelicula {
TestPrimitivas.java
/**
*
* @teacher Eric Gustavo Coronel Castillo
* @blog www.desarrollasoftware.com
* @email [email protected]
* @youtube www.youtube.com/DesarrollaSoftware
* @cursos gcoronelc.github.io
*/
public class TestPrimitivas {
run:
0
150
TestReferencias.java
/**
*
* @teacher Eric Gustavo Coronel Castillo
* @blog www.desarrollasoftware.com
* @email [email protected]
*/
public class TestReferencias {
run:
Drama
Terror
SOBRECARGA DE MÉTODOS
Algunos métodos en una clase pueden tener el mismo nombre. Estos métodos deben
contar con diferentes argumentos. El compilador decide que método invocar
comparando los argumentos. Se generará un error si los métodos solo varían en el
tipo de retorno.
Tipo Valor
char '0'
byte, short, int, long 0
boolean false
float, double 0.0
Referencia a Objeto null
CONSTRUCTORES
Para una adecuada iniciación de variables de instancia, la clase debe tener un
constructor. Un constructor se invoca automáticamente cuando se crea un objeto. Se
declaran de forma pública. Tiene el mismo nombre que la clase. No retorna ningún
valor. Si no se codifica un constructor, el compilador crea uno por defecto sin
argumentos que solo inicia las variables de instancia.
Pelicula.java
/**
*
* @teacher Eric Gustavo Coronel Castillo
* @blog www.desarrollasoftware.com
* @email [email protected]
* @youtube www.youtube.com/DesarrollaSoftware
* @facebook www.facebook.com/groups/desarrollasoftware/
* @cursos gcoronelc.github.io
*/
public class Pelicula {
public Pelicula() {
titulo = "Pelicula sin definir.";
}
TestConstructores.java
/**
*
* @teacher Eric Gustavo Coronel Castillo
* @blog www.desarrollasoftware.com
* @email [email protected]
*/
public class TestConstructores {
public static void main(String[] args) {
Pelicula pelicula1 = new Pelicula();
Pelicula pelicula2 = new Pelicula("La lista de Schindler.");
Pelicula pelicula3 = new Pelicula("El dormilon.", "Comedia");
System.out.println(pelicula1.getTitulo() + pelicula1.getTipo());
System.out.println(pelicula2.getTitulo() + pelicula2.getTipo());
System.out.println(pelicula3.getTitulo() + pelicula3.getTipo());
}
}
run:
Pelicula sin definir.Drama
La lista de Schindler.Drama
El dormilon.Comedia
La referencia: this
Los métodos de instancia reciben el argumento this implícitamente que se refiere al
mismo objeto.
/**
*
* @teacher Eric Gustavo Coronel Castillo
* @blog www.desarrollasoftware.com
* @email [email protected]
* @youtube www.youtube.com/DesarrollaSoftware
* @facebook www.facebook.com/groups/desarrollasoftware/
* @cursos gcoronelc.github.io
*/
public class Pelicula {
Pelicula.java
/**
*
* @teacher Eric Gustavo Coronel Castillo
* @blog www.desarrollasoftware.com
* @email [email protected]
* @youtube www.youtube.com/DesarrollaSoftware
* @facebook www.facebook.com/groups/desarrollasoftware/
* @cursos gcoronelc.github.io
*/
public class Pelicula {
public Pelicula(){
this("Pelicula sin definir");
}
TestThis.java
/**
*
* @teacher Eric Gustavo Coronel Castillo
* @blog www.desarrollasoftware.com
* @email [email protected]
*/
public class TestThis {
run:
Pelicula sin definir.
Todo sobre mi madre
VARIABLES DE CLASE
Las variables de clase comparten un único valor entre todas las instancias de la clase.
Se declaran con el calificador static.
/**
*
* @teacher Eric Gustavo Coronel Castillo
* @blog www.desarrollasoftware.com
* @email [email protected]
*/
public Class Pelicula {
/**
*
* @teacher Eric Gustavo Coronel Castillo
* @blog www.desarrollasoftware.com
* @email [email protected]
*/
public Class Pelicula {
// Iniciación explicita
private static double precioMinimo = 3.29;
MÉTODOS DE CLASE
Estos métodos son compartidos por todas las instancias. Se usan estos métodos
principalmente para manipular variables de clase. Se les declara con el calificador
static. Se invoca a este método de clase con el nombre de la clase o con el nombre
de una instancia.
HERENCIA Y POLIMORFISMO
Se estudia el uso de la herencia y el polimorfismo en el reúso de clases.
Herencia
Permite a una clase compartir la misma estructura de datos y comportamiento de otra
clase. La herencia minimiza la necesidad de duplicar código. El Polimorfismo permite
utilizar el método de acuerdo al objeto heredado.
Superclase Item
La herencia en Java
Una subclase se define indicando a que superclase extiende.
Una subclase hereda todas las variables instancia de la superclase. Las variables de
instancia deben ser private para que instancias de la subclase hereden sus valores.
La referencia super
Se refiere a la clase padre. Se usa para invocar constructores de la clase padre. Debe
ser la primera sentencia del constructor de la clase hijo. Esta referencia también se
usa para invocar cualquier método del padre.
Métodos
La superclase define los métodos para todas las subclases. La subclase puede
especificar métodos propios.
Item0.java
Pelicula0.java
TestSuper.java
La subclase hereda todos los métodos del padre. La subclase puede re-escribir un
método del padre.
Item1.java
Pelicula1.java
TestSobrescribir.java
}
}
La referencia super
Si una subclase sobrescribe un método de la superclase; el método de la superclase
se puede invocar con la referencia super.
Item2.java
Equipo2.java
TestSuper2.java
Polimorfismo
Permite efectuar una misma operación dependiendo del tipo de objeto.
Alquiler3.java
Item3.java
Pelicula3.java
Equipo3.java
Juego3.java
String fabricante;
if (fabricante.equals("Nintendo")) tasa = 1;
int importe = tasa*contrato.getDias();
return importe;
}
Libro3.java
TestPolimorfismo.java
testOperador(oscar);
testOperador(vhs);
testOperador(mu);
testOperador(agua);
}
Variables finales
Una variable final es una constante. Una variable final no puede ser modificada. Una
variable final debe ser iniciada. Una variable final por lo general es pública para que
pueda ser accesada externamente.
Métodos finales
Un método puede ser definida como final para evitar la sobreescritura en una
subclase. Un método final no se puede redefinir en una clase hijo.
if (password.equals(...
}
Clases finales
Una clase final no puede ser padre de otra clase. Una clase puede ser definida como
final para evitar la herencia. El compilador es más eficiente con definiciones final por
qué no buscara estas clases o métodos al tratar clases heredadas.
EL MÉTODO finalize()
Cuando todas las referencias de un objeto se pierden, se marcan para que el Garbage
Collector los recoja y libere ese espacio en memoria.
El objeto "Zelig" que estaba referenciado por pelicula ha perdido todas sus
referencias. Luego el Garbage Collector liberara el espacio ocupado por "Zelig". El
método finalize es llamado justo antes que el Garbage Collector libere la memoria. En
este instante se puede aprovechar para realizar otras operaciones.
Capítulo 4
CLASES ABSTRACTAS
E INTERFASES
Se estudiará el uso de clases abstractas, métodos abstractos, interfaces,
implementación de interfaces.
CLASES ABSTRACTAS
Clases abstractas
Sirven para modelar objetos de alto nivel, no contienen código, sino solo
declaraciones. Todos sus métodos deben existir en sus clases hijas. Una clase
abstracta no puede ser instanciada (Crear un objeto a partir de ella).
Métodos abstractos
Estos métodos son parte de clases abstractas. Un método abstracto debe ser
redefinido en las subclases. Cada subclase puede definir el método de manera
diferente. Las clases abstractas pueden contener métodos que no son abstractos,
estos son métodos concretos.
Item.java
/**
*
* @teacher Eric Gustavo Coronel Castillo
* @blog www.desarrollasoftware.com
* @email [email protected]
*/
public abstract class Item {
// Método abstracto
public abstract boolean esAlquilable();
// Método concreto
public float getPrecio() {
return precio;
}
Pelicula.java
/**
*
* @teacher Eric Gustavo Coronel Castillo
* @blog www.desarrollasoftware.com
* @email [email protected]
*/
public class Pelicula extends Item{
Libro.java
/**
*
* @teacher Eric Gustavo Coronel Castillo
* @blog www.desarrollasoftware.com
* @email [email protected]
*/
public class Libro extends Item {
Abstracto.java
/**
*
* @teacher Eric Gustavo Coronel Castillo
* @blog www.desarrollasoftware.com
* @email [email protected]
*/
public class Abstracto {
System.out.println("PELICULA");
System.out.println("Alquilable:" + pelicula.esAlquilable());
System.out.println("Precio:" + pelicula.getPrecio());
System.out.println("LIBRO");
System.out.println("Alquilable:" + libro.esAlquilable());
System.out.println("Precio:" + libro.getPrecio());
run:
PELICULA
Alquilable:true
Precio:5.0
LIBRO
Alquilable:false
Precio:0.0
INTERFACES
Una interface es totalmente abstracta; todos sus métodos son abstractos, sus
atributos son públicos estáticos y final. Una interface define los métodos que otras
clases pueden implementar, pero no provee ninguna línea de código. Una clase solo
puede heredar de una superclase. Una clase puede implementar muchas interfaces;
por lo que las interfaces permiten herencia múltiple.
Conducible
No Conducible
Las interfaces describen la conducta que requiere muchas clases. El nombre de una
interface por lo general es un adjetivo como Conducible, Ordenable, Ubicable.
Conducible.java
También se puede definir la interface sin los calificadores public static final
abstract, puesto que son implícitos. Para declarar que una clase implementa una
interface se usa implements.
Conducible.java
/**
*
* @teacher Eric Gustavo Coronel Castillo
* @blog www.desarrollasoftware.com
* @email [email protected]
*/
public interface Conducible {
// Girar a la izquierda
void girarIzquierda(int grados);
// Girar a la derecha
void girarDerecha(int grados);
NaveArea.java
/**
*
* @teacher Eric Gustavo Coronel Castillo
* @blog www.desarrollasoftware.com
* @email [email protected]
*/
public class NaveAerea {
Globo.java
/**
*
* @teacher Eric Gustavo Coronel Castillo
* @blog www.desarrollasoftware.com
* @email [email protected]
*/
public class Globo extends NaveAerea implements Conducible {
Patin.java
/**
*
* @teacher Eric Gustavo Coronel Castillo
* @blog www.desarrollasoftware.com
* @email [email protected]
*/
public class Patin implements Conducible {
TestInterface.java
/**
*
* @teacher Eric Gustavo Coronel Castillo
* @blog www.desarrollasoftware.com
* @email [email protected]
*/
public class TestInterface {
run:
GLOBO
Dirección: E
PATIN
Giro de 45 grados a la derecha
Capítulo 5
UTILIDADES
Se estudiará el uso de colecciones de objetos y una técnica de ordenación mediante
interfaces.
LA CLASE Object
Todas las clases en java heredan de la clase java.lang.Object. Los siguientes métodos
se heredan de la clase Object
http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html
Para cada dato primitivo java provee una clase para convertirlo en referencia y tratarlo
como un objeto y resolver los problemas previos.
/**
*
* @teacher Eric Gustavo Coronel Castillo
* @blog www.desarrollasoftware.com
* @email [email protected]
*/
public class PruebaReferencia {
Integer objetoPrecio;
objetoPrecio = new Integer(precio);
System.out.println("C.- " + objetoPrecio.toString());
System.out.println("D.- " + objetoPrecio);
System.out.println("E.- " + (objetoPrecio + 5));
System.out.println("F.- " + objetoPrecio.intValue());
System.out.println("G.- " + (objetoPrecio.intValue() + 5));
run:
A.- 0
B.- 7
C.- 2
D.- 2
E.- 7
F.- 2
G.- 7
▪ En la fila E, existe una conversión implícita del objeto objetoPrecio a int para
que pueda efectuarse la suma con el valor 2.
COLECCIONES
Es un conjunto librerías para manipular y almacenar datos. Estas librerías se llaman
colecciones.
Reto:
Arquitectura
Referencia:
https://docs.oracle.com/javase/tutorial/collections/intro/index.html
Interfaces de colecciones
La interface Collection
Añade el objeto en la colección
add(Object)
Añade la colección.
addAll(Collection)
La interface List
Colecciones ordenadas (secuencias) en las que cada elemento ocupa una posición
identificada por un índice. El primer índice es el 0. Las listas admiten duplicados.
La interface Map
Son pares de datos (clave, valor). No puede haber claves duplicadas y cada clave se
corresponde con al menos un valor.
Clases implementadas
El concepto de Polimorfismo aplica para todas las clases que implementan estas
interfases.
Producto.java
/**
*
* @teacher Eric Gustavo Coronel Castillo
* @blog www.desarrollasoftware.com
* @email [email protected]
*/
public class Producto {
public Producto() {
}
import java.util.ArrayList;
import java.util.Iterator;
/**
*
* @teacher Eric Gustavo Coronel Castillo
* @blog www.desarrollasoftware.com
* @email [email protected]
* @youtube www.youtube.com/DesarrollaSoftware
* @facebook www.facebook.com/groups/desarrollasoftware/
* @cursos gcoronelc.github.io
*/
public class MercadoLista {
// Se define un ArrayList
ArrayList lista = new ArrayList();
run:
Lista del mercado con 6 productos
colecciones.Producto@2a139a55
colecciones.Producto@15db9742
colecciones.Producto@6d06d69c
colecciones.Producto@7852e922
colecciones.Producto@4e25154f
colecciones.Producto@15db9742
Lista del mercado con 5 productos
Pan - 6
Carne - 2
Manzanas - 5
Brocoli - 2
Carne – 2
Objetos Duplicados
Debe notar que un objeto está duplicado, se está considerando dos veces.
Producto.java
/**
*
* @teacher Eric Gustavo Coronel Castillo
* @blog www.desarrollasoftware.com
* @email [email protected]
* @youtube www.youtube.com/DesarrollaSoftware
* @facebook www.facebook.com/groups/desarrollasoftware/
* @cursos gcoronelc.github.io
*/
public class Producto {
public Producto() {
}
@Override
public boolean equals(Object objeto) {
boolean rpta = false;
if (objeto != null) {
Producto producto = (Producto) objeto;
if (this.getNombre().equals(producto.getNombre())) {
return true;
}
}
return rpta;
}
@Override
public int hashCode() {
return this.getNombre().hashCode();
}
▪ Aun cuando se agregaron 6 elementos, la lista solo cuenta con 5. Set no permite
duplicados.
▪ Un Set no cuenta con índice, por lo que para eliminar un elemento se indica el
objeto.
MercadoHashSet.java
import java.util.HashSet;
import java.util.Iterator;
/**
*
* @teacher Eric Gustavo Coronel Castillo
* @blog www.desarrollasoftware.com
* @email [email protected]
*/
public class MercadoHashSet {
// Definir un HashSet
HashSet lista = new HashSet();
lista.add(pan);
lista.add(leche);
lista.add(manzanas);
lista.add(brocoli);
lista.add(carne);
lista.add(res);
run:
Lista del mercado con 5 productos
colecciones.Producto@6c2e9d68
colecciones.Producto@3ddf86b
colecciones.Producto@45e6467
colecciones.Producto@1387d
colecciones.Producto@c90fb9f
Lista del mercado con 4 productos
Brocoli - 2
Carne - 2
Leche - 2
Pan – 6
Lista del mercado con 0 productos
/**
*
* @teacher Eric Gustavo Coronel Castillo
* @blog www.desarrollasoftware.com
* @email [email protected]
*/
public class Producto implements Comparable {
public Producto() {
}
@Override
public boolean equals(Object objeto) {
boolean rpta = false;
if (objeto != null) {
Producto producto = (Producto) objeto;
if (this.getNombre().equals(producto.getNombre())) {
return true;
}
}
return rpta;
}
@Override
public int hashCode() {
return this.getNombre().hashCode();
}
@Override
public int compareTo(Object objeto) {
// Indica en base a que atributos se compara el objeto
// Devuelve +1 si this es > que objeto
// Devuelve -1 si this es < que objeto
// Devuelve 0 si son iguales
Producto producto = (Producto) objeto;
String nombreObjeto = producto.getNombre().toLowerCase();
String nombreThis = this.getNombre().toLowerCase();
return (nombreThis.compareTo(nombreObjeto));
}
MercadoTreeSet.java
import java.util.Collection;
import java.util.TreeSet;
/**
*
* @teacher Eric Gustavo Coronel Castillo
* @blog www.desarrollasoftware.com
* @email [email protected]
*/
public class MercadoTreeSet {
// Definir un TreeSet
TreeSet lista = new TreeSet();
lista.add(pan);
lista.add(leche);
lista.add(manzanas);
lista.add(brocoli);
lista.add(carne);
lista.add(res);
lista.remove(manzanas);
mostrarLista(lista);
run:
Lista del mercado con 5 productos
Brocoli - 2
Carne - 2
Leche - 2
Manzanas - 5
Pan - 6
Lista del mercado con 4 productos
Brocoli - 2
Carne - 2
Leche - 2
Pan - 6
Lista del mercado con 0 productos
Producto.java
/**
*
* @teacher Eric Gustavo Coronel Castillo
* @blog www.desarrollasoftware.com
* @email [email protected]
*/
public class Producto implements Comparable {
public Producto() {
}
@Override
public boolean equals(Object objeto) {
boolean rpta = false;
if (objeto != null) {
Producto producto = (Producto) objeto;
if (this.getNombre().equals(producto.getNombre())) {
return true;
}
}
return rpta;
}
@Override
public int hashCode() {
return this.getNombre().hashCode();
}
@Override
public int compareTo(Object objeto) {
// Indica en base a que atributos se compara el objeto
// Devuelve +1 si this es > que objeto
// Devuelve -1 si this es < que objeto
// Devuelve 0 si son iguales
MercadoCollections.java
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
/**
*
* @teacher Eric Gustavo Coronel Castillo
* @blog www.desarrollasoftware.com
* @email [email protected]
*/
public class MercadoCollections {
// Definir un ArrayList
ArrayList lista = new ArrayList();
run:
Lista del mercado con 5 productos
0.- Pan|6
1.- Carne|2
2.- Leche|2
3.- Manzanas|5
4.- Brocoli|2
Lista del mercado con 5 productos
0.- Brocoli|2
1.- Carne|2
2.- Leche|2
3.- Manzanas|5
4.- Pan|6
Pan es el elemento 4
Ejemplo de HashMap
AgendaHashMap.java
import java.util.HashMap;
import java.util.Map;
/**
*
* @teacher Eric Gustavo Coronel Castillo
* @blog www.desarrollasoftware.com
* @email [email protected]
*/
public class AgendaHashMap {
run:
Ejemplo de TreeMap
AgendaTreeMap.java
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
/**
*
* @teacher Eric Gustavo Coronel Castillo
* @blog www.desarrollasoftware.com
* @email [email protected]
*/
public class AgendaTreeMap {
// Definir un TreeMap
TreeMap<String, String> agenda = new TreeMap();
run:
Doctor : (+52)-4000-5000
Hermano : (575)-2042-3233
Capítulo 6
MANEJO DE EXCEPCIONES.
¿QUÉ ES UN ERROR?
En java es cuando la situación es irrecuperable y termina el programa.
¿CUÁL ES LA DIFERENCIA?
Una excepción se puede controlar en el programa. Un error no.
CARACTERÍSTICAS DE JAVA
Cuando ocurre una excepción en un método, Java lanza (throw) una excepcion
(Exception).
Java separa los detalles del manejo de errores del código principal, obteniéndose un
código más legible y menos propenso a errores de codificación.
EXCEPCIONES
Devolviendo la excepción hasta el manejador de excepciones. No se requiere que
cada método invocado maneje la excepción, sino únicamente lo hará el primer
manejador de excepciones de la lista de métodos invocados.
M etodo1 M etodo1
M anejo d e erro res M anejo d e excepciones
Código de error
M etodo2 M etodo2
Código de error
M etodo3 M etodo3
Código de error
E xcepcion
M etodo4 M etodo4
M etodo1 M etodo1
M anejo d e erro res M anejo d e excepciones
M etodo2 M etodo2
M etodo3 M etodo3
Código de error
E xcepcion
M etodo4 M etodo4
Throwable
Todos los errores y excepciones heredan de la clase Throwable
Thro wa ble
E rro r E xception
Errores
Heredan de la clase Error; estos se generan cuando ocurren errores fatales para el
programa como, por ejemplo: cuando la memoria está llena o cuando es imposible
encontrar una clase requerida.
Excepciones no controladas
Heredan de la clase RuntimeException. Estas ocurren cuando por ejemplo se divide
entre cero o se intenta acceder a un elemento del arreglo fuera de sus límites.
Mediante código se puede capturar, manipular o ignorar estas excepciones. Si no
maneja el error, java terminara el programa indicando el estado del error.
Excepciones controladas
Heredan de la clase Exception. Estas deben ser capturadas y manejadas en algún
lugar de la aplicación. Las excepciones creadas por el programador serán heredadas
de la clase Exception.
EXCEPCIONES NO CONTROLADAS
No necesitan ser controladas en el código.
La documentación del java indicara que excepciones lanza los métodos del java.
Clase : java.io.FileInputStream
Método: public FileInputStream(String name) throws FileNotFoundException
Método: public int read() throws IOException
int cantidad;
String cadena = "5";
try {
cantidad = Integer.parseInt(cadena);
}
catch ( NumberFormatException e) {
System.err.println(cadena + " no es un entero");
}
/**
*
* @teacher Eric Gustavo Coronel Castillo
* @blog www.desarrollasoftware.com
* @email [email protected]
*/
public class TestMultiException {
run:
5
Error en 5/0
Reto:
/**
*
* @teacher Eric Gustavo Coronel Castillo
* @blog www.desarrollasoftware.com
* @email [email protected]
*/
public class TestFinally {
run:
Se trabajó con 5 y 0
Reto:
TestThrows.java
/**
*
* @teacher Eric Gustavo Coronel Castillo
* @blog www.desarrollasoftware.com
* @email [email protected]
*/
public class TestThrows {
run:
Error en abcde 6
Reto:
UserFileException.java
/**
*
* @teacher Eric Gustavo Coronel Castillo
* @blog www.desarrollasoftware.com
* @email [email protected]
*/
public class UserFileException extends Exception {
/**
*
* @teacher Eric Gustavo Coronel Castillo
* @blog www.desarrollasoftware.com
* @email [email protected]
*/
public void ReadUserFile throws UserFileException {
try {
// Código que manipula un archivo
}
catch (IOException e) {
throw new UserFileException(e.toString());
}
Capítulo 7
Buenas Prácticas
PROGRAMACIÓN EN CAPAS
Introducción
Cuando se construye software como producto empresarial o comercial, se llevan a
cabo varias técnicas de manera que el desarrollo se haga en forma ordenada y así
poder asegurar un avance continúo del proyecto, un producto final de calidad, y
además realizar posteriores mejoras sea una tarea más fácil.
Una de las más utilizadas se llama la programación por capas, que consiste en dividir
el código fuente según su funcionalidad principal.
ser dividida la aplicación general en varios módulos y capas que pueden ser tratados
de manera independiente y hasta en forma paralela.
Por otra parte, otra característica importante de recalcar es la facilidad para las
actualizaciones de la aplicación. En este aspecto, la programación en capas juega un
papel de suma importancia ya que sigue un estándar conocido en el ambiente de
desarrollo de aplicaciones, lo cual da al programador una guía para hacer mejoras a
la aplicación sin que esto sea una tarea tediosa y desgastante, siguiendo el estándar
establecido para tal fin y dividiendo las tareas en partes específicas para cada capa
del proyecto.
Las principales capas que siempre deben estar en este modelo son:
▪ Capa de Datos
La presentación del programa ante el usuario, debe manejar interfaces que cumplan
con el objetivo principal de este componente, el cual es facilitar al usuario la interacción
con la aplicación. Para esto se utilizan patrones predefinidos para cada tipo de
aplicación y para cada necesidad del usuario. La interfaz debe ser amigable y fácil de
Las interfaces deben ser consistentes con la información que se requiere, no se deben
utilizar más campos de los necesarios, así como la información requerida tiene que
ser especificada de manera clara y concisa, no debe haber más que lo necesario en
cada formulario y por último, las interfaces deben satisfacer los requerimientos del
usuario, por lo cual no se debe excluir información solicitada por el usuario final y no
se debe incluir información no solicitada por el mismo.
Es aquí donde se encuentra toda la lógica del programa, así como las estructuras de
datos y objetos encargados para la manipulación de los datos existentes, así como el
procesamiento de la información ingresada o solicitada por el usuario en la capa de
presentación.
Recibe los datos que ingresó el usuario del sistema mediante la capa de presentación,
luego los procesa y crea objetos según lo que se necesite hacer con estos datos; esta
acción se denomina encapsulamiento.
Capa de Datos
El manejo de los datos debe realizarse de forma tal que haya consistencia en los
mismos, de tal forma los datos que se ingresan así como los que se extraen de las
bases de datos, deben ser consistentes y precisos.
Es en esta capa donde se definen las consultas a realizar en la base de datos, tanto
las consultas simples como las consultas complejas para la generación de reportes
más específicos.
Esta capa envía la información directamente a la capa de reglas de negocio para que
sea procesada e ingresada en objetos según se necesite, esta acción se denomina
encapsulamiento.
Ventajas y Desventajas
La programación en capas no es una técnica rígida que debe implementarse
solamente de una forma, sino que los desarrolladores de proyectos tienen múltiples
maneras de implementarla según las tecnologías y tendencias que se utilicen.
Dentro del concepto de programación en capas, existen dos términos esenciales para
el mejor entendimiento de los conceptos relativos a esta metodología, es aquí donde
radica la importancia de la cohesión y el acoplamiento dentro de una aplicación
generada mediante este método.
Cohesión
Este término es utilizado para describir el comportamiento que deben tener los
módulos y objetos de un sistema o subsistema, comportamiento que describe
la forma en que deben trabajar los objetos y módulos entre sí, con alta cohesión
para que trabajando en conjunto los módulos y objetos puedan alcanzar un solo
propósito de manera más eficaz y rápida.
Acoplamiento
Se refiere al grado de dependencia que existe entre los módulos. Este grado
de dependencia debe ser considerablemente bajo ya que el trabajo se divide
en módulos para que cada uno tenga un funcionamiento específico y puede ser
más factible la implementación por separado de cada uno. En caso de haber
alto acoplamiento entre módulos no se estaría alcanzando el principal objetivo
de este modelo, el cual es dividir una tarea grande en varias pequeñas, ya que
los módulos actuarían como uno solo al estar altamente acoplados entre sí y
se perdería el objetivo primordial de dividir el proyecto.
Ventajas
Al implementar este modelo de programación, se asegura un trabajo de forma
ordenada y separada, debido a que sigue el principio de “divide y vencerás”.
Cada capa está dividida según su funcionalidad cuando se quiere modificar el sistema
basta con cambiar un objeto o conjunto de objetos de una capa. Esto se llama
modularidad.
Desventajas
Cuando se implementa un modelo de programación en capas, se debe llegar a un
balance entre el número de capas y subcapas que componen el programa. Este debe
ser el necesario y suficiente para realizar un trabajo específico con eficiencia y ser lo
más modular posible.
Conclusiones
La programación en capas ha sido una de las últimas tendencias en cuanto a software
comercial se refiere, es una tendencia que bien aplicada puede resultar en un
desarrollo de software eficiente.
PRINCIPIOS SOLID
SOLID es un acrónimo inventado por Robert C.Martin para establecer los cinco
principios básicos de la programación orientada a objetos y diseño. Este acrónimo
tiene bastante relación con los patrones de diseño, en especial, con la alta cohesión
y el bajo acoplamiento.
El problema surge cuando tenemos la necesidad de utilizar ese mismo método desde
otra clase. Si no se refactoriza en ese momento y se crea una clase destinada para la
finalidad del método, nos toparemos a largo plazo con que las clases realizan tareas
que no deberían ser de su responsabilidad.
O-Abierto/Cerrado (Open/Closed)
Principio atribuido a Bertrand Meyer que habla de crear clases extensibles sin
necesidad de entrar al código fuente a modificarlo. Es decir, el diseño debe ser abierto
para poderse extender pero cerrado para poderse modificar. Aunque dicho parece
fácil, lo complicado es predecir por donde se debe extender y que no tengamos que
modificarlo. Para conseguir este principio hay que tener muy claro cómo va a funcionar
la aplicación, por donde se puede extender y cómo van a interactuar las clases.
El objetivo de este principio es el uso de abstracciones para conseguir que una clase
interactúe con otras clases sin que las conozca directamente. Es decir, las clases de
nivel superior no deben conocer las clases de nivel inferior. Dicho de otro modo, no
debe conocer los detalles. Existen diferentes patrones como la inyección de
dependencias o service locator que nos permiten invertir el control.
KISS
Kiss es un acrónimo en inglés que significa “Keep it simple, stupid”, que en español
vendría siendo “Manténlo simple, estúpido”. Una traducción más suave que
también se usa es “Keep it super simple”, es decir: “Manténlo súper simple”. El
principio fue formulado por un ingeniero del ejército estadounidense en 1960, y
propone que cualquier sistema que implementemos, un producto, un servicio, un
sistema informático, las soluciones a un problema, etc.; son mucho mejores si se
basan en la simplicidad y sencillez.
Kiss plantea que usted debe evitar cualquier complejidad que no agregue valor
a la solución, y reducir la tendencia de muchas personas de “sobre complicar”
las cosas.
El principio Kiss implica entender a profundidad la verdadera necesidad del cliente así
como las características y elementos esenciales y no esenciales de una solución,
producto o servicio. Así podrá desechar aquello que no aporte valor. Pregúntese
siempre si lo que está añadiendo es algo imprescindible para atender sus necesidades
o las del cliente.
Algunos de los beneficios que pueden obtener del principio Kiss para su negocio son
los siguientes:
▪ Los productos o servicios serán de mayor calidad, ya que puede invertir más
dinero en lo esencial, en lugar de invertir en cosas innecesarias.
Así que recuerde, la próxima vez que vaya a realizar cualquier trabajo o
emprendimiento, ¡mantenlo sencillo! No complique las cosas más allá de lo
estrictamente necesario.
La perfección se alcanza, no cuando no hay nada más que añadir, sino cuando ya no
queda nada más que quitar.
YAGNI
YAGNI significa “You Aren't Gonna Need It” (No vas a necesitarlo) Es uno de los
principios del Extreme Programming que indica que un programador no debe agregar
funcionalidades extras hasta que no sea necesario.
Aplicar siempre las cosas cuando realmente los necesita, no cuando lo que prevén que
los necesita.
Ron Jeffries
Navaja de Occam
La Navaja de Occam se remonta a un principio metodológico y filosófico,
perfectamente aplicable al desarrollo de software, según el cual, “en igualdad de
condiciones, la explicación más sencilla suele ser la correcta”.
Reflexión cuidadosa
Tanto el principio KISS como la Navaja de Occam pueden ser recursos incómodos
para quienes gustan de ver el mundo en polaridades de bueno o malo, correcto o
incorrecto. Son maneras de pensar instrumentales, de tránsito; herramientas para
encarar la ambigüedad y seguir adelante sin entramparse en tediosas discusiones
bizantinas sobre suposiciones, gustos o creencias. También hay que aclarar que estos
principios exigen una mentalidad abierta y crítica para testear los hechos con
frecuencia y someterlos a revisión.
PRINCIPIO DRY
Cuando el principio DRY se aplica de forma eficiente los cambios en cualquier parte
del proceso requieren cambios en un único lugar. Por el contrario, si algunas partes
del proceso están repetidas por varios sitios, los cambios pueden provocar fallos con
mayor facilidad si todos los sitios en los que aparece no se encuentran sincronizados.
Cada vez que repites un trozo de código (reglas, procesos, rutinas) debes acordarte
de dónde las pones. Si posteriormente cambian las especificaciones, o encuentras
una mejor forma de hacer las cosas, o te diste cuenta que hiciste algo que no debías,
tienes que cambiar el código en todos los lugares donde existe. Si no lo haces, vas a
tener un sistema que se comporta de una forma en unas ocasiones, y de otra forma
en otras, porque utiliza estas representaciones inconsistentes, tendrás un sistema
inconsistente.
Obsesiónate con este principio, cada vez que uses el editor de texto, y veas que estás
repitiendo algo, haciendo mucho "copy & paste" de una serie de estructuras IF para
ponerlos en dos o tres métodos diferentes, o si varias clases son muy similares, tal
vez es momento de detenerte y hacer una refactorización para colocar todo eso en un
sólo lugar y reutilizar toda esa lógica, debes utilizar la herencia, clases abstractas o
cualquier recurso que te permita concentrar todo eso en un sólo sitio.
Con respecto al código, no se trata de que los pedazos de código NUNCA se deban
repetir, a veces es necesario y menos complejo dejar que algunas líneas se repitan
en diferentes clases; donde en realidad lo debes aplicar es cuando tratas de hacer
representaciones funcionales de tu aplicación: Ejemplo, si tienes una rutina que va a
recuperar los datos de cliente y hacer cierta transformación a esos datos y lo harás a
menudo en la aplicación, vale la pena hacer una función llamada (por ejemplo)
"recuperaClienteInfo".
En muchas ocasiones, encontramos que una función existente hace "casi" lo mismo
que queremos, pero necesitamos que haga algo extra o que no lo haga. Si te
encuentras en este caso, en lugar de duplicar la función, mejor añádele un parámetro,
y utiliza la información de ese parámetro para que la función haga el trabajo que
necesitas. Una vez hecha esta operación, el problema que se presenta es rastrear el
código existente y modificar por todos lados para añadir ese parámetro; puedes
entonces tener varias alternativas:
Un ejemplo.
Supongamos que estamos haciendo una parte de un sistema en el cual se almacenará
un catálogo de productos, digamos de frutas. Normalmente lo primero que haremos
es crear la base de datos. En la base de datos se tendrían (por ejemplo) estos campos:
id, código, nombre, precio. En la misma base de datos agregamos ciertas restricciones
al producto: el código es único y es una cadena de 10 caracteres, el nombre no puede
ir vacío, el precio no puede ser cero (observemos que incluso los tipos de esos datos
radican en la creación de la tabla en la base de datos).
Una vez creada la base de datos, nos dirigimos a nuestro IDE para crear el código
que trabajará con esos datos. Los enfoques varían mucho, y las maneras de trabajar
con esos datos también. Pero en este caso vamos a trabajar con una capa de
persistencia basada en un ORM (Object-Ralational Mapping). En algún lado de la
configuración del ORM estableceremos que la tabla fruta se mapeará al objeto Fruta.
Que el objeto Fruta tendrá un id, un nombre, un código y un precio.
Con nuestro mapeo funcionando, nos dirigimos a crear nuestro objeto Fruta. Nuestro
objeto tendrá un BigInt para el id, tendrá un String para el código, otro para el nombre
y un BigDecimal para el precio. Ahora crearemos los métodos de accesos con su set
y su get. (Propiedades en Java). Si la capa de persistencia nos echa una mano no
tendremos que verificar que el código sea único, pero si no, tendremos que codificarlo
nosotros.
Ahora, si queremos que nuestro código sea escalable y pueda mantenerse a largo
plazo, utilizaremos alguna implementación del patrón MVC (Model-View-Controller, o
Modelo-Vista-Controlador). En cada uno pondremos los respectivos campos de la
fruta: el id, el código, el nombre y el precio. Haremos un listado de las frutas que hay
almacenadas, y una forma para agregar y/o editar entradas. En la vista le diremos al
controlador qué desplegar, y haremos una tabla en el View. El model ya lo
implementamos, que es nuestro objeto Fruta. Para el formulario haremos lo mismo,
pondremos los campos de fruta y lo guardaremos. Para proteger nuestro modelo
haremos algunas validaciones del lado del servidor, pero para darle una experiencia
interactiva al usuario, también haremos validaciones en el lado del cliente. Usaremos,
claro está, uno de esos bonitos frameworks que ahora nos hacen la vida más fácil con
javascript. La validación del código único requerirá una llamada de Ajax, y las demás
serán simples validaciones con Javascript.
Pasados unos días, nos mandan un requerimiento del cliente que pide que el código
en vez de ser de 10 caracteres va a ser de 15 (cambiaron un par de cosas del negocio),
y que hará falta otro código: el código de bodega que será de 20 caracteres y también
hará falta el peso unitario, que será un decimal opcional.
En nuestra mente comienza a correr el tedioso proceso que tenemos que realizar:
hacer los cambios en la base de datos, hacer los cambios en el mapeo, hacer los
cambios en el objeto fruta, hacer los cambios en el controller y en el view para la lista,
hacer los cambios en el controller y en el view (que incluye dos validaciones de
javascript). Además….qué fácil será confundirnos.
A todo esto, la documentación estaba ya lista, y habrá que cambiarla, pero por falta
de tiempo creemos que se quedará tal y como está.
He aquí lo que nos pasa cuando violamos el principio DRY. El principio DRY establece
que la información, o el conocimiento debe estar almacenado en UN SOLO LUGAR,
para evitar lo engorroso que es hacer cambios en mil lados cuando hacen, además
de ahorrarnos la tendencia a cometer errores cuando hay que cambiar muchas cosas
que significan lo mismo.
Nadie negará la utilidad de patrones como el MVC, o de ideas como el ORM. Pero a
veces esas soluciones crean una sobre ingeniería tan grande que no sé si compensan
sus soluciones.
Capítulo 8
Patrones de Software
INTRODUCCIÓN
Los Patrones de Software son recomendaciones probadas y sirven como modelo para
dar soluciones a problemas comunes en el desarrollo del software. Son considerados
en la actualidad como buenas prácticas en la ingeniería de software.
Un patrón define una posible solución correcta para un problema de software dentro
de un contexto dado, describiendo las cualidades invariantes de todas las soluciones.
Sin embargo, no fue hasta principios de los 90's cuando los patrones de diseño de
software tuvieron un gran éxito en el mundo de la informática a partir de la publicación
del libro "Design Patterns", escrito por GoF (Gang of Four) y compuesto por
Erich Gamma, Richard Helm, Ralph Johnson y John Vlisides. El libro plantea 23
patrones de diseño comunes (Factory, Singleton, Adapter, Facade, Command, Iterator
entre otros)
Hoy en día existe una variedad de patrones que permite uniformizar y diseñar
soluciones estándar de software, y que muy bien pueden ser aplicados en el desarrollo
de aplicaciones empresariales utilizando Java.
Los patrones bastante usados en el desarrollo de aplicaciones son MVC (Model View
Controller), DAO (Data Access Object) y DTO (Data Transfer Object).
SINGLETON
Contexto
Existen escenarios donde la aplicación sólo necesita emplear una única instancia
(objeto) de una clase, y esta debe ser accesible desde los diferentes componentes del
sistema.
Las clases que cumplen estas características suelen tener alguna de las siguientes
funciones:
Problema
Necesitamos crear una instancia de una clase que sea accesible globalmente, y que
sea única.
Solución
El patrón Singleton proporciona la siguiente solución:
Este diagrama UML muestra cómo se implementa el patrón Singleton en una clase.
Contiene una propiedad estática (el subrayado indica que es un método de clase), y
que el método getInstancia() retorna un objeto de la misma clase.
private Demo() {
}
. . . . . .
Contexto
Aplicaciones interactivas con interfaces humano-computador cambiantes y flexibles.
Problema
Es muy frecuente que se solicite cambios a la interfaz de usuario. Los cambios a la
interfaz deberían ser fáciles y no tener consecuencias para el núcleo del código de la
aplicación.
Solución
Modelo
Vista
Controlador
Contexto
En general, los componentes de un sistema necesitan intercambiar datos.
Problema
Se requiere enviar y recuperar un conjunto de datos entre un objeto y otro.
Solución
Crear una clase que agrupe un conjunto de datos que se desea transferir y por lo
general implemente solo métodos set y get para asignar y recuperar los datos.
Clase Data Transfer Object (DTO) antes llamado Value Object (VO).
Contexto
El contexto para las fuentes de datos presenta muchas características que hacen
difícil tener componentes estándares y escalables. A continuación se enumeran
algunas características de este entorno:
Problema
Todo sistema necesita una capa de persistencia de datos, por lo tanto, podemos
afirmar que no se tiene un problema, realmente se tienen varios problemas que se
describen a continuación:
▪ Las API varían entre RDBMS (Sintaxis SQL, formato de datos, etc.).
▪ Dependencias de código.
Solución
La solución la tenemos en el patrón Data Access Object (DAO) para abstraer y
encapsular todo el acceso a la fuente de datos, cuyas características se describen a
continuación:
Ahora, imaginemos que hicimos una aplicación para la empresa donde trabajamos.
Utilizando como motor de base de datos Oracle. Pero NO tenemos dividida la capa de
lógica de negocio de la de capa de lógica persistencia. Por lo que la interacción con
la base de datos se hace directamente desde la capa de lógica de negocio. Nuestra
aplicación consiste en cantidad considerable de clases, y gran parte de ellas
Bien, ahora que sabemos porque es importante tener separadas las capas de lógica
de negocio y de persistencia, vamos a ver cómo utilizar el patrón de diseño DAO para
crear nuestra propia capa de lógica de persistencia.
DAO consiste básicamente en una clase que es la que interactúa con la fuente de
datos. Los métodos de esta clase dependen de la aplicación y de lo que queramos
hacer. Pero generalmente se implementan los métodos CRUD para realizar las “4
operaciones básicas” de una base de datos.
Podría decirse que un DTO es un objeto simple, que tiene como atributos los datos
del modelo, con sus correspondientes métodos getters y setters.
Capítulo 9
Prácticas de Laboratorio
PRACTICA 01
Objetivo
Aplicar el concepto de Orientación a Objetos para resolver problemas sencillos
utilizando dos capas.
Enunciado
La empresa "Todo Barato" necesita facilitar la elaboración de los pedidos que
realizan los empleados del departamento de compras a sus proveedores, el problema
radica al momento de calcular el impuesto.
Abstracción
Se necesita un componente que implemente dos servicios:
PRACTICA 02
Objetivo
Aplicar el concepto de encapsulación, la orientación a objetos y la programación en
capas.
Enunciado
Una institución financiera necesita de un programa que le permita encontrar el importe
que deben pagar sus clientes por los préstamos que realiza, se sabe que se trata de
un interés compuesto, capitalizable mensualmente.
Dónde:
C : Capital
n : Número de periodos
PRACTICA 03
Objetivo
Aplicar el concepto de encapsulación, la orientación a objetos y la programación en
capas.
Enunciado
La empresa Vía Éxitos Necesita saber cuánto se le debe pagar a sus trabajadores y
a cuánto asciende el importe de impuesto a la renta que debe retener.
Se sabe que si los ingresos supera los 1500.00 Nuevos Soles se debe retener el 8%
del total correspondiente a la renta.
PRACTICA 04
Objetivo
Aplicar la sobrecarga para disponer de diversas versiones de métodos y constructores
que se puedan aplicar dependiendo de las necesidades que se tengan o se proyecten
tener.
Enunciado
La empresa EduTec necesita de una librería que permita calcular el promedio de un
conjunto de números.
PRACTICA 05
Objetivo
Entender la diferencia entre variables y métodos de instancia y de clase.
Enunciado
El colegio "Ángeles del Cielo" está solicitando un programa en Java para que los
alumnos de primaria verifiquen sus ejercicios de matemáticas referidos a:
▪ Cálculo de factorial
▪ La serie de Fibonacci
▪ Número primo
PRACTICA 06
Objetivo
Aplicar el concepto de herencia y polimorfismo.
Enunciado
El restaurante "El Buen Sabor" necesita implementar una aplicación que permita a sus
empleados calcular los datos que se deben registrar en el comprobante de pago.
Los conceptos que se manejan cuando se trata de una factura son los siguientes:
Consumo 100.00
Impuesto 19.00
Total 119.00
Total 119.00
PRACTICA 07
Objetivo
Aplicar interfaces en el diseño de componentes software.
Enunciado
La institución educativa EduTec cuenta con dos tipos de trabajadores: Empleados y
Docentes.
Los empleados cuentan con un sueldo fijo y depende del cargo que ocupa, según la
siguiente tabla:
El sueldo del docente está en función de las horas que dicta, el pago por hora es de
120 Nuevos Soles.
PRACTICA 08
Objetivo
Entender el concepto de arreglo y colecciones.
Enunciado
La institución educativa SuperTec en su política de darle al profesor las herramientas
computacionales para que pueda realizar su labor, requiere de una aplicación para
que pueda registrar las notas de sus estudiantes.
▪ Listado estadístico que incluye: nota promedio, nota mayor, nota menor,
aprobados y desaprobados con respecto al promedio del alumno.
Se sabe que por cada alumno debe registrar 4 notas, y el promedio del alumno se
obtiene promediando las 3 mejores notas.
Capítulo 10
CURSOS VIRTUALES
CUPONES
En esta URL se publican cupones de descuento:
http://gcoronelc.github.io
En este curso aprenderás las mejores prácticas de programación para que te inicies
con éxito en este competitivo mundo del desarrollo de software.
Cada tema está desarrollado con ejemplos que demuestran los conceptos teóricos y
finalizan con un proyecto aplicativo.
En este curso aprenderás a programas bases de datos Oracle con JDBC utilizando
los objetos Statement, PreparedStatement, CallableStatement y a programar
transacciones correctamente teniendo en cuenta su rendimiento y concurrencia.
En este curso aprenderás a programas las bases de datos ORACLE con PL/SQL, de
esta manera estarás aprovechando las ventas que brinda este motor de base de datos
y mejoraras el rendimiento de tus consultas, transacciones y la concurrencia.