00 introdprog.qxd 23/7/07 20:01 page 1 introducción a...

94
Introducción a la Programación Preparado para rendir la estrella inicial del examen DCE por José María Selesan

Upload: duongngoc

Post on 22-Sep-2018

214 views

Category:

Documents


0 download

TRANSCRIPT

Introducción a laProgramación

Preparado para rendir la estrellainicial del examen DCE

por José María Selesan

00_IntrodProg.qxd 23/7/07 20:01 Page 1

TÍTULO > Introducción a la Programación

AUTOR > José María Salesan

FORMATO > 13,5 x 19 cm

PÁGINAS > 96

Copyright © GRADI S.A. 2007.

Hecho el depósito que marca la ley. Reservados todos los derechos de autor.

Prohibida la reproducción total o parcial de esta publicación por cualquier medio

o procedimiento y con cualquier destino.

Primera impresión realizada en agosto de 2007.

Kollor Press, Capital.

Todas las marcas mencionadas en este libro

son propiedad exclusiva de sus respectivos dueños.

Selesan, José MaríaIntroducción a la programación. - 1a ed. - Banfield - Lomas de Zamora : Gradi S.A., 2007.v. 11, 96 p. ; 19x14 cm. (Pocket users)

ISBN 978-987-1347-45-2

1. Informática. I. TítuloCDD 005.3

00_IntrodProg.qxd 23/7/07 20:01 Page 2

3

El objetivo del libro es brindar al lec-tor un panorama general sobre el desa-rrollo de software para computadorasy servir como punto de partida, tantopara rendir el examen cero del progra-ma Desarrollador Cinco Estrellas deMicrosoft, como para adentrarse en es-ta fascinante profesión. A lo largo delos cinco capítulos que lo integran, nosintroduciremos en algunos de los prin-cipales temas que todo programadordebe conocer.

El primer capítulo trata sobre los fun-damentos del software y los algoritmos.Si bien pueden parecer un tanto trivia-les, son de fundamental importancia,porque un programador debe estar pre-parado y capacitado para pensar cual-quier solución a un problema en formade algoritmo. Estudiaremos, también,distintas maneras de expresar algorit-mos, necesarias como herramientas decomunicación y documentación.

En los capítulos dos y tres, abordare-mos temas relacionados con la progra-mación estructurada. A lo largo deellos, aprenderemos muchos concep-tos, la mayoría de los cuales se utilizana diario, porque forman la base decualquier programa. Aprenderemos los

conceptos de variable, estructuras decontrol, buenas prácticas de codifica-ción, y más. Es importante que el lec-tor medite en profundidad cada unode estos temas, realice prácticas y con-sulte más material para asimilar co-rrectamente cada uno de ellos y esta-blecer una base de conocimiento sóli-da que le permita enfrentar cualquiertipo de desarrollo.

Luego, el capítulo cuatro presenta unaintroducción a la Programación Orien-tación a Objetos (POO). Este paradig-ma, si bien no es nuevo, presenta unavance importante en la manera de de-sarrollar software, y recién en los últi-mos años se lo está considerando comoel paradigma por defecto para todonuevo desarrollo. Si bien este capítulono ahonda en detalles, tiene como ob-jetivo familiarizar al lector con cadauno de los conceptos clave de la POO.

Finalmente, el capítulo cinco intro-duce algunos de los conceptos del Len-guaje Unificado de Modelado (UML).UML se basa fuertemente en los con-ceptos de POO, como clases y heren-cia, por lo que será necesario compren-der los temas del capítulo cuatro paraaprovechar al máximo éste.

Introducción

00_IntrodProg.qxd 23/7/07 20:01 Page 3

Capítulo 1

FUNDAMENTOS¿Qué es el software? 8

Un poco de historia 9

Los lenguajes de programación 11

Los lenguajes en la actualidad 13

Compilación e interpretación 14

Algoritmos 15

Expresión de algoritmos 15

Conclusiones 18

Capítulo 2

PROGRAMACIÓN ESTRUCTURADAMejorar el código 20

Hacia la programación estructurada

Conceptos de programación

estructurada 22

Identificadores y palabras clave

Variables

Tipos de datos

Sentencias

Operadores y expresiones

Tipos de operadores

Estructuras de control

Conclusiones 34

Capítulo 3

ELEMENTOS DE PROGRAMACIÓNModularización 36

Procedimientos y funciones

Librerías 44

Arreglos y matrices 45

Arreglos

Matrices

El estilo de programación 50

Tabulaciones

Comentarios

Conclusiones 54

Capítulo 4

PROGRAMACION ORIENTADAA OBJETOSLos objetos 56

Origen

Ventajas de la POO

CONTENIDO ‹‹

4

00_IntrodProg.qxd 23/7/07 20:01 Page 4

5

Clases y objetos 58

Propiedades y métodos

Pensar en objetos 60

Patrones de diseño

Relaciones entre clases 63

Relación de uso

Relación de agregación

Herencia 66

Redefinir comportamiento

Extender clases

Tipos de herencia

Clases abstractas

Interfaces

Polimorfismo 72

Conclusiones 74

Capítulo 5

UML¿Qué es UML? 76

Diagrama de clases 77

Clases

Relaciones entre clases

Diagrama de secuencia 83

Elementos del diagrama

de secuencia

Diagramas de casos de uso 85

Conclusiones 86

Apéndice

EL EXAMENAlgoritmos 88

Lenguajes de programación 88

Programación estructurada 89

Programación orientada

a objetos 91

Desarrollador 5 Estrellas 92

00_IntrodProg.qxd 23/7/07 20:01 Page 5

6

Cuando un músico escucha una me-lodía que acaba de componer o cuan-do un escultor retoca el último detallede su obra maestra, está ante un logropersonal, pero que fue hecho pensan-do en los demás. Está ante el fruto desu trabajo, que tuvo que realizar parapasar de una idea o modelo que estabasólo en su imaginación, a algo percep-tible por los otros. Y ese logro causauna gran satisfacción.

El desarrollo de software –al igualque la música, la escultura o la pintu-ra– es una actividad creativa y, hasta sise quiere, artística. Es una actividad enla que una persona (el programador)debe plasmar una idea en un programaque alguien usará luego. Y es muy pro-bable que esa idea sea algo totalmentenovedoso, algo que nadie antes ha vis-to. Y ver esa idea traducida en softwa-re produce una sensación que sólo unprogramador puede entender.

Ser programador no es fácil, pero esdivertido. Desarrollar software es, defi-nitivamente, una tarea compleja. De-beremos ser capaces de interpretar alusuario, de entender qué es lo que ne-cesita (aunque muchas veces él mismono sabe qué es lo que necesita). Pasare-mos largas horas pensando un algorit-mo que resuelva el problema de nues-

tro cliente de la mejor manera. Mu-chas veces nos iremos a casa y seguire-mos pensando en ese dichoso algorit-mo. Nos iremos a dormir (probable-mente tarde, porque habremos dedica-do parte de nuestro tiempo libre aaprender nuevas tecnologías) y desper-taremos pensando en el algoritmo o,incluso, con la solución en mente. Pe-ro cuando escribamos la última líneadel código que implementa ese algorit-mo y lo veamos funcionando, obten-dremos una gran satisfacción. Una sa-tisfacción que sólo puede entenderotro programador.

Cuando escribí mi primera línea decódigo, debo haber tenido unos 11años. Ese día, al ver que una secuenciade caracteres casi ilegible dibujaba uncírculo en la pantalla del televisor (laépoca de las PCs recién comenzaba),me di cuenta de que eso era lo que que-ría hacer el resto de mi vida. Creo quecada persona que quiere dedicarse aldesarrollo de software, antes de nada,debe experimentar qué sensación leproduce ver su programa en ejecución.Aquel que no sienta nada jamás podráser un programador, porque la mayorrecompensa es, justamente, esa sensa-ción, aunque sean las 4 de la madruga-da y llevemos 20 horas codificando.

Prólogo

00_IntrodProg.qxd 23/7/07 20:01 Page 6

CAPÍTULO 1

Fundamentos

En este primer capítulo, veremos los fundamentos

básicos del software, su funcionamiento, su uso

y su creación. A su vez introduciremos los principales

conceptos sobre la programación moderna.

ATENCIÓN AL LECTOR > [email protected]

01_IntrodProg.qxd 23/7/07 20:04 Page 7

8

FUNDAMENTOS

¿QUÉ ES EL SOFTWARE?> Desde siempre, las computadoras han sido máquinas con la única capacidadde llevar a cabo instrucciones, como imprimir un texto en un dispositivo de sa-lida o sumar dos números. Un programa es un conjunto de instrucciones y da-tos que juntos y, de manera sistemática, permiten resolver problemas. Podemosentonces definir el software como el conjunto de programas que funcionan enuna computadora y que permiten realizar una o varias tareas específicas.

Es importante resaltar que, al hablar de computadoras, no nos referimos sólo alas personales (PC), sino a cualquier dispositivo capaz de leer instrucciones deuna memoria, y ejecutarlas. Por lo tanto, podemos encontrar software en un la-varropas, en un respirador artificial y hasta en automóviles modernos.

Según su uso, el software se puede clasificar en dos grandes grupos: el softwarede sistema y el software de aplicación. El software de sistema es el conjunto deprogramas básicos para el funcionamiento de la computadora, como por ejem-plo el sistema operativo (Windows o Linux), los drivers, etcétera., mientras queel software de aplicación son los programas para realizar tareas específicas, co-mo un procesador de texto, un juego o un compilador.

Los términos software y sistema se utilizan para referirse a lo mismo. Sin embar-go, la palabra sistema por sí sola no tiene nada que ver con el software. Un sis-tema es un conjunto de elementos que interactúan de alguna manera, como pue-de ser el sistema digestivo o el sistema solar. Otro ejemplo de sistema, son los sis-temas de información, sin que esto tampoco implique un software. Por ejemplo,un sistema contable es un conjunto de métodos y de herramientas que permitenmantener la información sobre los movimientos económicos y los bienes de unaempresa, pero se pueden utilizar libros en papel para alcanzar el objetivo. Final-mente, un sistema de información basado en computadora es la implementación

EL HARDWARE

El otro componente importante de unacomputadora es el hardware, que incluyetodos los elementos físicos o materialesque la conforman. La diferencia entre el

hardware y el software es que este últi-mo es intangible (lo vemos, pero no po-demos tocarlo), mientras que el hardwa-re es totalmente palpable.

01_IntrodProg.qxd 23/7/07 20:04 Page 8

9

›¿QUÉ ES EL SOFTWARE?

con herramientas computacionales (programas y datos) de un sistema de infor-mación. Por lo tanto, como sinónimo de software podemos utilizar sistema deinformación basado en computadora. Por otro lado, los términos programa ysistema suelen utilizarse indistintamente, pero no está bien. Generalmente, pode-mos decir que un sistema es un grupo de programas que interactúan para reali-zar ciertas tareas. Un programa es una unidad mucho más pequeña, indepen-diente y sencilla que un sistema.

UN POCO DE HISTORIAMuchos autores coinciden en afirmar que la idea de programa como secuencia

de instrucciones se remonta a principios del siglo XIX y no tiene nada que ver conla computación. Efectivamente, en 1801 un francés llamado Joseph Marie Jac-quard ideó un mecanismo de tarjetas perforadas para controlar los dibujos queformaban los hilos en una máquina para tejer. De esa manera, lograba programarlas puntadas de la máquina para obtener tramas y figuras repetibles.

En 1843, Ada Augusta Lovelace, hija del poeta inglés Lord Byron, planteó la ideade usar tarjetas perforadas para controlar la Máquina Diferencial de Babbage (ver re-cuadro) y lograr que repita ciertas operaciones. Unos años más tarde, su idea fue to-mada para desarrollar un sistema de cómputo para la oficina de censos de los Esta-dos Unidos. Las tarjetas estaban diseñadas de tal modo que los agujeros representa-ban la edad, raza, sexo, etcétera. Este desarrollo permitió que el tiempo en obtenerlos resultados del censo de 1890 fuera de 5 años menos que el censo anterior.

La idea de lady Ada tuvo tal repercusión que, al día de hoy, se la considera co-mo la primera programadora, y las tarjetas perforadas fueron utilizadas en cen-tros de cómputos hasta no hace mucho tiempo.

LA MÁQUINA DIFERENCIAL

En el año 1812, Charles Babbage,preocupado por los errores de cálcu-lo en las tablas matemáticas, pensóque sería útil poder calcularlos deforma automática. Ideó, entonces,una máquina capaz de obtener apro-ximaciones al resultado de una fun-

ción matemática, mediante un méto-do llamado de las diferencias. Si bienpor limitaciones propias de la épocanunca llegó a terminar su construc-ción, su denominada Máquina dife-rencial sentó las bases de la compu-tación moderna.

01_IntrodProg.qxd 23/7/07 20:04 Page 9

10

FUNDAMENTOS

Ya en el siglo XX, el físico estadounidense John Atanasoff, conocedor de las teo-rías de Babbage y consternado por la cantidad de cálculos que debía realizar, pen-só en construir una máquina de cálculo que, a diferencia de las mecánicas, seríadigital, y su funcionamiento se basaría en el sistema binario. Su aparato fue co-nocido como ABC Atanasoff-Berry-Computer, y por eso es considerado el ini-ciador de la computación digital.

Luego, durante la Segunda Guerra Mundial, se construyó y comenzó a funcio-nar en instalaciones militares de los Estados Unidos una máquina llamadaENIAC (Electronic Numeric integrator and Computer). Su funcionamiento se ba-saba en tubos de vacío, interruptores y relés para hacer operaciones matemáticasutilizando el sistema binario. Por su tamaño, ocupaba una habitación entera.

Figura 1. La ENIAC fue una de las primeras computadoras del siglo XX. Su poder de cálculo era menor al de una calculadora de bolsillo actual.

A partir de la ENIAC, las computadoras fueron evolucionando año tras año, a unritmo cada vez más vertiginoso hasta llegar a las computadoras que conocemos enla actualidad. Sin embargo, a pesar de esta evolución, las computadoras mantienendos características esenciales: están basadas en el sistema binario y necesitan que seles provea de una secuencia ordenada de instrucciones para poder funcionar.

LA MÁQUINA DE TURING

Creada por Alan Turing, consistía enuna cinta y un cabezal que podía leer yescribir caracteres en dicha cinta, co-mo también moverse hacia la izquierday hacia la derecha. La cinta podría ver-se como el conjunto de entradas y sali-das de un programa. Turing demostró

que su máquina podría resolver cual-quier problema representable por unalgoritmo y que, si no era capaz de re-solverlo, entonces resultaba, insolubleen una computadora. Su trabajo seconvirtió en el tema central de estudiode la Teoría de la Computación.

01_IntrodProg.qxd 23/7/07 20:04 Page 10

11

›LOS LENGUAJES DE PROGRAMACIÓN

LOS LENGUAJES DE PROGRAMACIÓN

> Ahora que sabemos qué es un programa, podemos decir que la programaciónes el proceso de construir programas. Para escribir programas, necesitamos cono-cer la lista de las posibles instrucciones que debemos proporcionar a la computa-dora, y cómo combinarlas para lograr los resultados deseados.

De acuerdo con el primer párrafo, para confeccionar programas, debemos es-cribir una secuencia de instrucciones que puedan ser entendidas por la compu-tadora, pero como vimos anteriormente, hasta las computadoras más moder-nas trabajan con el sistema binario, por lo que, para programarlas, deberíamosproporcionarles secuencias de unos y ceros formando las instrucciones denuestro programa. Si bien el sistema binario es muy simple, para un ser hu-mano, resultaría imposible recordar las combinaciones de unos y de ceros queforman cada una de las instrucciones. Para solucionar este problema, existenlos lenguajes de programación, una forma más sencilla y legible de represen-tar las instrucciones.

Sin entrar en detalles formales, podemos decir que un lenguaje de programa-ción es un conjunto de reglas que determinan, de forma clara, precisa y sin am-bigüedades, la forma en que se le imparten las instrucciones a una computadorapara construir un programa. Estas reglas se dividen en reglas sintácticas y reglassemánticas. Las reglas sintácticas especifican cuáles son los caracteres válidos dellenguaje y cómo se pueden agrupar en palabras también válidas. Las reglas se-mánticas determinan cuál es el significado de las palabras, es decir, qué se espe-ra que la computadora haga cuando recibe una palabra o una instrucción.

ARQUITECTURAS CISC Y ARQUITECTURAS RISC

El conjunto de instrucciones que pue-de entender una computadora de-pende de su arquitectura (por ejem-plo, un procesador Intel tiene un con-junto de instrucciones diferente delde un procesador Motorola). La canti-dad de instrucciones permiten clasi-

ficar a los procesadores en dos gran-des grupos: CISC (Complex Instruc-tion Set Computer, computadora conconjunto de instrucciones complejo) yRISC (Reduced Instruction Set Com-puter, computadora con conjunto deinstrucciones reducido).

01_IntrodProg.qxd 23/7/07 20:04 Page 11

12

FUNDAMENTOS

Los lenguajes de programación fueron creados para facilitar la escritura de pro-gramas, proveyendo una abstracción de las instrucciones reales de la computado-ra (formadas por unos y ceros) y reemplazándolas por palabras que fueran más fá-ciles de recordar por las personas. Según el nivel de abstracción que proveen, loslenguajes de programación se clasifican en tres niveles (Tabla 1). Cuanto más altosea el nivel, más cercanas al lenguaje humano serán sus instrucciones y, general-mente, más poderosas, ya que cada instrucción del lenguaje puede representaroperaciones complejas formadas por muchas instrucciones de la máquina.

NIVEL DEL LENGUAJE CARACTERÍSTICAS Bajo Las instrucciones del lenguaje están muy relacionadas con las instrucciones

de la computadora, por lo tanto, el programador debe tener un buenconocimiento del funcionamiento del equipo. Al programar directamente(o casi) con instrucciones de la máquina, se obtienen resultados eficientesy se puede lograr cualquier cosa que haga la computadora, aunque con un esfuerzo más grande que con otros niveles de abstracción.Como lenguaje de bajo nivel, podemos mencionar el Assembler.

Medio Si bien algunos autores ignoran este nivel, existe un grupo de lenguajes con una abstracción un poco más alta que los de bajo nivel, pero aún bastante cercana al hardware. Su sintaxis es más sencilla que la de los lenguajes de bajo nivel, pero permiten escribir programascercanos al lenguaje de la computadora.Un ejemplo típico de lenguaje de nivel medio es el lenguaje C.

Alto Este lenguaje está formado por palabras comunes en algún idioma (como por ejemplo el inglés), por lo que resultan fáciles de recordar y de interpretar. Generalmente, son lenguajes más poderosos en cuanto a expresividad que los de bajo nivel, pero puede ocurrir también que resulte difícil implementar programas que tengan que hacer un uso muy específico del hardware.Como ejemplo de lenguajes de alto nivel, podemos mencionar a C# o Java.

Tabla 1. Clasificación de los lenguajes según su nivel de abstracción.

TIPOS DE LENGUAJES …

Es muy importante tener en cuenta que, aunque los lenguajes de más alto ni-vel puedan parecerse al lenguaje natural de los seres humanos, deberán ser más

01_IntrodProg.qxd 23/7/07 20:04 Page 12

13

›LOS LENGUAJES DE PROGRAMACIÓN

estrictos y limitados, ya que es necesario que permitan definir las instruccionesde una forma entendible y sin ningún tipo de ambigüedad.

LOS LENGUAJES EN LA ACTUALIDADA lo largo del tiempo, los lenguajes han evolucionado y se adaptaron a las

necesidades y a las posibilidades computacionales de cada momento. Por eso,actualmente disponemos de una gran cantidad de lenguajes de programaciónentre los cuales elegir a la hora de comenzar un desarrollo o de aprender unanueva tecnología.

Para tomar una buena decisión y elegir el lenguaje que más nos conviene, esimportante conocer sus características, sus capacidades y debilidades. Además,un aspecto fundamental para tener en cuenta es el paradigma o enfoque del len-guaje, es decir, de qué forma hay que pensar y escribir el programa para resol-ver un problema. Los paradigmas más conocidos son el imperativo, el declara-tivo y el orientado a objetos. Mediante el paradigma imperativo, debemos in-dicar explícitamente los pasos por seguir para resolver el problema, es decir, de-bemos indicar el cómo. Por otro lado, el paradigma declarativo permite escri-bir el programa describiendo las características del problema, es decir, especifi-cando el qué. Por último, el paradigma orientado a objetos permite modelary escribir los programas a partir de la abstracción de los objetos reales que for-man parte del dominio del problema. Actualmente, el paradigma declarativo esusado en el ambiente académico y con fines de investigación, mientras que, enambientes productivos y de negocios, se utilizan los lenguajes imperativos y, enmayor medida, los orientados a objetos.

¿QUÉ ES EL ANÁLISIS LÉXICO?

La compilación de un programa esuna tarea bastante compleja, que in-volucra una serie de pasos conducen-tes a la generación del código de má-quina. El primer paso se denominaanálisis léxico. Consiste en leer eltexto del programa (normalmente al-macenado en uno o en varios archi-

vos) y aplicar ciertas reglas para iden-tificar las palabras clave y las expre-siones válidas del lenguaje de progra-mación. Durante el análisis léxico, yapueden identificarse algunos erroresbásicos, frecuentes en la mayoría delos programas, como por ejemplo, losidentificadores mal formados.

01_IntrodProg.qxd 23/7/07 20:04 Page 13

14

FUNDAMENTOS

COMPILACIÓN E INTERPRETACIÓN> Cuando escribimos un programa en algún lenguaje, nuestro propósito final siem-pre será ejecutarlo en una computadora para realizar una tarea específica. Ahorabien, al utilizar un lenguaje de programación estamos escribiendo instrucciones queno son exactamente las que la computadora entiende. Para que nuestro programapueda ser ejecutado, será necesario traducir las instrucciones que hemos escrito enforma más sencilla para que la computadora pueda entenderlas. Esta traducción re-sulta siempre necesaria para poder ejecutar un programa escrito en cualquier lengua-je. El tipo de traducción que se haga, permitirá clasificar los lenguajes en lenguajescompilados y lenguajes interpretados.

En los lenguajes compilados, la traducción se realiza por única vez, almacenandolas instrucciones ya traducidas a lenguaje máquina en un archivo. De este modo, almomento de ejecutar el programa, la computadora lee una a una las instruccionesdel archivo generado durante el proceso de compilación, y las ejecuta. Para realizarla traducción o compilación, se utiliza un programa llamado compilador, que seencarga de tomar cada una de las instrucciones escritas en un lenguaje de progra-mación y traducirlas a una o más instrucciones del lenguaje de la máquina. Duran-te la compilación, el compilador además valida que las instrucciones que hemos es-crito sean correctas y que se respeten todas las reglas del lenguaje.

Por otro lado, con los lenguajes interpretados, no existe un paso previo de com-pilación, sino que la traducción se realiza mientras se ejecuta el programa. Para ello,se utiliza un software denominado intérprete, que a medida que el programa se eje-cuta, lee cada una de las instrucciones y las traduce a instrucciones de la máquina,para que sean ejecutadas. Al igual que los compiladores, los intérpretes deben vali-dar que las instrucciones estén bien escritas para poder traducirlas sin problemas.

Generalmente, usando lenguajes compilados, se logra mayor rendimiento, ya queel proceso de validación y de traducción se realiza una sola vez (al momento de lacompilación). Luego, una vez que el programa está compilado, cada ejecución se ha-ce sobre una secuencia de instrucciones de la computadora. Al usar lenguajes inter-pretados, la validación y traducción se realiza cada vez que se ejecuta el programa.Es más, si una misma instrucción se repite varias veces, el intérprete la validará y tra-ducirá cada vez. Sin embargo, los lenguajes interpretados proveen cierto grado deflexibilidad a la hora de realizar cambios en nuestro programa ya que, modificandocualquier instrucción, estará lista para que el intérprete la tome y la traduzca.

01_IntrodProg.qxd 23/7/07 20:04 Page 14

15

›ALGORITMOS

LIBROS ÚTILES

Hay una gran cantidad de libros paraintroducirse en el mundo de la progra-mación de software y de los algorit-mos. Recomendamos, Metodología dela Programación. Algoritmos, diagra-

mas de flujo y programas, de OsvaldoCairo (ISBN 9701509404). En el cual,se proponen distintas técnicas de aná-lisis para enfrentar la solución de unproblema y llevarla a un algoritmo.

ALGORITMOS> Según el diccionario, un algoritmo es un conjunto ordenado de operacionessistemáticas que permite hacer un cálculo y hallar la solución de un tipo de pro-blemas. Por ejemplo, cualquiera de los métodos que aprendimos en la escuela pa-ra multiplicar dos números reales es un algoritmo. El método o la receta para pre-parar una comida no es un algoritmo, ya que el orden de algunos pasos, muchasveces, no importa o ni siquiera está claramente especificado (por ejemplo, pode-mos batir las claras a nieve antes o después de mezclar la harina con él azúcar, yaún así vamos a poder hacer una torta).

Ahora que conocemos los algoritmos, podemos redefinir el término programa co-mo implementación de un algoritmo determinado en un lenguaje de progra-mación. El conocimiento del concepto de algoritmo es fundamental para todo pro-gramador ya que, en la tarea diaria de escribir programas para resolver problemas,antes debemos descubrir y entender cuál es el algoritmo que los resuelve. Muchasveces, como programadores, nos encontraremos siguiendo los pasos de un algorit-mo con lápiz y papel para entender su funcionamiento o probar su eficacia.

EXPRESIÓN DE ALGORITMOSComo los algoritmos no están relacionados únicamente con la programación de

computadoras, es necesario contar con métodos independientes para expresarlosy, por lo tanto, transmitirlos a otras personas. En la actualidad, existen varias for-mas de expresar un algoritmo, como ser, el lenguaje natural, el pseudocódigo, losdiagramas de flujo, algunos diagramas del lenguaje de modelado UML (que ve-remos en el último capítulo), etcétera.

En el caso del lenguaje natural, el algoritmo es expresado por medio de ora-ciones en un idioma determinado. A modo de ejemplo, se puede indicar el al-

01_IntrodProg.qxd 23/7/07 20:04 Page 15

16

FUNDAMENTOS

goritmo, en lenguje natural, para ver una película en DVD de la siguiente ma-nera: presione la tecla Open/Close para abrir la bandeja del reproductor; luego,inserte el disco y presione la tecla nuevamente. En su televisor, seleccione la opciónDVD y por último presione la tecla Play.

PseudocódigoUno de los problemas del lenguaje natural es que suele resultar excesivamente

verborrágico, ya que debe respetar en cierta medida las reglas gramaticales dellenguaje. Para evitar este problema, se puede utilizar un pseudocódigo, que con-siste en una serie de normas sintácticas y gramaticales, parecidas a las de un len-guaje de programación, pero sin tanta rigidez, y con cierta libertad en el uso y enla combinación de las palabras.

Por ejemplo, supongamos que debemos escribir el algoritmo de Euclides paraencontrar el máximo común divisor entre dos números enteros. Usando pseudo-código, podemos consignar:

Entrada: A, B enteros

Salida: el máximo divisor común entre A y B

Mientras A > 0 hacer:

Si A > B

CARACTERÍSTICAS DE LOS ALGORITMOS

El estadounidense Donald Knuth, au-tor del libro El arte de programarcomputadoras, señaló cinco propieda-des que deberá tener todo algoritmo:Finito: un algoritmo debe tener unnúmero finito de pasos, tras los cua-les debe terminar.Preciso: cada paso debe estar defini-do con precisión, rigurosidad y sinambigüedades.Entradas: todo algoritmo debe tener

cero o más entradas, que son los da-tos que se le proporcionan como in-formación variable y específica de lainstancia del problema que resuelve.Salida: un algoritmo tiene una o mássalidas, que son el resultado del pro-blema que intenta resolver, y que de-penden de las entradas provistas.Eficacia: los pasos deben ser suficientespara lograr el cometido del algoritmo, esdecir, el algoritmo debe ser eficaz.

01_IntrodProg.qxd 23/7/07 20:04 Page 16

17

›ALGORITMOS

A := A – B

Si no

B := B – A

El Máximo Común Divisor es el contenido de A

Esto significa que la entrada al programa consiste de números enteros (A y B)y, mientras el valor de A sea mayor que cero, se le asigna a A la resta entre A y B,si A es mayor que B; si no, a B se la asigna la diferencia entre B y A. El resulta-do es el valor que queda en A luego de las sucesivas restas.

Como puede verse en el ejemplo, se especifican claramente cuáles son los datosde entrada y de salida. Además se utilizan algunos símbolos ya conocidos (comoel signo mayor a) y otros propios del pseudocódigo (como el signo := para repre-sentar que el elemento de la izquierda toma como valor el resultado de la opera-ción de la derecha).

Diagrama de flujoLos diagramas de flujo son una representación gráfica de los pasos de un algo-

ritmo. En un diagrama de flujo, cada tipo de figura tiene su significado. Su nom-bre se debe a que las figuras se conectan con flechas que indican la secuencia oflujo de operación.

Si bien muchas personas utilizan sus propios símbolos y figuras al momento decrear sus diagramas de flujo, actualmente está definido de manera clara y están-dar cuáles son las figuras válidas y cuál es su significado, de manera que cualquie-ra que las conozca pueda interpretar el diagrama.

Los símbolos más utilizados son:• Flecha: indica el sentido del proceso, es decir, hacia dónde hay que dirigirse pa-

ra encontrar el siguiente paso.

PARA TENER EN CUENTA

Al hacer un diagrama de flujo, hay quetener muy presente estos aspectos:• Debe haber un único punto de inicio

del proceso.

• Debe haber siempre un camino pa-ra llegar a la solución.

• Debe haber un único punto de findel proceso.

01_IntrodProg.qxd 23/7/07 20:04 Page 17

• Rectángulo: se usa para representar un paso determinado del algoritmo.• Rombo: representa un punto de decisión sobre la base de una condición. De

un rombo salen siempre dos flechas: una en un sentido, si se cumple la condi-ción y otra en otro sentido, si la condición no se cumple.

Para ilustrar el concepto, vamos a especificar el algoritmo de Euclides que usa-mos anteriormente, mediante un diagrama de flujo.

18

FUNDAMENTOS

� CONCLUSIONES

Para introducirse en el mundo de la programación y el desarrollo de aplica-ciones de software, es muy importante comenzar con una buena base de co-nocimiento de algoritmos y técnicas de resolución de problemas de distintotipo, sin usar un lenguaje específico (podemos usar pseudocódigo). Una vezque dominemos ciertas técnicas de resolución de problemas y podamos ex-presar las soluciones como algoritmos, estaremos preparados para apren-der lenguajes de programación que nos permitan llevar esos algoritmos auna computadora que los ejecute por nosotros.

Devolver A B < B - AA < A - B

A > B

A > 0Sí No

Sí No

Figura 2. Diagrama de flujo del algoritmo de Euclides

01_IntrodProg.qxd 23/7/07 20:04 Page 18

CAPÍTULO 2

Programaciónestructurada

En este capítulo, nos adentraremos en los principios

fundamentales de la programación y, al mismo

tiempo, iremos aprendiendo sintaxis de los

dos principales lenguajes de la plataforma .Net.

ATENCIÓN AL LECTOR > [email protected]

02_IntrodProg.qxd 23/7/07 20:05 Page 19

20

PROGRAMACION ESTRUCTURADA

MEJORAR EL CÓDIGO

> En el Capítulo 1, vimos que un programa es la implementación de un algoritmodeterminado, es decir, una secuencia de pasos o instrucciones, mediante un lengua-je de programación. Cuando escribimos un programa, es normal que necesitemosalterar la secuencia de instrucciones siguiendo determinadas pautas. Si recordamosel algoritmo que analizamos en el capítulo anterior, podemos ver que en cada vuelta,la instrucción por ejecutar depende de si A es mayor que B, o B es mayor que A.

En los primeros lenguajes de programación (como el BASIC original), la úni-ca forma que existía de variar las instrucciones por ejecutar según una condiciónera mediante un salto a otra parte del programa (generalmente, a otra posiciónde memoria u otro número de línea). Es decir, debíamos evaluar la condición y,dependiendo de si ésta era verdadera o falsa podíamos seguir en la línea de aba-jo o hacer que la próxima instrucción por ejecutar fuera diferente, ubicada enotra parte del programa.

Por ejemplo, para resolver el algoritmo de Euclides usando saltos, deberíamosescribir algo así (con pseudocódigo):

1: Si A <= 0 Ir a línea 7

2: Si A > 0 Ir a línea 5

3: B := B – A

4: Ir a línea 1

5: A := A – B

6: Ir a línea 1

7: Devolver A

Esta implementación tiene dos grandes problemas. El primero es que su es-critura se vuelve un poco dificultosa, porque hay que conocer los números delínea. Por ejemplo, al escribir la línea 1, ya hay que saber que vamos a saltar ala línea 7. Si bien esto podría solucionarse usando números de línea que va-yan, por ejemplo, de 10 en 10 y hacer los saltos a números más bien lejanos,a medida que necesitemos modificar el algoritmo y escribir más líneas de có-digo (incluso entre dos líneas ya existentes), los números disponibles se iríanacercando más y más, y podría llegar el momento en que necesitáramos renu-

02_IntrodProg.qxd 23/7/07 20:05 Page 20

21

›MEJORAR EL CÓDIGO

merar las líneas para tener más espacio. El segundo problema reside en la po-ca claridad del código. Para alguien que lo lee por primera vez, puede resultarextremadamente difícil entender.

Dados los constantes saltos hacia atrás y hacia adelante a través de las instruccio-nes del programa, este tipo de código inevitablemente enredado se conoce comocódigo spaghetti, y la instrucción más famosa para hacer saltos de línea es GOTO(del inglés go to, ir a).

HACIA LA PROGRAMACIÓN ESTRUCTURADACon el paso del tiempo, los programadores vieron que el código spaghetti resulta-

ba muy difícil de mantener, ya sea para agregar una nueva característica al programao para corregir un error. Así, en la década del 60, un científico de los Países Bajos,Edsger Dijkstra, formuló un teorema en el que demostró que cualquier programainformático puede escribirse usando sólo tres tipos de instrucciones básicas: la se-cuencia, la evaluación de condiciones y la repetición o bucle de instrucciones, ysin utilizar instrucciones GOTO. Este teorema, conocido como el Teorema deDijkstra, sentó las bases de lo que hoy conocemos como programación estructu-rada y de una gran familia de lenguajes de programación basados en este concepto.

Al escribir un programa utilizando las tres estructuras propuestas por Dijkstra,se obtienen programas mucho más claros, fáciles de entender y de mantener yaque, en todo momento, la lógica está a la vista, y resulta fácil encontrar cuál es lasiguiente instrucción por ejecutar.

Iteración

Condicional

MMiieennttrraass A > 0 hacer:

SSii A > B

A: = A - B

SSii no

B: = B - A

Imprimir A

Imprimir B

Devolver A

Secuencia}{Figura 1. En esta figura, vemos las tres estructuras

de control propuestas por Dijkstra en el algoritmo de Euclides.

02_IntrodProg.qxd 23/7/07 20:05 Page 21

22

PROGRAMACION ESTRUCTURADA

CONCEPTOS DE PROGRAMACIÓNESTRUCTURADA> En las siguientes secciones, veremos los conceptos básicos de la programación es-tructurada, junto con su implementación utilizando lenguajes de la plataforma .Net.

IDENTIFICADORES Y PALABRAS CLAVEComo vimos antes, un programa está formado por instrucciones. En los len-

guajes de programación, sobre todo en los de nivel medio y alto, las instruccio-nes están formadas por palabras que pueden pertenecer o no a algún idioma hu-mano. Como también vimos, los lenguajes de programación son más estrictosque los lenguajes naturales y no se permite el uso de cualquier palabra ni tampo-co cualquier combinación de ellas. Toda palabra que se pueda usar en un progra-ma, ya sea parte del lenguaje de programación o definida por nosotros, recibe elnombre de identificador. En todos los lenguajes de programación, los identifi-cadores deben respetar ciertas reglas para que sea más sencillo el trabajo del com-pilador o del intérprete. La forma más común de representar un identificador espor una secuencia de uno o más caracteres consecutivos (no se permiten los es-

C# Y VB.NET

Los dos lenguajes más importantesen .Net (y los únicos provistos por Mi-crosoft desde la discontinuidad de J#)son C# y Visual Basic .Net.C# es un lenguaje orientado a obje-tos, que fue diseñado especialmen-te para la plataforma .Net (inclusogran parte de las clases del frame-work están escritas en C#). Comosu nombre lo indica, C# está basadoen el leguaje C, del que se han eli-minado algunos componentes parahacerlo más seguro en cuanto al

modelo de ejecución y de adminis-tración de memoria.Visual Basic .Net es una adaptaciónpara .Net del conocido lenguaje Vi-sual Basic (que a su vez es una adap-tación del BASIC original de los años60) y como tal conserva muchas delas características (y problemas) delleguaje original. Al igual que C#, VB-.Net (como también se conoce a Vi-sual Basic .Net) está basado en el pa-radigma de Orientación a Objetos queestudiaremos en el Capítulo 4.

02_IntrodProg.qxd 23/7/07 20:05 Page 22

23

›CONCEPTOS DE PROGRAMACIÓN ESTRUCTURADA

pacios ni los saltos de línea) seguidos de caracteres o de números. Generalmen-te, no se permite que los identificadores comiencen con números.

Hay una familia de identificadores que forman parte del lenguaje de programa-ción y que sólo pueden usarse con los fines para los que fueron diseñados. Estosidentificadores reciben el nombre de palabra clave. Por ejemplo, el lenguaje C#tiene la palabra clave using, con una semántica determinada, y al ser palabra cla-ve, no podremos usarla en otro contexto.

VARIABLESEn cualquier programa que hagamos, necesitaremos manejar datos: el nombre

del usuario, el saldo de una cuenta corriente, la cantidad de veces que iteramossobre una línea de código. Y es natural que estos datos cambien de valor duran-te la vida del programa. Así, nos encontramos con uno de los conceptos más bá-sicos de la programación, el concepto de variable. Una variable es una referen-cia a un dato cuyo valor puede cambiar durante la ejecución de un programa.

Siendo un poco más formales, podemos decir que una variable es una posiciónen la memoria de la computadora, donde reside un dato significativo para el pro-grama. Para que resulte más fácil la lectura y la comprensión de los programas, lasvariables reciben nombres formados por identificadores válidos. Así, por ejemplo,

LA PLATAFORMA .NET

Microsoft .Net es una plataforma paradesarrollo y ejecución de software pre-parada para enfrentar los nuevos de-safíos en el mundo de la programaciónde aplicaciones. Esta plataforma con-siste de una familia de lenguajes deprogramación, una librería de clasescomún a todos los lenguajes de la pla-taforma y un entorno de ejecución con-trolado. Una de las características másimportantes de .Net es que el códigono se traduce directamente a instruc-ciones máquina, sino a un lenguaje in-

termedio que luego, durante le ejecu-ción del programa, es traducido a códi-go máquina. Esto brinda la posibilidadde escribir programas independientesde la plataforma de hardware y del sis-tema operativo. Además, la bibliotecade clases comunes, junto con una es-pecificación común a todos los lengua-jes (conocida como CLS o Common La-guage Specification, Especificación deLenguaje Común), permite una perfec-ta y fácil interacción entre diferenteslenguajes de la plataforma.

02_IntrodProg.qxd 23/7/07 20:05 Page 23

24

PROGRAMACION ESTRUCTURADA

en el caso de la implementación del algoritmo de Euclides que hemos estudiado,usamos dos variables, denominadas A y B. Es una buena práctica de programa-ción dar nombres significativos a las variables, de manera de hacer evidente la in-tención que tenemos al momento de definirla. Si en un programa llamamos a unavariable c, alguien que lea luego el programa (incluso podríamos ser nosotros mis-mos) no podrá entender rápidamente cuál es el dato que representa; mientras quesi usamos nombreCliente, está claro que, en la ubicación de memoria referenciadapor la variable, estamos almacenando el nombre de un cliente.

Figura 2. Según Google Trends, existe una tendencia a usar más el lenguaje C# que VB.Net, además de haber más noticias en

Internet sobre C# (fuente www.google.com/trends?q=visual+basic%2Cc%23).

TIPOS DE DATOSUn tipo de dato es el conjunto de valores que toma una variable, junto con las

operaciones que pueden realizarse sobre esos valores. En muchos lenguajes, es ne-cesario asociar una variable con un tipo de dato, de manera que el compilador ointérprete pueda validar que las operaciones que hemos escrito realmente corres-ponden al tipo de dato que manejamos. Un ejemplo de tipo de datos es el nú-mero entero. El conjunto de valores que puede tomar es el de los números ente-ros (0, 1, 2, -1, etcétera), y las operaciones que podemos realizar sobre ellos sonla suma, la resta, la multiplicación y la división de enteros.

02_IntrodProg.qxd 23/7/07 20:05 Page 24

25

›CONCEPTOS DE PROGRAMACIÓN ESTRUCTURADA

Los lenguajes que exigen que definamos el tipo de dato de las variables antes deusarlas se denominan fuertemente tipados. Desde el punto de vista de la detecciónde errores, estos lenguajes presentan una gran ventaja frente a los no tipados ya quepermiten detectar, durante la compilación (en el caso de lenguajes compilados), al-gunos errores muy habituales, como intentar asignar a una variable un dato que nole corresponde. Por ejemplo, si definimos la variable numerador como de tipo ente-ro, pero más adelante le asignamos el texto Hola Mundo, el compilador de un len-guaje fuertemente tipado detectará el problema y nos lo informará antes decompilar. Si el lenguaje no es fuertemente tipado, esto no se detectará y podría ocu-rrir que, luego, cuando queramos hacer una multiplicación entre la variable nume-rador y el valor 5, la operación resulte en un error. Al no ser detectado por el com-pilador, este error surgirá durante la ejecución del programa.

En la plataforma .Net, C# es un lenguaje fuertemente tipado, mientras que enVB.Net existe la posibilidad de indicarle al compilador que exija o no la declara-ción de los tipos de datos de las variables.

SENTENCIASLas sentencias describen acciones que serán ejecutadas por la computadora co-

mo parte del funcionamiento del programa. Éstas se diferencian de las instruc-

LOS COMENTARIOS EN C# Y EN VB.NET

Los comentarios son un caso espe-cial de sentencia no ejecutable quepermiten escribir un texto libre con elobjetivo de aumentar la legibilidad delcódigo. En cada lenguaje, la forma deescribir comentarios varía, como asítambién los tipos de comentarios quese pueden escribir (de una sola líneao de muchas líneas).En C#, los comentarios de una solalínea se escriben comenzando conlos caracteres // (por ejemplo: //es-to es un comentario), mientras que

los comentarios de muchas líneasse escriben comenzando con los ca-racteres /* y finalizando con */. En-tre ambos caracteres, puede habertexto y saltos de línea.En VB.Net, los comentarios de unasola línea se escriben comenzandocon la comilla simple (‘), y no exis-ten los comentarios múltiple línea(aunque se los puede simular escri-biendo líneas consecutivas de co-mentarios, todas comenzadas concomilla simple).

02_IntrodProg.qxd 23/7/07 20:05 Page 25

26

PROGRAMACION ESTRUCTURADA

ciones en que una sentencia puede ser traducida por el compilador o por el in-térprete en cero o más instrucciones de máquina. Es decir, una sentencia poseemayor abstracción y expresividad que una instrucción.

Las sentencias pueden clasificarse en ejecutables y no ejecutables. Las ejecuta-bles son las que se traducen en instrucciones de la máquina y se utilizan para rea-lizar acciones concretas (como sumar dos números o imprimir un texto en lapantalla del monitor). Por el contrario, las sentencias no ejecutables no se tradu-cen a instrucciones, y su única funcionalidad reside en aumentar la legibilidaddel código fuente, ya que se pueden usar como comentarios para explicar deta-lles de la implementación.

Al mismo tiempo, las sentencias pueden ser clasificadas en simples y compues-tas. Una sentencia simple es una sentencia en sí misma y no contiene a ningunaotra. Por ejemplo, la sentencia de asignación utilizada para asignar un valor a unavariable es una sentencia simple, ya que comprende únicamente la acción de asig-nar el valor a la variable. Por otro lado, las sentencias compuestas están formadaspor dos o más sentencias que se ejecutan de acuerdo con alguna estructura decontrol, tal como veremos más adelante.

OPERADORES Y EXPRESIONESAnteriormente, vimos que un tipo de datos define los posibles valores que pue-

de tomar una variable con el conjunto de operaciones o de acciones que se reali-zan sobre esos valores. Podemos definir un operador como el símbolo utilizadopara indicar una operación sobre elementos llamados operandos. Por ejemplo,para el tipo de dato número entero, está definida la operación de suma, que pue-de representarse mediante el signo +. Así, si escribimos 2 + 3, indicamos que que-remos aplicar la operación de suma a los valores (operandos) 2 y 3. Del mismomodo, si escribimos saldo + 100, mostramos que queremos sumar 100 al valoralmacenado en la variable identificada como saldo. Cuando unimos dos o másconstantes o variables mediante un operador, definimos una expresión.

Las expresiones pueden ser simples o compuestas. Una expresión simple esaquélla sólo formada por un operador con los operandos necesarios. Una ex-presión compuesta está formada por dos o más operaciones simples. En el ca-so de las expresiones compuestas, es necesario especificar con exactitud el or-den en que se resuelven las expresiones simples que las componen. En el casode operadores matemáticos, generalmente, el orden en que se resuelven es el

02_IntrodProg.qxd 23/7/07 20:05 Page 26

27

›CONCEPTOS DE PROGRAMACIÓN ESTRUCTURADA

tradicional (es decir, primero el producto y la división, y luego la suma y laresta). Si al momento de escribir la expresión no tenemos del todo claro cuáles el orden de prioridad de los operadores, podemos utilizar paréntesis para al-terar o hacer implícito el orden de resolución.

TIPOS DE OPERADORESPara no entrar en detalles muy matemáticos, podemos identificar tres grandes

tipos de operadores: los lógicos, los aritméticos y los relacionales.

Operadores lógicosLos operadores lógicos relacionan uno o más valores de verdad (es decir, valores

que pueden ser verdadero o falso), y el resultado es otro valor de verdad en funciónde los operandos. Dentro de los lenguajes de programación, los operadores lógicosse utilizan para evaluar condiciones y modificar así el flujo de control de un pro-grama. Los operadores lógicos más conocidos son no (NOT), o (OR), y (AND).En la Tabla 1, pueden apreciarse los valores devueltos por los operadores lógicos másconocidos (usamos los nombres en inglés para ir familiarizándonos con los lengua-jes de programación). En la jerga de la programación llamamos operadores boo-leanos a los operadores lógicos, por su relación con el álgebra de Boole.

A B NOT A A AND B A OR B A XOR BF F V F F FF V V F V VV F F F V VV V F V V F

Tabla 1. Tabla de verdad de los cuatro operadores lógicos más comunes.

OPERADORES BOOLEANOS …

Operadores aritméticosComo hemos visto, los operadores aritméticos se corresponden con las opera-

ciones matemáticas tradicionales: la adición, la sustracción, la potenciación.

Operadores relacionalesLos operadores relacionales, tal como su nombre lo indica, establecen una re-

lación entre sus operandos. Un ejemplo clásico de operador relacional es el ope-

02_IntrodProg.qxd 23/7/07 20:05 Page 27

28

PROGRAMACION ESTRUCTURADA

rador mayor que, notado con el símbolo >. Engeneral, los operadores relacionales devuelven unvalor de verdad, por lo que son usados en expre-siones lógicas (por ejemplo, el valor de verdad dela expresión 7 > 9 es falso).

Figura 3. George Boole fue el precursor en el álgebra de Boole, de donde se tomó el concepto de Operador lógico o booleano.

Tipos de operadoresSegún la cantidad de operadores con los que trabaja un operador puede cla-

sificarse en unario o binario. Un operador unario se aplica sólo a un opera-dor. El ejemplo más común es el signo -, utilizado para indicar números ne-gativos (por ejemplo, -15). Los operadores binarios poseen dos operandos, co-mo por ejemplo, el signo +. El caso de los operadores binarios puede exten-derse y generalizarse para una cantidad cualquiera de operadores, en cuyo ca-so se denominan operador n-arios, donde n es la cantidad de operandos. Co-mo ejemplo, podemos imaginar un operador 4-ario llamado M que devuelveel máximo entre cuatro números. Una operación con este operador podría es-cribirse como M 7 2 0 9.

Según el lugar donde están los operadores con respecto a los operandos enuna operación, un operador puede clasificarse en infijo, prefijo o sufijo. Unoperador prefijo se coloca delante de los operadores. El ejemplo que veíamosantes para el signo -, usado como operador unario, es un caso de operador

EL LENGUAJE PASCAL

El lenguaje Pascal fue creado por Ni-klaus Wirth con el objetivo de lograrun lenguaje fácil de aprender, parausar en sus clases de programación,y lo bautizó en honor a Blaise Pascal,inventor de la primera calculadoramecánica. Pascal es un lenguaje es-

tructurado y fuertemente tipado, ade-más de contar con características quehacen posible un buen grado de en-capsulamiento. Actualmente, muchasuniversidades lo siguen utilizando pa-ra introducir los conceptos de progra-mación estructurada.

02_IntrodProg.qxd 23/7/07 20:05 Page 28

29

›CONCEPTOS DE PROGRAMACIÓN ESTRUCTURADA

prefijo. Si el operador se coloca entre los operandos, entonces de denominainfijo (es el tipo más común entre los operadores matemáticos). Por ejemplo,el signo de adición (+) es un operador infijo, ya que se lo escribe entre los ope-randos (2 + 4). Por último, los operadores sufijos son aquellos que se colocandetrás de los operandos. Un ejemplo no tan conocido es el operador ++ dellenguaje C#. Este operador devuelve el valor del operador y luego le suma uno(podemos escribir por ejemplo: a++).

ESTRUCTURAS DE CONTROLNormalmente, el flujo de ejecución de un programa es secuencial, porque se

ejecuta una sentencia tras otra. Las estructuras de control permiten modificarel flujo secuencial, alterando el orden de las sentencias bajo determinadas cir-cunstancias. En los lenguajes estructurados, existen dos estructuras de controlbásicas: la selección y la repetición o iteración. Según el teorema de Dijkstra,estas dos estructuras, junto con la secuencia, son suficientes para escribir cual-quier programa.

La estructura de selecciónLa estructura de selección permite determinar si una sentencia (simple o com-

puesta) será ejecutada o no a partir de la evaluación de una determinada condi-ción o expresión booleana. En la mayoría de los lenguajes actuales, la selecciónse realiza mediante el uso de la estructura if (si). La forma más básica de esta es-tructura es la siguiente (en pseudocódigo):

Si (expresión booleana)

Entonces ejecutar sentencia A

Si no ejecutar sentencia B

La segunda parte (la del si no) es optativa y permite ejecutar una acción alter-nativa para cuando el resultado de la expresión lógica es falso.

En C#, la estructura de selección se escribe mediante la palabra if seguida dela expresión entre paréntesis y debajo la sentencia por ejecutar en caso de que laexpresión sea verdadera. En forma opcional, puede haber un else (si no) para es-pecificar una acción en caso de que la expresión lógica sea falsa.

02_IntrodProg.qxd 23/7/07 20:05 Page 29

30

PROGRAMACION ESTRUCTURADA

// C#

if( saldo > montoExtraccion )

RealizarExtraccion(montoExtraccion);

else

MostrarMensaje(“No tiene suficiente saldo”);

En Visual Basic .Net, la estructura de selección es muy similar, aunque con al-gunas diferencias: la expresión no necesita ir entre paréntesis y debe ser seguidapor la palabra reservada THEN (entonces). Además, VB.Net provee la posibilidadde escribir la acción en la misma línea del if o en la línea siguiente. En caso quese escriba debajo, la estructura debe ser cerrada usando end if.

‘ VB.Net

If saldo > montoExtraccion Then

RealizarExtraccion(montoExtraccion)

Else

MostrarMensaje(“No tiene suficiente saldo”)

End If

‘ Tambien podemos hacer esto:

If b > 0 Then c = a / b else c = 0

En muchos lenguajes, existe otra estructura de selección alternativa, denominadacomúnmente case o select case, que permite especificar varias alternativas por ca-

CLASIFICACIONES DE LOS TIPOS DE DATOS

Los tipos de datos pueden clasificar-se en tres grupos: los ordinales, losno ordinales y los compuestos. Los ti-pos de datos ordinales son aquelloscuyos valores pueden ser ordenados(se establece una relación de ordenentre cualquier par de valores), comopor ejemplo, los números enteros o

los caracteres de la tabla ASCII. Losvalores de los tipos no ordinales nopueden ordenarse, como es el casode los números decimales de granprecisión o los punteros a memoria.Los tipos de datos compuestos inclu-yen las cadenas de caracteres y lasestructuras de datos.

02_IntrodProg.qxd 23/7/07 20:05 Page 30

31

›CONCEPTOS DE PROGRAMACIÓN ESTRUCTURADA

sos, según el valor de una variable o de una expresión. Si bien el select case puedeescribirse perfectamente como una secuencia de estructuras if, en pseudocódigo,podemos escribir la selección múltiple de esta manera:

SegunEsElValorDe expresión hacer:

C1: sentencia 1

C2: sentencia 2

Sino: sentencia n

El funcionamiento de esta estructura es así: se evalúa la expresión, y su valor secompara con la lista de constantes C1, C2, etcétera. Si el valor de la expresión es-tá comprendido en la lista de constantes, se ejecuta la sentencia correspondiente(por ejemplo, si el valor de la expresión es C2, se ejecuta la sentencia 2). Si el va-lor de la expresión no está en la lista de constantes, y hay un sino, se ejecuta la sen-tencia asociada a éste, caso contrario, la ejecución continúa en la línea siguiente.

En C#, la estructura de selección múltiple cumple la misma función, pero sedenomina switch, y su sintaxis es la siguiente:

// C#

switch(variable)

{

case 10:

HacerAlgo();

break;

case 20:

HacerOtraCosa();

break;

default:

HacerAlgoDistinto();

break;

}

En Visual Basic .Net, la misma estructura selectiva múltiple se denomina Se-lect Case y se escribe así:

02_IntrodProg.qxd 23/7/07 20:05 Page 31

32

PROGRAMACION ESTRUCTURADA

‘ VB.Net

SELECT CASE variable

CASE 10: HacerAlgo()

CASE 20: HacerOtraCosa()

CASE ELSE: HacerAlgoDistinto();

END SELECT

Las estructuras de repeticiónMuy a menudo, necesitamos repetir una sentencia más de una vez para completar

el objetivo del algoritmo. Las estructuras de repetición de los lenguajes estructura-dos permiten ejecutar una sentencia una cierta cantidad de veces o mientras se cum-pla una determinada condición. Por ejemplo, si volvemos a mirar el algoritmo delCapítulo 1, podremos notar que repetimos las sentencias que hacen las restas entre lasdos variables mientras que el valor de la variable A sea mayor que cero.

Como decíamos en el párrafo anterior, la mayoría de los lenguajes estructuradosproveen dos tipos de estructuras de repetición: una para repetir una sentencia mien-tras se cumpla una condición (es decir, mientras el resultado de evaluar una expre-sión lógica sea verdadero), y otra para repetir una sentencia una cantidad determi-nada de veces. La sentencia que se ejecuta repetidas veces se denomina bucle.

La estructura de repetición condicional se denomina comúnmente while(mientras). En el lenguaje C#, simplemente se la escribe seguida de la expresiónlógica entre paréntesis y debajo la sentencia a ejecutar:

// C#

While( a > 0 )

a = a - b;

En Visual Basic .Net, es muy similar, con la diferencia que se debe marcar el fi-nal de la estructura con las palabras clave End While, y no es necesario escribirla expresión booleana entre paréntesis:

‘ VB.Net

While a > 0

a = a - b

End While

02_IntrodProg.qxd 23/7/07 20:05 Page 32

33

›CONCEPTOS DE PROGRAMACIÓN ESTRUCTURADA

En algunos lenguajes, existe una variante de esta estructura de repetición, consisten-te en evaluar la expresión lógica al final. La diferencia radica en que, al evaluar la con-dición al final, la sentencia por repetir se ejecutará por lo menos una vez, mientrasque, si la evaluación se hace al comienzo, la sentencia podría no ejecutarse nunca.

Al momento de usar una estructura while, se debe prestar especial atención a laexpresión lógica que determina el fin del bucle (también conocida como condi-ción de corte), ya que escribirla mal, podría hacer que el bucle nunca finalizara(bucle infinito). Por ejemplo, si la condición de corte es que el valor de una va-riable llegue a cero, pero olvidamos modificarlo dentro del bucle, el valor perma-necerá constante, y el ciclo nunca finalizará.

La otra estructura de control repetitiva con la que disponemos en la mayoría delos lenguajes estructurados es la que se conoce como For. Esta estructura permi-te especificar que se quiere repetir la sentencia una cantidad finita de veces, usan-do una variable como contador. A cada iteración, la variable contador se incre-menta automáticamente (es decir, no necesitamos preocuparnos por actualizarlacomo sucede con while). En algunos lenguajes, como Pascal, no se permite mo-dificar la variable contadora dentro del bucle para facilitar la traducción y valida-ción del código durante la fase de compilación.

En C#, la estructura for es un poco difícil de comprender al comienzo, perouna vez que nos familiarizamos con ella, vemos que tiene una gran capacidad deexpresividad y de flexibilidad para escribir repeticiones complejas. Al escribir unfor en C#, debemos especificar el valor con el que comienza la variable conta-dora, la condición que determina que el contador ha llegado al valor final y laexpresión que incrementa el contador. Esto último parece contradecir lo quemencionábamos antes acerca de que no es necesario preocuparnos por modifi-car el contador. Y es cierto. En ese aspecto, la estructura for de C# es parecidaa la estructura while. Veámosla en un ejemplo:

// C#

for(i=0;i<10;i++)

HacerAglo();

Como se puede ver en el ejemplo, la estructura consta de tres partes fundamen-tales separadas por punto y coma. La primera especifica el valor del contador con

02_IntrodProg.qxd 23/7/07 20:05 Page 33

34

PROGRAMACION ESTRUCTURADA

el que comienza la iteración. La segunda, la condición para finalizar. Y la últimaespecifica la expresión que modifica el valor del contador en cada iteración. Eneste ejemplo, la sentencia HacerAlgo se ejecutará diez veces. El for de C# sopor-ta algunas variantes que lo hacen más complejo y potente, pero su explicación ex-cede el alcance de este libro.

En Visual Basic .Net, la estructura for es mucho más sencilla e intuitiva, perotambién menos potente. Además, se diferencia de la versión en C# en que debeser cerrado con la palabra reservada Next (siguiente). Continuando con el ejem-plo anterior, en Visual Basic podemos escribir:

‘VB.Net

For i=1 to 10

HacerAglo()

Next

En este ejemplo, la sentencia HacerAlgo se repetirá diez veces, y, en cada itera-ción, el valor de la variable i se incrementará automáticamente en 1.

� CONCLUSIONES

En el momento de su aparición, la programación estructurada significó un im-portante avance en las formas de construir software, sobre todo por el impac-to que causó en los costos de mantenimiento. La facilidad de mantenimientose debe a que, con la programación estructurada, conseguimos programasmás fáciles de entender y de depurar (por la ausencia de instrucciones GOTO),además, los bloques de código son más claros.

02_IntrodProg.qxd 23/7/07 20:05 Page 34

CAPÍTULO 3

Elementos deprogramación

En el capítulo anterior, hemos introducido los conceptos

fundamentales de la programación estructurada,

tal como fue planteada por Dijkstra en su famoso

teorema. Ahora veremos algunos conceptos interesantes

que, si bien se encuentran en la mayoría de los

lenguajes estructurados de la actualidad, son un poco

más generales y pueden aplicarse, prácticamente,

en cualquier paradigma de programación.

ATENCIÓN AL LECTOR > [email protected]

03_IntrodProg.qxd 23/7/07 20:41 Page 35

36

ELEMENTOS DE PROGRAMACIÓN

MODULARIZACIÓN> En nuestro trabajo como programadores, nos encontramos a diario con laobligación de resolver problemas. A medida que la tecnología avanza y las ne-cesidades de los usuarios son más exigentes, los problemas que debemos resol-ver se tornan más complejos. Esto hace que la escritura de los programas seabastante difícil, y que su complejidad los vuelva inaccesibles. Tarde o tempra-no, la cantidad de variables y elementos que debemos manejar superará los lí-mites normales de la mente humana.

Una técnica muy común para facilitar la escritura de programas de gran tama-ño o que necesiten resolver problemas muy complejos consiste en dividir el pro-blema en problemas más pequeños. De esta manera, cada dificultad será más fá-cil de entender y, por lo tanto, resultará más sencillo encontrar un algoritmo quelo resuelva. Así, la construcción del programa se reduce a la construcción de pe-queñas unidades o subprogramas que se conectan de alguna manera para resol-ver juntas el problema original. Esta técnica se conoce como Modularización, ya cada subprograma se lo denomina módulo.

Un programa escrito usando la técnica de modularización se resume en unconjunto de subprogramas que se llaman unos a otros. Cada programa incluyeuna lista de sentencias (de cualquiera de los tres tipos que estudiamos en el ca-pítulo anterior) y, eventualmente, llamadas a otros subprogramas. Cuando ha-blamos de llamar o invocar a un subprograma, lo que queremos decir es que,desde un subprograma (o incluso desde el programa principal), se deriva la eje-cución al subprograma llamado. Por ejemplo, en el siguiente pseudocódigo:

Programa Principal:

1 A()

2 B()

3 Fin.

Subprograma A:

3 Imprimir la palabra “Hola”

Subprograma B:

4 Imprimir la palabra “Mundo”

03_IntrodProg.qxd 23/7/07 20:41 Page 36

37

›MODULARIZACIÓN

El programa principal llama o invoca al subprograma A y luego al subpro-grama B. Y aquí surge uno de los primeros conceptos clave de la modulariza-ción: un subprograma o módulo debe ser un algoritmo en sí mismo (de acuer-do con la definición que vimos en el Capítulo 1), es decir, que debe consistir deuna secuencia finita de pasos tras la cual finaliza. Entonces, cuando se hace unallamada a un subprograma, éste se ejecuta (o sea, se ejecutan sus sentencias) y,al terminar, el control vuelve al punto desde donde se hizo la invocación. Re-tornando sobre el ejemplo anterior, concluimos que la secuencia de ejecuciónserá: comienza el programa, se deriva la ejecución al subprograma A, se impri-me la palabra Hola, el control vuelve a la línea 2, se deriva el control al sub-programa B, se imprime la palabra Mundo, el control vuelve a la línea 3, y elprograma termina.

PROCEDIMIENTOS Y FUNCIONESLos módulos se pueden clasificar en procedimientos y en funciones. Las fun-

ciones devuelven un único valor al programa o subprograma que hizo la llama-da. Los procedimientos, generalmente, no devuelven ningún valor, aunque po-drían hacerlo. Las funciones se usan para resolver algún cálculo y devolver el re-sultado, mientras que los procedimientos se utilizan para realizar una tarea con-creta, pero que no involucre devolver nada al programa o subprograma que lo lla-mó. En la mayoría de los lenguajes de programación, los procedimientos y fun-ciones deben recibir un nombre consistente en un identificador válido según lasreglas léxicas del lenguaje.

Otra de las ventajas de la división en subprogramas reside en que nos permi-te usar el mismo grupo de sentencias varias veces en el mismo programa sin ne-cesidad de volver a escribirlas. Sin embargo, lo más probable es que en los dis-tintos lugares donde podamos llamar a un procedimiento o función, los datos

DIVIDE Y VENCERÁS

La técnica de dividir un problema enproblemas más pequeños que seanmás fáciles de resolver se conoce ha-bitualmente como la técnica de Divi-dir y vencer, en referencia a pensa-

mientos de Nicolás Maquiavelo. En sulibro El Príncipe, Maquiavelo hablasobre generar discordia entre lospueblos, de manera que se separen yasí poder dominarlos más fácilmente.

03_IntrodProg.qxd 23/7/07 20:41 Page 37

38

ELEMENTOS DE PROGRAMACIÓN

que necesitamos manejar no sean los mismos. Es necesario, entonces, poderpasarle información adicional al subprograma. Esto se realiza mediante el usode parámetros o argumentos. Un parámetro es una variable que el procedi-miento o función recibe como dato de entrada y que puede usar para cambiarsu comportamiento sobre la base del valor recibido (usando, por ejemplo, unasentencia condicional).

Los parámetros del argumento pueden ser de entrada o de salida. Los de en-trada son los que el programa o módulo que llama le pasa al subprograma,mientras que los parámetros de salida son aquellos que el procedimiento ofunción utiliza para devolver información a quien lo llamó. Es importante noconfundir un parámetro de salida con el resultado de una función: los pará-metros de salida pueden ser usados tanto en procedimientos como en funcio-nes, y se puede utilizar la cantidad que sea necesaria, mientras que el valor deresultado sólo se puede usar en las funciones, y no puede haber más de unopor función.

Para ilustrar el uso de funciones, retomemos el ejemplo del algoritmo de Eucli-des y convirtámoslo en una función (en pseudocódigo):

Funcion MCM(A,B)

Mientras A > 0 hacer:

Si A > B

A := A – B

Si no

B := B – A

Devolver A

En este caso, la función se llama MCM y posee dos parámetros de entrada, detipo numérico, A y B. La función MCM consiste de una única sentencia de re-petición que hace restas sucesivas entre A y B y, finalmente, devuelve el valorde A como resultado de la función.

Para entender el uso de una función, vamos a utilizar la función MCM del ejem-plo anterior dentro de un procedimiento:

03_IntrodProg.qxd 23/7/07 20:41 Page 38

39

›MODULARIZACIÓN

Procedimiento MostrarMCM()

Pedir un numero y guardarlo en V1

Pedir un numero y guardarlo en V2

M := MCM(V1, V2)

Mostrar valor de M

En el ejemplo, se pide al usuario que ingrese un número y se lo almacena en lavariable V1. Se hace lo mismo con la variable V2. Luego, a la variable M se leasigna el resultado de la función MCM llamada con los valores V1 y V2 (los pará-metros A y B del ejemplo). Por último, se muestra el valor de la variable M.

Ámbito de variablesEl ámbito de una variable es el contexto o porción de programa en el que la

variable está definida, es conocida y accesible para ser usada. Si bien cada lengua-je de programación tiene sus propias reglas de ámbito (es decir, las reglas que de-finen dónde es accesible una variable definida en algún punto de un programa),los subprogramas delimitan el ámbito de las variables.

Si el ámbito de una variable incluye sólo un subprograma, entonces se dice quees una variable local (local al procedimiento o función), mientras que si abarcatodos los módulos, la variable será global. Una variable local sólo existe mientrasse ejecuta el subprograma que la contiene, mientras que una variable global exis-te durante toda la ejecución, y su valor puede consultarse o modificarse desdecualquier punto del programa o subprogramas.

Algunos lenguajes de programación como Pascal permiten escribir programasdentro de subprogramas, lo cual agrega niveles extras de visibilidad o ámbitode las variables, ya que una variable local a un procedimiento puede ser acce-

USO DE PARÁMETROS DE ENTRADA Y DE SALIDA

Si bien un procedimiento puede tenerparámetros de salida, esto suele noresultar en una buena práctica de pro-gramación. A menos que no podamoshacer otra cosa, si necesitamos devol-

ver un valor desde un subprograma,siempre es mejor usar una función.Esto dará un único punto de salida alsubprograma, mejorando la claridad yla legibilidad del código.

03_IntrodProg.qxd 23/7/07 20:41 Page 39

40

ELEMENTOS DE PROGRAMACIÓN

dida desde un procedimiento interno (Figura 1). En C# y Visual Basic .Net, lasreglas de ámbito determinan que las variables pueden ser globales dentro deuna clase (ya veremos qué es una clase en el siguiente capítulo), o locales a unprocedimiento o función.

Programa principal

Declarar variable A

A:=2

Llamar a B()

Procedimiento (B)

Declarar variable B1

B1:=A*2

Llamar a C()

Procedimiento C()

Declarar variable C1

C1:=B1*3

A:=C1+1

Fin procedimiento C

Fin procedimiento B

Al ejecutar el programa, la variable A

tendrá el valor 13, como resultado de

la asignación global que se hace en el

procedimiento C.

La variable A es global al programa.

La variable B1 es local al

procedimiento B.

La variable B1 es local al procedimiento

B, pero como el procedimiento C

está dentro de B, la variable B1 se

convierte en global para C. La variable

C1 es local al procedimiento C.

Figura 1. Algunos lenguajes permiten definir procedimientosdentro de otros, extendiendo el ámbito de las variables locales.

Un punto importante por tener en cuenta es que el ámbito de las variablesse ve reducido cuando hay un conflicto de nombres. En los casos en que seproduzca este conflicto, el ámbito se resuelve asignando prioridad a la varia-ble que se encuentra definida más adentro en el anidamiento de programa ysubprogramas. En estos casos, decimos que la variable de más adentro ocultaa la de más afuera. Esto significa que, si tenemos una variable visible desde unprocedimiento y dentro de ese procedimiento declaramos una variable con el

03_IntrodProg.qxd 23/7/07 20:41 Page 40

41

›MODULARIZACIÓN

mismo nombre, esta última tendrá prioridad sobre la global, y al asignarle unvalor, se asignará a la variable local.

Programa principal

Declarar variables A y B

A:=2

B:=3

Llamar a P1(B)

Procedimiento P1(A)

Declarar variable B

B:=A*2

Imprimir B

Mediante esta llamada se pasa el valor de

B como parámetro A al procedimiento P1.

El procedimiento P1 tiene un parámetro

llamado A, que por estar en un nivel de

anidamiento más interno ”oculta” a la

variable A del programa principal.

La variable B de P1 oculta a la variable B

del programa principal, por lo que el

procedimiento P1 imprimirá el valor 6.

Figura 2. En este ejemplo, se puede ver el conceptode ocultamiento con variables y con parámetros.

Parámetros por valor y por referenciaExisten dos formas de pasar parámetros a un procedimiento o función: por valor

o por referencia. Al pasar un parámetro por valor, tal como su nombre lo indica,lo que le estamos pasando al subprograma es el valor de la variable, es decir, que elsubprograma recibe una copia de la variable original con el valor de ella. Al pasar

¡CUIDADO CON LAS VARIABLES GLOBALES!

Muchas veces las variables globa-les son tentadoras, porque evitan lanecesidad de pasar parámetros deun subprograma a otro para utilizarel valor de una variable. Sin embar-go, en la práctica, el uso indiscrimi-

nado de variables globales no es re-comendado porque dificulta elmantenimiento del programa, dadoque es difícil determinar en quémomento una variable global reci-bió algún valor.

03_IntrodProg.qxd 23/7/07 20:41 Page 41

42

ELEMENTOS DE PROGRAMACIÓN

un parámetro por referencia, lo que se le pasa al subprograma es la dirección de me-moria donde se encuentra el valor de la variable. Es decir, se le pasa una referenciaal valor. Dado que se pasa la dirección de memoria donde se encuentra el valor,cualquier asignación que se le haga al parámetro se efectuará en realidad sobre lavariable original, ya que se escribe en la misma dirección de memoria.

Muchos lenguajes de programación (entre ellos Visual Basic .Net) no tienen elconcepto de parámetro de salida como parte del lenguaje, por lo que es necesa-rio utilizar parámetros por referencia para devolver un valor al programa o sub-programa que hizo la llamada.

Procedimientos y funciones en C# y Visual Basic .NetObviamente, los dos lenguajes de .Net provistos por Microsoft proveen meca-

nismos para definir subprogramas.

En C#, el concepto de procedimiento no existe como tal, sino que todo sonfunciones. Sin embargo, es posible definir procedimientos como funciones queno devuelven un resultado, utilizando el tipo de dato void (que es un tipo de da-tos nulo). En Visual Basic .Net, los procedimientos se definen mediante la pala-bra clave Sub. Veámoslo con ejemplos.

// C#

void HolaMundo()

{

Console.WriteLine(“Hola Mundo”);

}

‘ VB.Net

Sub HolaMundo()

Console.WriteLine(“Hola Mundo”)

End Sub

En el caso de C#, el procedimiento (que en realidad es una función) comienzacon el tipo de dato devuelto, void, seguido del nombre del procedimiento con lalista de parámetros entre paréntesis (que en el ejemplo está vacía). La secuenciade sentencias que compone el procedimiento en C# está delimitado por las lla-

03_IntrodProg.qxd 23/7/07 20:41 Page 42

43

›MODULARIZACIÓN

ves de apertura y cierre (los caracteres { y }). Por otro lado, en VB.Net, la defini-ción del procedimiento comienza con la palabra clave Sub, seguida del nombredel procedimiento y la lista de parámetros. A diferencia de C#, en Visual Basic.Net no se utilizan caracteres para marcar el comienzo de las sentencias del pro-cedimiento, pero sí se utiliza End Sub para marcar el fin.

La forma de definir una función en C# es igual que en el ejemplo anterior,reemplazando la palabra void por el tipo de dato que se necesite devolver (porejemplo, int para enteros). En VB.Net, la definición de una función es sustan-cialmente diferente, ya que debe utilizarse la palabra reservada Function en lu-gar de Sub, y se le agrega al final el tipo de dato de salida. Además, como con losprocedimientos, en VB.Net hay que marcar el fin de la función con End Func-tion. Como requisito extra, en ambos lenguajes es obligatorio colocar la palabrareturn para devolver el resultado de la función.

// C#

int Sumar(int a, int b)

{

return a + b;

}

‘ VB.Net

Function Sumar(a, b as Integer) As Integer

Return a + b

End Function

LAS DLLS EN WINDOWS

El sistema operativo Windows estáformado por unas cuantas decenas deDLLs. Un detalle interesante sobre es-to es que esas DLLs poseen las fun-ciones y procedimientos que Windowsutiliza para hacer todo lo que hace, yestán lo suficientemente documenta-

das como para que podamos utilizar-las en nuestros programas cuandonecesitemos hacer algo que el len-guaje no tiene previsto. Este conjuntode DLLs se denomina API (ApplicationProgrammer Interface o Interfaz parael programador de aplicaciones).

03_IntrodProg.qxd 23/7/07 20:41 Page 43

44

ELEMENTOS DE PROGRAMACIÓN

LIBRERÍAS

> Una de las grandes ventajas de la modularización reside en que los módulospueden utilizarse en distintos lugares. Para ello, resulta muy común organizarlosen librerías. Una librería o biblioteca es un conjunto de subprogramas compi-lados en un único archivo.

En algunos lenguajes (sobre todo los más viejos), al compilar un programa se ge-nera un archivo denominado programa objeto, que es el código máquina genera-do a partir del código fuente del programa, pero sin incluir el código de las libre-rías utilizadas. Luego, en un segundo paso denominado enlace (linking) se combi-na el programa objeto con las librerías para producir un único archivo ejecutable.

En los lenguajes de programación que permiten compilar código para ejecutaren el sistema operativo Windows, es muy común el uso de librerías de enlace di-námico (los conocidos archivos DLL, acrónimo de dynamic link library). Elenlace dinámico consiste en saltear el paso de enlace durante la compilación pa-ra hacerlo durante la ejecución de un programa. Así, mientras un programa seejecuta, si necesita código que se encuentra en una librería, se coloca ésta en me-moria, y se transfiere el control al subprograma necesario dentro de la librería.

Figura 3. En .Net podemos crear librerías de clases,que se comportarán como librerías de enlace dinámico.

03_IntrodProg.qxd 23/7/07 20:41 Page 44

45

›ARREGLOS Y MATRICES

ARREGLOS Y MATRICES

> Las estructuras de datos son conjuntos de datos relacionados y organizados dealguna manera (la forma de organizarlos depende justamente de la estructura usa-da). Desde un punto de vista más formal, las estructuras de datos son tipos de da-tos (complejos), ya que determinan los valores que pueden contener y las operacio-nes que se les pueden aplicar. De acuerdo a cómo se administra la memoria paraalmacenar la información, las estructuras de datos se pueden clasificar en estáticasy dinámicas. Las estructuras estáticas ocupan una cantidad fija de memoria duran-te toda su vida. El tamaño queda establecido al momento de definir la estructura,es decir, cuando definimos una variable del tipo de la estructura de datos. Las es-tructuras dinámicas tienen un tamaño inicial, pero pueden crecer durante la ejecu-ción, a medida que se incrementa la cantidad de datos que almacenan.

ARREGLOSLos arreglos o vectores (Arrays) son estructuras de datos que permiten almacenar

una colección de datos del mismo tipo, de manera que pueden ser accedidos en for-ma directa. Dicho de otra manera, los arreglos son una sucesión contigua de n da-tos (donde n es el tamaño del arreglo), cada uno con un índice determinado por laposición. Así, es posible acceder a un elemento del arreglo mediante su índice. Unarreglo tiene un único nombre, y éste abarca a todos los elementos que contiene.

El arreglo es una secuencia de datos contiguos

en memoria.

A[0]

Luego del arreglo pueden seguir datos

de cualquier tipo.

Figura 4. Los elementos de un arreglo ocupan posiciones contiguas de memoria.

50 0 80 30 55 27 10 Pérez tue

A[1] A[6]

03_IntrodProg.qxd 23/7/07 20:41 Page 45

46

ELEMENTOS DE PROGRAMACIÓN

Normalmente, los arreglos son estructuras estáticas de datos, pero algunos len-guajes de programación permiten cambiarles el tamaño mientras se ejecutan.

Para entender la utilidad de los arreglos, pensemos que necesitamos almacenar elregistro de lluvias de cada mes para una ciudad. Sin usar arreglos, deberíamos tenerdoce variables para contener el registro pluvial de los doce meses del año. Esta alter-nativa presenta algunas desventajas: es tediosa para programar, ya que hay que de-clarar cada una de las variables con un nombre diferente. Además, se hace imposi-ble recorrerlas mediante una estructura de repetición. Por último, si queremos hacerque el usuario ingrese el número de mes y mostrar las lluvias de ese mes, deberíamoshacer un select case para mostrar la variable correspondiente al mes ingresado.

Si en cambio utilizamos un arreglo, tendremos los doce valores bajo un mis-mo nombre de variable y podremos acceder al registro pluvial del n-ésimo mesdirectamente leyendo el elemento del arreglo ubicado en la posición n. Supon-gamos que la variable se denomina lluvias; entonces, podemos escribir un al-goritmo como el que sigue para mostrar el registro de lluvias de un mes selec-cionado por el usuario:

// Pseudocódigo:

Procedimiento MostrarRegistroPluvial

Leer un entero y guardarlo en la variable mes

Mostrar el valor de lluvias[mes]

Aquí vemos una notación sintáctica que hasta ahora no habíamos visto: llu-vias[mes]. Esta expresión significa: el dato que se encuentra en la posición mes

EL PRIMER ELEMENTO

Cada lenguaje de programación tie-ne diferentes posturas a la hora dedefinir las dimensiones de un arre-glo, como así también de definircuál es el índice del primer elemen-to. Lenguajes como Delphi permitendefinir los índices de un arreglo co-menzando con cualquier número

(por ejemplo, podemos indicar quelos índices van del 50 al 100). Otroslenguajes permiten definir el tama-ño del arreglo, y el primer elementoqueda fijado por una convención dediseño. En .Net, todos los índices dearreglos y colecciones comienzansiempre en cero.

03_IntrodProg.qxd 23/7/07 20:41 Page 46

47

›ARREGLOS Y MATRICES

dentro del arreglo (el valor que está dentro de los corchetes representa el índiceal que se quiere acceder). En el ejemplo, hemos usado una variable como índi-ce del arreglo, pero se puede usar también un valor constante, por ejemplo llu-vias[2] para acceder a las lluvias de febrero.

Arreglos en .NetObviamente, los lenguajes de .Net proveen soporte para la creación y uso de

arreglos. En C#, los arreglos son estáticos, mientras que, en Visual Basic .Net,pueden ser dinámicos. En ambos lenguajes, los arreglos se definen declarando sutamaño y el tipo de los elementos. El primer índice es siempre el cero.

// C# - Defino un arreglo de 2 enteros

int[] arreglo = new int[2];

arreglo[0] = 1;

arreglo[1] = 20;

‘ VB.Net – Defino un arreglo de 2 enteros

Dim arreglo(2) as Integer

Arreglo(0) = 1

Arreglo(1) = 2

MATRICESSi bien las matrices tienen un origen en la matemática, en el contexto de la pro-

gramación son estructuras de datos que permiten organizar la información en fi-las y columnas. Cada elemento de una matriz puede ser accedido por un par deíndices (la fila y la columna). Al igual que en los arreglos, los elementos de unamatriz deben ser todos del mismo tipo de datos.

ESTRUCTURAS DE DATOS MÁS COMPLEJAS

Los arreglos y matrices son estructu-ras de datos básicas. En muchas oca-siones, necesitamos trabajar con es-tructuras más complejas. En .Net, dis-ponemos de tipos de datos para mane-jar estructuras como listas, pilas o co-

las, entre otras. Una pila es similar aun arreglo, en donde sólo podemos co-locar elementos al principio y sacar delmismo lugar. En una cola, sólo pode-mos ubicar elementos al final y quitarelementos del comienzo.

03_IntrodProg.qxd 23/7/07 20:41 Page 47

7

3

14

0

4

1

49

99

0

18

2

17

48

ELEMENTOS DE PROGRAMACIÓN

Figura 5. Una matriz está organizada en filas y columnas. Cada elemento se accedemediante un índice compuesto por el número de fila y por el número de columna.

Columna

Elemento (3,4)

Fila

Desde el punto de vista de su almacenamiento en memoria, la matriz puede servista como un arreglo de filas, donde cada fila es un arreglo de elementos. Vistode esta manera, una matriz es, en definitiva, un arreglo de elementos de tipo dedato arreglo. Es decir, un arreglo bidimensional.

A la hora de recorrer una matriz, se debe prestar atención a no confundir los índi-ces de los elementos, teniendo bien presente en qué columna y en qué fila está cadauno de los que necesitamos acceder. Dada su estructura de dos dimensiones, la for-ma de recorrer una matriz es mediante dos estructuras repetitivas anidadas, una pa-ra recorrer las filas y la otra para recorrer las columnas. Dependiendo del orden enque se quiera hacer el recorrido, se iterará primero sobre las filas y luego sobre las co-lumnas, o primero sobre las columnas y luego sobre las filas. Para saber si hemos im-plementado correctamente el recorrido, podemos tomar una matriz de ejemplo y se-

FXCOP

Luego del surgimiento de .Net, Micro-soft publicó documentos con estánda-res de codificación y buenas prácticasde programación, con el objetivo deque todos los programadores escribie-ran código de la misma manera. Exis-te un programa llamado FxCop, dispo-

nible en www.gotdotnet.com/Team/FxCop/. Este programa analiza en-samblados ya compilados de .Net y ge-nera una lista con las violaciones a losestándares definidos por Microsoft.Actualmente, FxCop fue incorporadoen algunas ediciones de Visual Studio.

03_IntrodProg.qxd 23/7/07 20:41 Page 48

49

›ARREGLOS Y MATRICES

guir con lápiz y papel cada uno de los pasos del algoritmo, verificando el resultadoobtenido (esto se conoce como Prueba de Escritorio).

Matrices en .NetLa definición de matrices en los lenguajes de .Net que estamos estudiando resul-

ta muy similar a la definición de arreglos, con el agregado de la segunda dimensión.

// C# - Defino una matriz de 2 filas y 3 columnas

int[,] matriz = new int[2,3];

matriz [0,1] = 1;

matriz [0,2] = 20;

‘ VB.Net – Defino una matriz de 2 filas y 3 columnas

Dim matriz (2,3) as Integer

matriz (0,1) = 1

matriz (0,2) = 2

En C#, existe una forma alternativa de definir las matrices, basada en la idea deuna matriz como un arreglo de arreglos:

// C# - Defino una matriz de 2 filas y 3 columnas

int[][] mat = new int[2][]{new int[3],new int[3]};

mat [0][1] = 1;

mat [0][2] = 20;

MÁS ALLÁ DE LAS DOS DIMENSIONES

Como vimos, una matriz es un arre-glo de arreglos, lo cual puede versecomo un arreglo de dos dimensio-nes. Los lenguajes de programaciónpermiten definir arreglos con la can-tidad de dimensiones que necesite-mos. Por ejemplo, si necesitamos

almacenar los registros de lluvia decada mes, de los últimos 20 años pa-ra 10 ciudades distintas, podemosdefinir un arreglo de 10x20x12 (10ciudades por 20 años por 12 mesesal año). En este caso, la estructurase conoce como Cubo.

03_IntrodProg.qxd 23/7/07 20:41 Page 49

50

ELEMENTOS DE PROGRAMACIÓN

EL ESTILO DE PROGRAMACIÓN

> Una de las premisas fundamentales de la programación consiste en saber quelos programas no se escriben una vez y quedan así para siempre. Cuando se escri-be un programa, es normal tener que volver sobre sus instrucciones para hacer unamodificación o corregir un error. Y es común que la persona que deba modificarel programa no sea la misma que lo escribió. Sin embargo, dada la complejidadinherente a todo programa, leer el código fuente ya escrito y tratar de entenderlopara hacer la modificación que necesitamos, puede ser toda una odisea.

Para que la tarea de mantenimiento del software sea un poco más sencilla, esnecesario que, como programadores, tengamos el hábito de escribir el código dela manera más prolija posible y que logremos un estilo estándar. Para lograr unbuen estilo de programación, debemos tener en cuenta algunos consejos.

TABULACIONESLas sentencias compuestas pueden estar formadas a su vez por otras senten-

cias compuestas, así se obtienen anidamientos en el código del programa. Parapoder identificar dónde comienza y dónde termina cada nivel de anidamiento,es muy útil tabular hacia la derecha cada sentencia que está dentro de otra (esdecir, cada nuevo nivel de anidamiento). Veamos la diferencia entre tabular yno tabular con un ejemplo:

ARREGLOS

Visual Basic .Net permite cambiar eltamaño de los arreglos. Para ello, pro-vee la palabra clave Redim. Hay quetener en cuenta, sin embargo, que elRedim destruye el arreglo original ycrea uno nuevo, con la consiguientepérdida de los valores que contenía.Para evitarlo, se puede utilizar RedimPreserve, que luego de crear el arre-glo, copia los elementos del viejo.

› MODULARIZACIÓN Y OVERLAYS

En épocas en que la memoria de lascomputadoras era escasa, muchasveces cargar todo el programa eraimposible. La solución consistía encolocar los módulos en archivos se-parados llamados overlays. Cuandose necesitaba ejecutar un móduloque estaba en un overlay, se descar-gaba otro de memoria y se cargaba elque tenía el módulo necesario.

03_IntrodProg.qxd 23/7/07 20:41 Page 50

51

›EL ESTILO DE PROGRAMACIÓN

// C# - Forma incorrecta de anidar sentencias

if(a>0) {

for(int i=1;i<a;i++) {

if(i<3)

b=a*i;

else

b=a*(i+3);

}}

// C# - Forma correcta de anidar sentencias

if(a>0) {

for(int i=1;i<a;i++)

{

if(i<3)

b=a*i;

else

b=a*(i+3);

}

}

En el primer ejemplo, resulta difícil determinar dónde comienza cada nivel de ani-damiento, mientras que, en el segundo, queda perfectamente claro a primera vista.

THE CODE PROJECT

Aquí podremos encontrar cientosy cientos de ejemplos de códigofuente en .Net, tanto en VB.Netcomo en C#. Los ejemplos estánorganizados por categoría y pornivel (desde Principiante hastaAvanzado). Además, la mayoríade los ejemplos están acompaña-dos de un artículo donde se expli-can sus fundamentos.

03_IntrodProg.qxd 23/7/07 20:41 Page 51

52

ELEMENTOS DE PROGRAMACIÓN

Figura 6. El uso correcto de comentarios, nombres significativose indentación favorecen la claridad del código.

COMENTARIOSMuchas veces, nos encontramos con que hemos escrito una expresión muy

compleja. Al momento de escribirla, tenemos bien claro qué es lo que hace, por-que acabamos de idearla, pero luego de un tiempo, cuando volvemos a leerlapuede que no entendamos muy bien qué es lo que quisimos hacer. Para solucio-nar casos de este tipo, es aconsejable el uso de comentarios y dejar una explica-ción del razonamiento que hicimos para obtener ese código, o cualquier otromensaje que resulte útil para quien lo lea.

Nombres significativosCuando creamos un procedimiento o una función, el objetivo es realizar un

cálculo o tarea específica, por lo que el nombre que le demos al subprograma

03_IntrodProg.qxd 23/7/07 20:41 Page 52

53

›EL ESTILO DE PROGRAMACIÓN

creado debe revelar de la mejor manera posible el objeto de su existencia. A lahora de darles nombres a los procedimientos y funciones, se aconseja usar pa-labras completas y frases que indiquen cuál es la tarea que el subprograma rea-liza, evitando las abreviaturas. También es recomendable usar verbos que repre-senten la acción por realizar.

// C# - Forma incorrecta de nombrar subprogramas

void calcRet(string fac)

int MCM(int a, int b)

// C# - Forma correcta de nombrar subprogramas

void CalcularRetenciones(string numeroFactura)

int MaximoComunDivisor(int numeroA, int numeroB)

Consistencia de formatoQuizá lo más importante a la hora de escribir código fácil de mantener sea lo-

grar un estilo consistente y estandarizado, y mantener ese estilo en todo el pro-grama. Esto significa que, si escribimos los nombres de variables locales con mi-núsculas, las constantes con mayúscula y los nombres de los procedimientosusando mayúscula para la primera letra de cada palabra, debemos repetir esa con-vención siempre. Así, si somos consistentes, alguien que esté familiarizado con lanomenclatura, al leer un identificador, podrá saber fácilmente si se trata de unavariable, una constante, o un procedimiento.

Del mismo modo que es bueno adoptar convenciones de nomenclatura, re-sulta importante la consistencia en el uso de líneas en blanco, de espacios en-

COMENTARIOS VS NOMBRES CLAROS

En la actualidad, existe una discusiónsobre si se deben usar o no comenta-rios para explicar qué es lo que haceun procedimiento o función. Algunossostienen que resulta necesario colo-car un comentario, mientras que otrosinsisten en que, si se necesita explicar

una porción de código, es porque re-sulta muy compleja, y aconsejan rees-cribirla para que sea más sencilla, se-parándola en otros procedimientos ofunciones si fuera necesario. La se-gunda postura lleva a un código muchomás claro y mantenible.

03_IntrodProg.qxd 23/7/07 20:41 Page 53

54

ELEMENTOS DE PROGRAMACIÓN

tre los operandos y los operadores en las expresiones, y en la cantidad de espa-cios usados para las tabulaciones.

Figura 7. Los entornos de programación modernos permiten definir reglas de codificación y luegomodifican el código automáticamente a medida que escribimos, de manera que se cumplan las reglas.

� CONCLUSIONES

En este capítulo, hemos aprendido uno de los conceptos fundamentales de laprogramación: la modularización. Como programadores, debemos tenersiempre presentes estos conceptos y usarlos al máximo posible. Es preferibletener muchas funciones y procedimientos a tener grandes bloques de códigode cientos de líneas. Muchos programadores (entre los que me incluyo) tienenesta regla de oro: si un procedimiento o función no cabe en una página del edi-tor que estamos usando, entonces será necesario dividirlo en procedimientosy funciones más pequeños, porque se está volviendo demasiado largo y, por lotanto, demasiado complejo.

03_IntrodProg.qxd 23/7/07 20:41 Page 54

CAPÍTULO 4

Programaciónorientada a objetos

La orientación a objetos es una de las técnicas

más utilizadas en la actualidad en el mundo

del desarrollo: en el ámbito académico, como

herramienta de aprendizaje y, en lo profesional,

para solucionar toda clase de problemas.

ATENCIÓN AL LECTOR > [email protected]

04_IntrodProg.qxd 23/7/07 20:47 Page 55

56

PROGRAMACIÓN ORIENTADA A OBJETOS

LOS OBJETOS

> Si miramos a nuestro alrededor, vemos que estamos rodeados de objetos. Ycuando debemos desarrollar un nuevo software para resolver un problema, veri-ficamos que los elementos que componen el problema son objetos. Pensemos enun sistema de gestión de negocios. Al analizar las características del problema,nos encontramos con que tenemos objetos como productos, facturas, remitos,depósitos, clientes, etcétera. Y no sólo objetos concretos, sino también abstrac-tos, como ser vencimientos o impuestos.

La programación orientada a objetos es un paradigma basado en la identifi-cación de los objetos inherentes al problema y en la escritura de código que mo-dele esos objetos, sus propiedades, sus comportamientos y la forma en la que serelacionan para resolver el problema. Visto de esta manera, la programaciónorientada a objetos resulta opuesta a la programación imperativa clásica, dondelos programas son secuencias de instrucciones.

ORIGENSegún algunos autores, el primer lenguaje en usar objetos fue Simula 67, crea-

do en la década del 60 para hacer simulaciones. Cuenta la historia que en el Cen-tro de Cómputo Noruego, en Oslo, trabajaban en simulaciones de barcos, y lacantidad de combinaciones de cualidades entre los diferentes barcos, y cómounas afectaban a otras, produjo gran confusión en los científicos que estaban es-cribiendo los programas. Entonces, se les ocurrió organizar los diversos tipos debarcos en clases de objetos; cada clase sería responsable de definir y de adminis-trar sus propios datos y su comportamiento.

Más tarde, el lenguaje Smalltalk fue el primero en introducir el término orienta-ción a objetos para referirse al uso de objetos y de mensajes entre ellos como basedel diseño y la programación de aplicaciones. Sin embargo, el auge de este paradig-ma comenzó en la década del 80, con el lenguaje C++. La tecnología de objetos fueagregada a muchos lenguajes ya existentes, pero este agregado artificial condujo aproblemas de diseño y de compatibilidad que no hicieron más que ensuciar los len-guajes existentes. Por otro lado, los lenguajes orientados a objetos puros (comoSmalltalk) no eran muy aceptados, porque carecían de características a las que esta-

04_IntrodProg.qxd 23/7/07 20:47 Page 56

57

›LOS OBJETOS

ban acostumbrados los programadores del momento. Se hicieron muchos intentospor crear lenguajes orientados a objetos, pero con algunas características imperativasy estructuradas; el único que sobrevivió fue el lenguaje Java. En la actualidad, loslenguajes de la plataforma .Net están diseñados de esta manera, es decir, se basan enla definición de clases y de objetos, pero conservan características de la programa-ción imperativa.

Figura 1. Smalltalk fue uno de los primeros lenguajes completamente orientados a objetos.

VENTAJAS DE LA POOLa programación orientada a objetos (POO) posee algunas ventajas frente a la pro-

gramación estructurada clásica. La POO consiste en una evolución de la programa-ción estructurada y cuenta con la experiencia adquirida a lo largo de años de desa-rrollo de software, lo que constituye su principal ventaja. Además, conduce a un mo-delo mental del problema mucho más cercano a la realidad, lo que favorece el aná-lisis, la implementación y el posterior mantenimiento del software. Otra ventaja esque la POO permite lograr un mayor grado de encapsulado, ya que el comporta-miento y los datos propios de cada clase quedan contenidos en la definición de ella.Por último, mediante técnicas que estudiaremos luego, la POO permite reutilizarmucho código, favoreciendo la escritura de nuevos programas.

04_IntrodProg.qxd 23/7/07 20:47 Page 57

58

PROGRAMACIÓN ORIENTADA A OBJETOS

CLASES Y OBJETOS

> Cuando se analiza un problema para resolverlo mediante las técnicas de progra-mación estructurada, nos enfocamos en identificar los datos que debemos manipu-lar y las transformaciones que sufren como parte de la solución. Con el paradigmade orientación a objetos, la tarea de análisis se centrará en la identificación de obje-tos, de sus características y de cómo se relacionan entre sí para resolver el problema.

Ya dentro del contexto formal de la teoría de Orientación a Objetos, podemosdefinir un objeto (parafraseando la definición de James Rumbaugh) como unconcepto, abstracción o elemento con significado claro dentro del problema encuestión (por ejemplo, un empleado). Como tal, un objeto se caracteriza por te-ner un estado, que es el conjunto de valores de sus propiedades en un momentodel tiempo (por ejemplo, el nombre de un empleado, o el monto del sueldo quepercibe). Además, todo objeto tiene un comportamiento, es decir, las accionesque puede realizar y que modificarían su estado (por ejemplo, un empleado pue-de ascender o completar tareas). Por último, un objeto se caracteriza por teneridentidad propia, esto es, por más que dos objetos tengan el mismo comporta-miento y el mismo estado, resultan totalmente diferentes e identificables.

Según el diccionario, una clase es un grupo de elementos de un conjunto que tie-nen características comunes. Las técnicas de orientación a objetos se centran en laidentificación de esos elementos comunes entre los objetos para poder agruparlos enclases y, así, manipularlos fácilmente. Podemos decir que una clase es una abstrac-ción de un grupo de objetos, porque no existe por sí sola.

Por ejemplo, pensemos en una mesa. Hay mesas rectangulares, mesas redondas, demadera, de metal, incluso de diferentes colores. Todas son mesas distintas e identi-ficables, es decir: objetos. Sin embargo, podemos verificar que todas tienen los mis-

CLASES E INSTANCIAS

En el mundo de la orientación a obje-tos, hay dos términos muy usados:clases e instancias. Como vimos, unaclase es una abstracción de un objetode la realidad. La clase es un modelo

estático, por lo tanto, para poder inte-ractuar con otros elementos, debe-mos crear instancias que representena cada uno de los objetos particularesque, agrupados, forman la clase.

04_IntrodProg.qxd 23/7/07 20:47 Page 58

59

›CLASES Y OBJETOS

mos atributos, aunque con distintos valores. Todas tienen un color, un material, unaforma; por lo tanto podemos agruparlas bajo un mismo concepto: la mesa. Desdeel punto de vista de la orientación a objetos, podemos decir que mesa es una clase.

Mesa

Color

Material

Cantidad de patas

Clase

Objeto 1 Objeto 2

PROPIEDADES Y MÉTODOSComo decíamos, los objetos poseen atributos y comportamiento. Ya desde el

punto de vista de la programación, los atributos de los objetos se traducen enpropiedades de las clases que los modelan. El comportamiento en cambio, estárepresentado por procedimientos y funciones dentro de la clase. En la jerga de laprogramación orientada a objetos, los procedimientos y funciones que creamosdentro de una clase se denominan métodos, y representan el conjunto de activi-dades que un objeto puede realizar, es decir, su comportamiento. Los libros máspuristas dicen que los objetos se relacionan intercambiando mensajes, por lo queel comportamiento de un objeto está determinado por los mensajes que puedeenviar y por los que puede aceptar desde otros objetos. Volviendo a la definiciónde método, justamente, podemos decir que los métodos son los encargados deinterceptar y de enviar mensajes desde y hacia otros objetos y, al mismo tiempo,alterar el estado actual del objeto.

Figura 2. Una clase es una abstracción de las principales propiedades de los objetos reales.

04_IntrodProg.qxd 23/7/07 20:47 Page 59

60

PROGRAMACIÓN ORIENTADA A OBJETOS

PENSAR EN OBJETOS

> La forma de solucionar problemas utilizando técnicas de Orientación a Obje-tos es muy distinta de la forma tradicional o estructurada.

Cuando nos presentan un requerimiento de una nueva aplicación y queremosemplear los conceptos de la Programación Orientada a Objetos, como primerpaso nos concentraremos en identificar los objetos que intervienen en el pro-blema. Deberemos, entonces, analizar cuidadosamente el requerimiento, ha-blar con los usuarios y prestar especial atención a los elementos que mencio-nan. Una técnica muy usada consiste en leer el requerimiento escrito (que de-berá ser lo más claro y completo posible) y subrayar todos los sustantivos, tan-to concretos como abstractos. Luego, de entre todos los sustantivos subraya-dos, descartamos aquellos que no son propios del problema por resolver. Unavez realizada esta primera actividad, habremos identificado una buena parte delos objetos del dominio de la aplicación.

Por ejemplo, imaginemos que necesitamos implementar una aplicación de alqui-ler de autos, y nos presentan el siguiente requerimiento (resumido): La empresa dis-pone de autos para alquilar a sus clientes. Cuando se alquila un auto, el cliente firmauna póliza de seguro. En un formulario de alquiler, se registra la fecha, el nombre delcliente, el número de su registro de conductor y el número de tarjeta de crédito.

Si aplicamos la técnica de los sustantivos, podremos identificar rápidamentetres objetos fundamentales para la aplicación: auto, cliente y formulario de alqui-ler. Dependiendo del tipo de análisis y diseño que queramos hacer, podríamosconsiderar como objetos la tarjeta de crédito e, incluso, el alquiler.

Como decíamos al principio, los objetos poseen propiedades y comportamiento.Para identificar las propiedades aplicamos una técnica similar a la de los sustanti-

TOMARLO CON CALMA

Muchas veces, no lograremos iden-tificar con claridad todos los objetosen una primera lectura. Será nece-sario hacer una segunda pasada (in-cluso más) sobre el texto del reque-

rimiento para encontrar objetosocultos, despejar ambigüedades oeliminar falsos objetos que no sonesenciales para la solución concretadel problema.

04_IntrodProg.qxd 23/7/07 20:47 Page 60

61

›PENSAR EN OBJETOS

vos, pero buscando cualidades o adjetivos de los objetos que ya hemos identifica-do. Siguiendo con el ejemplo del alquiler de autos, podemos ver que el formulariode alquiler tiene propiedades como la fecha, el nombre del cliente, etcétera.

Una vez que hemos identificado los objetos y sus propiedades, estamos en con-diciones de definir clases para agruparlos y abstraer todas las posibles instanciasde ellos. Hemos alcanzado así el fin de la primera etapa en el proceso de soluciónde problemas mediante técnicas de orientación a objetos.

Figura 3. Con las técnicas de análisis, identificamos los objetosdel mundo real; luego abstraemos sus propiedades para agruparlos en clases.

Autos Auto

ColorMarca

Año

Clientes Cliente

NombreNúmero de

Registro

Formularios Formulario

FechaCliente

Nº de póliza

PATRONES DE DISEÑOSi bien el proceso de análisis y diseño orientado a objetos se centra en la iden-

tificación de los objetos propios del dominio del problema, a menudo es necesa-rio crear objetos ficticios. Éstos colaboran con los objetos reales en la solución delproblema o en proveer mecanismos de flexibilidad, extensibilidad o claridad del

04_IntrodProg.qxd 23/7/07 20:47 Page 61

62

PROGRAMACIÓN ORIENTADA A OBJETOS

código, y ayudan a separar los intereses y responsabilidades de cada objeto. Unejemplo muy común de estos escenarios son los requisitos no funcionales.

Para entender un poco mejor este aspecto, retomemos el ejemplo del sistema dealquiler de autos e imaginemos que se nos exige que el sistema valide la tarjeta decrédito, pero que además el código esté preparado para adaptar el sistema a nue-vos mecanismos de validación. Una posible solución es definir una clase llamadaValidadorTarjetaCredito, con un método que reciba un número de tarjeta y unimporte, y valide que se puede cobrar ese importe a esa tarjeta. Luego, utilizan-do la herencia y el polimorfismo (que veremos luego), se pueden crear nuevas cla-ses que empleen diversos mecanismos de validación.

A lo largo de los años, los desarrolladores reconocieron que muchas de las solu-ciones que encontraban a los problemas no funcionales con orientación a obje-tos comenzaban a repetirse o tenían elementos en común y que, además, funcio-naban (es decir, cumplían su propósito). Actualmente, a estas soluciones proba-das a problemas comunes, se las llama patrones. Hay distintas clasificaciones depatrones según la familia de problemas que atacan, siendo los más comunes losdenominados Patrones de diseño.

El principal objetivo de los Patrones de diseño es el de proveer un catálogode elementos de diseño que ayuden a los programadores en su tarea diaria,evitando que tengan que buscar nuevas soluciones cada vez que se enfrentancon un problema común. Además, los Patrones de diseño facilitan la comuni-cación entre los programadores, como así también la comprensión del códigoescrito por otro. Obviamente, los patrones no pretenden eliminar el trabajodel desarrollador, ya que éste debe ser capaz de identificar las características decada problema y tener un dominio de los principales patrones para asociarloscon el problema y aplicarlos.

LA BANDA DE LOS CUATRO

El tema de los patrones ha generadogran cantidad de bibliografía. Quizá ellibro más popular a la hora de apren-der sobre patrones es Design Pat-terns. Elements of Reusable Object-Oriented Software. Los patrones que

en él se presentan, se conocen comopatrones GoF, sigla de Gang of Four(la Banda de los Cuatro), en alusión asus cuatro autores, autoridades abso-lutas en este ámbito (Gamma, Helm,Jonson y Vlissides).

04_IntrodProg.qxd 23/7/07 20:47 Page 62

63

›RELACIONES ENTRE CLASES

RELACIONES ENTRE CLASES

> En el mundo real, y dentro del contexto de una aplicación que debemos im-plementar, los objetos no están solos. Todo objeto se relaciona en cierta medidacon alguno de los otros objetos (sea de la misma clase o no). En el ejemplo de al-quiler de autos que estudiamos anteriormente, los clientes (que son objetos) serelacionan con los autos (que también son objetos) mediante la operación de al-quiler. Del mismo modo, los formularios de alquiler se relacionan con los autosy con los clientes. Una buena regla adicional para la identificación de objetos apartir de un requerimiento es que, si un objeto no se relaciona con ningún otro,es probable que no sea necesario tenerlo en el sistema o deba ser revisado para versi no nos faltó considerar algún aspecto del requerimiento.

Un objeto puede relacionarse con otro de distintas maneras, como por ejemplo,enviándose mensajes entre sí. Durante el análisis, una vez que determinamos los ob-jetos y definimos las clases, debemos prestar atención a las relaciones entre los obje-tos, ya que deberán ser modeladas para que luego se encuentren disponibles en ca-da instancia. Entre las relaciones más importantes, podemos mencionar: uso, agre-gación y herencia. Veamos las dos primeras ahora y dejemos la herencia para des-pués, ya que es muy importante y merece un tratamiento aparte.

RELACIÓN DE USOEn una relación de uso, un objeto A usa un objeto B, en el sentido de utilizar

algún servicio provisto por B. En cualquier aplicación, es muy común encontrarque un objeto necesita algún servicio de otro, como pedirle que haga una deter-minada tarea. Si retomamos el ejemplo de la validación de tarjetas de crédito que

POO PURA

Muchos puristas de la orientación aobjetos sostienen que Smalltalk yEiffel son de los pocos lenguajesrealmente orientados a objetos. Elargumento se basa en que otros len-guajes (como los presentes en la

plataforma .Net) poseen aún mu-chos conceptos de la programaciónestructurada (como por ejemplo lasestructuras de control) y eso atentacontra la definición formal de orien-tación a objetos.

04_IntrodProg.qxd 23/7/07 20:47 Page 63

64

PROGRAMACIÓN ORIENTADA A OBJETOS

vimos cuando tratamos el tema de los patrones, podemos observar que el objetoValidadorTarjetaCredito brinda un servicio que alguien más, por ejemplo un ob-jeto RegistradorDeAlquiler puede usar para completar su función. En la biblio-grafía de POO, se suele llamar relación Usa-A a la relación de uso

RELACIONES

Desde el punto de vista de la imple-mentación, tanto las relaciones deagregación como las de composi-ción suelen representarse comopropiedades o atributos de las cla-

ses agregadas o compuestas. Porejemplo, la clase Carrito puede te-ner una propiedad que sea la listade objetos de la clase Producto queella contiene.

Figura 4. Cuando un objeto A solicita una tarea a un objeto B, se dice que el objeto A usa el objeto B.

Objeto A

Hacer Tarea

Tarea lista

Objeto B

RELACIÓN DE AGREGACIÓNMuchas veces, un objeto se compone de otros. Este tipo de relación se denomi-

na agregación. En una relación de agregación entonces, un grupo de objetos (dela misma clase o de clases distintas) se agrupan para formar un objeto más com-plejo. Por ejemplo, un carrito de compras se compone de uno o más productosque el cliente ha comprado. Si bien los objetos producto son independientes, elobjeto carrito necesita de ellos para existir. La relación de agregación puede ser

04_IntrodProg.qxd 23/7/07 20:47 Page 64

65

›RELACIONES ENTRE CLASES

recursiva, es decir, un objeto que está compuesto por otros, a su vez, puede serparte de un objeto más grande, definiendo así una estructura jerárquica. Porejemplo, una universidad puede estar compuesta de facultades, cada facultad secompone de departamentos, y cada departamento, de profesores y de alumnos.

ComposiciónLa composición es un caso especial de agregación en el que los objetos agrega-

dos a otro, sólo pertenecen a él. Por ejemplo, un automóvil está compuesto de unmotor, un chasis, una carrocería y otros elementos, pero cada uno de ellos sólopuede pertenecer a ese auto. Un motor que está en un auto no puede estar en otro.

La distinción entre agregación y composición depende directamente del problemapor resolver y, en un buen modelo de objetos, debería reflejar exactamente la realidad.

Figura 5. En una relación de agregación, los objetos se agrupan para formar un objeto más complejo.

Objeto b1

Objeto c1

Objeto c2

Objeto a

Objeto b2

Objeto c3

MÉTODOS Y PROPIEDADES DE CLASE

Normalmente, los métodos y pro-piedades corresponden a cada ins-tancia de una clase (a cada objeto).Sin embargo, muchas veces hay ca-racterísticas que son comunes a to-

das las instancias. En estos casos,podemos definir métodos o propie-dades compartidos, que pertenecena la clase y se pueden invocar direc-tamente sobre ella.

04_IntrodProg.qxd 23/7/07 20:47 Page 65

66

PROGRAMACIÓN ORIENTADA A OBJETOS

HERENCIA

> La herencia es un tipo muy importante de relación entre objetos. En una re-lación de herencia, una clase recibe las propiedades y comportamiento de otracomo si fuesen suyas y, al mismo tiempo, puede agregar las propias.

Veamos esto con un ejemplo. Supongamos que estamos desarrollando una apli-cación que necesita hacer cálculos de superficie sobre distintas figuras geométri-cas, es decir, vamos a tener objetos como Círculo, Cuadrado, Trapecio, etcétera.Dado el requerimiento que tenemos, todos los objetos presentarán un compor-tamiento en común: calcular su superficie. Lo que podemos hacer entonces esdefinir una clase llamada Figura y establecer una relación de herencia entre estaclase y cada una de las figuras particulares. Le asignamos el método de cálculo desuperficie a la clase Figura y, mediante la relación de herencia, las demás clasestendrán este comportamiento como heredado. Decimos entonces que las clasesCuadrado, Trapecio, etcétera, heredan de la clase Figura.

Así como el uso define una relación usa-a, y la composición define una relaciónse-compone-de, la herencia se conoce como una relación es-un. Siguiendo con elejemplo de las figuras, decimos que un círculo es una figura, un cuadrado es unafigura, y así con todos. Cuando una clase B hereda de una clase A, se dice que laclase A es la clase padre o clase base, y la clase B es la clase hija, heredera o deri-vada. En el ejemplo anterior, entonces, la clase Figura es la clase base, y las de-más, sus clases derivadas.

La relación de herencia no se limita a un solo nivel, es decir, que una clase deriva-da de otra puede a su vez ser la base de una tercera clase, formando así una estruc-tura jerárquica o de árbol. Además, en escenarios de múltiples niveles, la relación de

DISEÑAR PENSANDO EN OBJETOS

La herencia tiene una gran potenciapara escribir código reutilizable, fle-xible y mantenible. Por eso, duranteel análisis del problema y durante elposterior diseño de las clases, sedebe prestar especial atención a

identificar relaciones de herenciapara aprovechar sus virtudes. Cono-cer algunos patrones de diseño pue-de ayudar también a identificar re-laciones de herencia, aun en clasesno concretas.

04_IntrodProg.qxd 23/7/07 20:47 Page 66

67

›HERENCIA

herencia es transitiva, esto es, si una clase C hereda de B, que a su vez hereda de A,todo el comportamiento y las propiedades de A pertenecen también a C.

A partir del ejemplo anterior, podemos apreciar que la relación de herencia pro-vee un mecanismo para lograr uno de los objetivos más importantes de la pro-gramación orientada a objetos, la reutilización de código. ¿Cómo se entiende es-to? Supongamos que de la clase Figura hereda una clase Cuadrilátero, que tienepropiedades para representar la longitud de cada uno de los lados. Si de la claseCuadrilátero derivan Rombo, Trapecio y Rectángulo, en estas nuevas clases ya notendremos que escribir el código de la propiedad, es decir, hemos reutilizado có-digo que ya estaba escrito.

Figura 6. Mediante la herencia, podemos definir una jerarquía de clases, donde cadaclase derivada hereda el comportamiento y las propiedades de su clase base.

Clase Figura

CalcularSuperficie()

Clase Cuadrilatero

LongitudLadoALongitudLadoBLongitudLadoCLongitudLadoD

Clase Circulo

Radio

Clase Cuadrado Clase Rombo

Además de la reutilización de código, la herencia provee otras aplicaciones úti-les, como son la extensión y la redefinición de clases. Veamos de qué se trata.

04_IntrodProg.qxd 23/7/07 20:47 Page 67

68

PROGRAMACIÓN ORIENTADA A OBJETOS

REDEFINIR COMPORTAMIENTOEs muy común que una clase que hereda de otra no se comporte exactamente

igual, aun para el comportamiento heredado. Veamos un ejemplo real: entre lasherramientas que provee el Framework .Net para crear aplicaciones basadas enventanas, tenemos clases para crear componentes visuales, como botones y listas.Supongamos que debemos crear botones, pero que sean redondos, y no rectangu-lares como los botones normales. Si no tuviéramos la herencia, deberíamos crearuna clase BotonRedondo y escribir absolutamente todo el código. Sin embargo,podemos hacer que nuestra clase herede de la clase Button de .Net y redefina unmétodo llamado OnPaint (que es el encargado de dibujar el botón en la pantalla)para dibujarlo como necesitamos. Tendremos así un nuevo tipo de botón que sedibuja como queremos, pero que posee todo el comportamiento y las propieda-des de cualquier otro botón (por ejemplo, reacciona ante un clic con el ratón).

Figura 7. Una clase puede redefinir un método heredadopara personalizarlo según su propio comportamiento.

Clase Boton

Dibujar:Dibuja un rectángulo ycoloca el texto del botón

AtenderClick()

Clase BotonRedondo

Dibujar:Dibuja un circulo ycoloca el texto del botón

La ClaseBotonRedondofunciona exactamenteigual que la claseBoton pero se dibujadistinto.

04_IntrodProg.qxd 23/7/07 20:47 Page 68

69

›HERENCIA

EXTENDER CLASESLa extensión es un mecanismo para agregar comportamiento y propiedades a

una clase, es decir, a todas las características que se heredan de la clase padre, sele agregan otras propias de la clase derivada. Por ejemplo, si tenemos una clasePersona y de ella derivamos una clase Empleado, podemos aplicar extensión agre-gando las propiedades Jefe y Sueldo. Si miramos este ejemplo pensando en la re-lación es-un, podemos decir que un Empleado es-una persona que además poseeun sueldo y un jefe, es decir, es una extensión.

La extensión es una de las aplicaciones más utilizadas y naturales de la heren-cia, ya que sienta las bases de un buen diseño que derive en código claro, man-tenible y robusto.

La extensión se puede combinar con la redefinición, para reutilizar aun más elcódigo heredado. Esto es, podemos redefinir un método de manera tal que secomporte exactamente igual al método heredado del padre, pero que además ha-ga algo extra. Volviendo al ejemplo del Botón, imaginemos que queremos hacerun botón tal que, cuando el cursor del ratón pase por encima, cambie de color.Deberemos entonces definir una nueva clase, que herede de Button y redefinir elmétodo OnPaint, pero en vez de escribirlo todo desde cero, llamamos al métodode la clase padre para dibujar el botón, y luego, si el cursor está sobre el rectán-gulo que comprende el botón, le cambiamos el color.

TIPOS DE HERENCIAHasta hora vimos ejemplos de herencia donde una clase derivada hereda sólo de

una clase base. Sin embargo, en la práctica pueden presentarse casos en que unaclase herede de más de una clase padre. Por ejemplo, imaginemos que tenemosuna clase Empleado, con una propiedad Sueldo, y una clase Músico con una pro-

HERENCIA MÚLTIPLE

La mayoría de los lenguajes actua-les no soportan herencia múltiple,ya que en general este tipo de he-rencia presenta más problemas quesoluciones. Uno de los problemasde la herencia múltiple es cómo re-

solver casos en que un método opropiedad existe en más de una cla-se base, entonces, ¿cuál es el querecibe la clase derivada? Tanto loslenguajes de .Net como Java no per-miten herencia múltiple.

04_IntrodProg.qxd 23/7/07 20:47 Page 69

70

PROGRAMACIÓN ORIENTADA A OBJETOS

piedad InstrumentoQueToca y queremos definir una clase EmpleadoDeOrquesta.Como los empleados de orquestas son músicos (tocan un instrumento) y ademásson empleados (perciben un sueldo), podemos heredar de ambas clases para reuti-lizar el código de cada una. Este tipo de herencia se denomina Herencia Múltiple.

CLASES ABSTRACTASEn el ejemplo de las figuras geométricas que vimos al comienzo, definimos una

clase Figura con un método CalcularSuperficie. Ahora bien, esa clase, es una abs-tracción de todas las posibles figuras geométricas y, por lo tanto, no le podemosdefinir el cálculo de superficie, ya que depende de cada tipo de figura. Afortuna-damente, para resolver cuestiones como ésta desde el diseño, tenemos la posibi-lidad de crear métodos abstractos: métodos que están declarados, pero que notienen implementación. La implementación de un método abstracto queda rele-gada a las clases derivadas. Una clase que contiene al menos un método abstrac-to se denomina abstracta.

INTERFACESLas interfaces son un derivado de las clases abstractas. En particular, una in-

terfaz es esencialmente igual a una clase con todos sus métodos abstractos. Unaclase que herede de una interfaz (en realidad para hablar correctamente debe-mos decir que la clase implementa una interfaz) está obligada a implementar

CLASE ABSTRACTA O INTERFAZ

Una decisión que muchas veces ten-dremos que tomar es si optar por unaclase abstracta o por una interfaz. Ladiferencia radica en dos puntos: siusamos una clase abstracta, tendre-mos la posibilidad de escribir algo decódigo (métodos no abstractos), parano tener que escribirlo en cada clasedescendiente. Con las interfaces, ten-dremos abierta la posibilidad de he-redar de otra clase.

› INSTANCIA

En .Net, cuando definimos una varia-ble que es una instancia de una cla-se, en realidad, lo que estamos guar-dando en la variable no es el objetocompleto sino la dirección de memo-ria (en el HEAP) donde se encuentrael objeto. Cuando pasamos un pará-metro por valor, lo hacemos por re-ferencia, y cualquier modificacióndel parámetro, la haremos sobre elobjeto original.

04_IntrodProg.qxd 23/7/07 20:47 Page 70

71

›HERENCIA

todos sus métodos y propiedades. Las interfaces se utilizan para proveer unaabstracción de algún comportamiento. Además, los lenguajes modernos comoJava y los lenguajes de .Net permiten que una clase implemente varias interfa-ces, proveyendo así una especie de herencia múltiple.

Figura 8. Las interfaces permiten abstraer comportamientosy, a la vez, heredar de otra clase, proveyendo un tipo de herencia múltiple.

Clase FiguraDibujable

Dibujar()

Clase Figura

CalcularSuperficie()

La ClaseFiguraDibujable es una figura, perotambién tiene lacapacidad de dibujarseal implementar lainterfaz IDibujable.

Interfaz IDibujable

Dibujar()

PROGRAMADOR .NET

Un completísimo portal con infor-mación para programadores. Ac-tualmente, hay más de 3500 re-cursos entre artículos y ejemplosde código. Los artículos y ejem-plos cubren la mayoría de los te-mas y de los lenguajes actualesque todo programador debe cono-cer. Está organizado en catego-rías, por lo que resulta sencilloencontrar lo que buscamos.

04_IntrodProg.qxd 23/7/07 20:47 Page 71

72

PROGRAMACIÓN ORIENTADA A OBJETOS

POLIMORFISMO

> El polimorfismo es una técnica que permite tratar a un objeto de una clasederivada como si fuese de la clase padre. Polimorfismo significa muchas formas, yjustamente se usa este término, porque permite que una variable tenga múltiplesformas. La definición misma de la relación de herencia brinda la posibilidad decontar con el polimorfismo, esto es, como una clase derivada es-una clase base,siempre que necesitemos una clase base podremos usar una clase derivada. Porejemplo, si tenemos un método que recibe un objeto de clase Figura, podremospasarle un objeto de clase Rectángulo o de clase Círculo, ya que tanto el rectán-gulo como el círculo son figuras. Los lenguajes actuales permiten polimorfismotanto por herencia como por implementación de interfaces.

La mayor utilidad del polimorfismo radica en que permite programar en un ni-vel de abstracción superior, ya que podemos especificar los contratos (es decir,qué esperamos en un método o propiedad) utilizando clases abstractas, interfa-ces o clases base de una gran jerarquía de herencia. Además, como veremos a con-tinuación, mediante el polimorfismo, se logra el máximo nivel de extensibilidaddel código, ya que permite encapsular las responsabilidades de los objetos dentrode los objetos mismos y desde afuera trabajar con su abstracción o clase base.

Para ilustrar la utilidad del polimorfismo, supongamos que tenemos que escri-bir un procedimiento que imprima la superficie de una figura, pero sin trabajarcon orientación a objetos. Para hacerlo, necesitaremos conocer el tipo de figuray escribir una sentencia de tipo select case para calcular la superficie según el ti-po de figura. Veamos algo de código (en C#).

EARLY BINDING VS LATE BINDING

El término Binding hace referencia alenlace entre el tipo de dato de una va-riable y el de su valor. Cuando el tipo dedato que tendrá un valor queda esta-blecido en tiempo de codificación, sedenomina Early Binding, mientras quecuando el tipo de dato real se conoce

recién en tiempo de ejecución, habla-mos de Late Binding (enlace tardío).Cuando se explota la técnica de poli-morfismo, se usa siempre Late Bin-ding, ya que una variable se declara deuna clase, pero en ejecución puede serde una clase derivada.

04_IntrodProg.qxd 23/7/07 20:47 Page 72

73

›POLIMORFISMO

switch(tipoFigura)

{

case “Cuadrado”:

Console.WriteLine(base*altura);

break;

case “Triangulo”:

Console.WriteLine((base*altura)/2);

break;

case “Circulo”:

Console.WriteLine(3.14*radio*radio);

break;

}

El problema con esta porción de código reside en que, cuando agreguemos unnuevo tipo de figura, tendremos que agregar también el caso para hacer el cálcu-lo correspondiente.

Si utilizamos objetos, podemos tener una clase abstracta Figura, con un méto-do abstracto CalcularSuperficie() y sendas clases derivadas para modelar los dis-tintos tipos de figuras. Cada clase derivada es responsable de redefinir el métodoCalcularSuperficie para adaptarlo a su fórmula de cálculo. De este modo, nues-tro procedimiento para imprimir la superficie se reduce a esto:

LA MAGIA DEL POLIMORFISMO

El polimorfismo abre las puertas aun nivel más de abstracción, en elque podemos escribir funcionalidadsin interesar mucho cómo se va autilizar luego. Un ejemplo claro de esto es el ma-nejo de secuencias de bytes en .Net.El Framework .Net posee una clasellamada Stream, que representauna secuencia de bytes.

Luego, hay clases derivadas paraleer y escribir de distintos medios,como archivos y llamadas http, yotros. Lo bueno es que muchos mé-todos reciben como parámetro unStream, pero podemos pasarle loque necesitemos.Éste es un claro ejemplo de Poli-morfismo, con una aplicación prác-tica en el mundo real.

04_IntrodProg.qxd 23/7/07 20:47 Page 73

74

PROGRAMACIÓN ORIENTADA A OBJETOS

public void Imprimir(Figura f)

{

Console.WriteLine(f.CalcularSuperficie())

}

Cuadrado c;

...

Imprimir( c ); // un cuadrado es una figura

Con esto, cuando necesitemos agregar un nuevo tipo de figura, bastará con es-cribir la clase correspondiente (heredando de Figura) e implementar el métodoCalcularSuperficie como corresponda, y no deberemos modificar el procedimien-to de impresión.

La técnica de polimorfismo es un poco difícil de entender al comienzo, perouna vez asimilada se convierte en el arma más poderosa de la orientación a obje-tos. El secreto está en entender que, cuando codificamos la llamada a un méto-do de una clase base, debemos tener presente que en ejecución se llamará al mé-todo correspondiente de una clase derivada.

� CONCLUSIONES

La programación orientada a objetos, bien usada, puede ayudarnos a cons-truir software con las características más deseables por todo programador:facilidad de escritura, facilidad de mantenimiento, extensibilidad y reutiliza-ción de código. La extensibilidad es la clave para escribir aplicaciones alta-mente flexibles, ya que permite agregar o modificar comportamiento con muypoco esfuerzo. Es muy importante aprender algunos patrones de diseño e in-corporar correctamente los conceptos de abstracción, encapsulamiento y po-limorfismo, para no caer en el error de utilizar un lenguaje orientado a obje-tos para escribir código estructurado.

04_IntrodProg.qxd 23/7/07 20:47 Page 74

CAPÍTULO 5

UML

Hemos visto distintas formas de expresar algoritmos,

como el pseudocódigo y los diagramas de flujo.

Estas herramientas resultan muy útiles, pero fueron

pensadas para expresar procedimientos y, por lo tanto,

tienen su aplicación más popular en la programación

estructurada. Con la llegada de las técnicas de POO,

se buscaron nuevas formas de expresar detalles

del problema por resolver ya que, en la programación

orientada a objetos, sólo nos concentramos en los

objetos del dominio y en los mensajes entre ellos.

ATENCIÓN AL LECTOR > [email protected]

05_IntrodProg.qxd 23/7/07 20:16 Page 75

76

UML

¿QUÉ ES UML?> UML es la sigla de Unified Modeling Language, o Lenguaje Unificado de Mo-delado. Como su nombre lo indica, UML es un lenguaje. Pero no un lenguajede programación como los que vimos durante todo el libro, sino uno de mode-lado: su propósito principal consiste en definir modelos. Por modelo, se entien-de una representación simplificada de la realidad. Además, UML es un lenguajevisual, es decir, toda su expresividad se basa en gráficos.

El lenguaje UML nació en 1995 como resultado del trabajo en conjunto deRumbaugh y Booch, dos investigadores en el área de Metodología, que comen-zaron a trabajar juntos en Racional, una compañía fundada por Booch. Luego seles sumó Jacobson, quien aportó más ideas para desarrollar lo que se convirtió enla primera versión de UML. Hasta entonces, se habían desarrollado unos cuan-tos mecanismos de modelado de software, pero como ninguno fue formalizadocorrectamente ni estandarizado, cada ingeniero de software los aplicaba como sa-bía y como le convenía. Esto trajo como consecuencia que los modelos desarro-llados fueran incomprendidos por los programadores, perdiendo su efectividad y,por lo tanto, su utilidad. UML fue aprobado como un estándar, lo que lo con-vierte en una herramienta fundamental para los analistas, diseñadores y arquitec-tos de software, que necesitan transmitir a los programadores, de forma clara yprecisa, los detalles del software por implementar.

UML consiste en un conjunto de diagramas de distintos tipos. Cada uno es-tá destinado a cubrir alguno de los aspectos del software, y se pretende que conUML se puedan modelar absolutamente todos los elementos de una aplica-ción. Hay diagramas para modelar los objetos, sus interacciones, las interaccio-nes del sistema con el mundo exterior (ya sean usuarios u otros sistemas). Elobjetivo principal de UML es el de proveer una herramienta de comunicaciónprecisa y sin ambigüedades. En la actualidad, existen numerosas herramientasque no sólo ayudan a construir los diagramas en UML, sino que además per-miten validar el modelo construido contra la especificación del lenguaje e in-cluso generar código sobre la base del modelo.

A lo largo de este capítulo, estudiaremos los principales conceptos de algunosde los tipos de diagrama más importantes de UML y veremos cómo se relacionacon los conceptos de orientación a objetos que ya hemos aprendido.

05_IntrodProg.qxd 23/7/07 20:16 Page 76

77

›DIAGRAMA DE CLASES

DIAGRAMA DE CLASES

> El diagrama de clases se utiliza para modelar las clases que intervienen en lasolución, con sus propiedades, sus métodos y las relaciones entre ellas. Es un dia-grama de tipo estático, en el sentido que modela entidades que se mantienenconstantes durante la ejecución. Recordemos que las clases son fijas, y lo que va-ría son las instancias, o sea, los objetos.

El diagrama de clases resulta muy útil tanto para especificar los requerimientoscomo para documentar los detalles del diseño. Además, mediante técnicas de in-geniería directa, permite generar el código de las clases, no sólo la definición, si-no también las propiedades y el esqueleto de los métodos. Veremos a continua-ción las principales características del diagrama de clases, para empezar, cómo ycuándo utilizarlo.

CLASESLas clases se representan mediante un rectángulo dividido horizontalmente en

tres partes. En la primera parte, se coloca el nombre de la clase; en la segunda,las propiedades; y en la tercera, los métodos. Recordemos que UML es un len-guaje y, por lo tanto, debemos respetar sus nomenclaturas y estándares, o el mo-delo que definamos no será un diagrama UML válido.

Cliente

Nombre

RealizarPago(cantidad)

Propiedades

Nombre de la clase

}Métodos}

Figura 1. En el diagrama de clases, cada una se representamediante un rectángulo con el nombre de la clase en la parte superior.

De las tres partes, sólo es obligatorio el nombre de la clase en la primera; las otrados pueden quedar vacías. Además, no es necesario especificar todas las propie-dades y operaciones de la clase, sólo las que resultan útiles para el modelo.

05_IntrodProg.qxd 23/7/07 20:16 Page 77

78

UML

Para darle más precisión al modelo, se puede especificar el tipo de dato de cadapropiedad, separándolo del nombre de la propiedad con dos puntos (Nombre:String). Si el tipo de dato de una determinada propiedad es otra clase, estamosante un caso de composición, que tiene una forma específica en UML (que ve-remos luego), sin embargo, en casos en que no haya lugar a dudas es posible in-dicarlo como si fuese un tipo de dato básico, como muestra la Figura 2.

Cliente

Nombre: StringContacto: Persona

La sección depropiedades y de

métodos puedequedar vacia.

Podemos especificar los tiposde dato de las propiedades.

En algunos casos podemosusar clases como tipo de datode las propiedades.

VisibilidadEn UML, se puede especificar la visibilidad de cada elemento de una clase

(propiedad o método). Si bien la visibilidad es algo más relacionado a la im-plementación en un lenguaje particular, es importante indicarla en el modelode diseño, ya que permite dejar definidas ciertas normas de encapsulamientoque el analista o el diseñador detectan durante las primeras fases del proyec-to. Si bien UML prevé notaciones para los tipos de alcance básicos, el lengua-je está abierto y permite utilizar modificadores propios del lenguaje que se uti-lice luego para la implementación.

Figura 2. Si bien es un caso de composición, a veces, podemos usar clases como tipo de las propiedades.

INGENIERÍA DIRECTA E INVERSA

Cuando se habla de modelos y, so-bre todo de UML, es muy comúnmencionar a la Ingeniería Directa ya la Ingeniería Inversa. Mediante laingeniería directa, se puede generar

el código fuente que implemente elmodelo, mientras que, a través de laingeniería inversa, se puede obtenerun modelo completo o parcial a par-tir de código fuente ya escrito.

05_IntrodProg.qxd 23/7/07 20:16 Page 78

79

›DIAGRAMA DE CLASES

La visibilidad se expresa mediante un signo a la izquierda del nombre de la pro-piedad o del método, y los utilizados son el signo más (+) para los elementos pú-blicos, el signo menos (-) para los privados y el numeral (#) para los protegidos.Recordemos que los elementos protegidos sólo son visibles por la clase y por susdescendientes, mientras que los privados sólo son visibles dentro de la clase.

RELACIONES ENTRE CLASESLas relaciones entre clases también están contempladas en UML, dado que, du-

rante el diseño, es muy útil especificar claramente cualquier relación, que debe-rá ser traducida luego al código.

ComposiciónEn UML, la composición se representa mediante una línea que une las dos cla-

ses, pero colocando un pequeño rombo del lado de la clase que se compone apartir de la otra. Opcionalmente, se puede indicar el nombre de la propiedad querepresenta la composición, pero no es muy habitual hacerlo, sobre todo en lasetapas iniciales del análisis.

En la Figura 3, vemos que una Escuela se compone de Aulas. Observemos los pe-queños números debajo de la línea. Estos números indican la multiplicidad, es de-cir, cuántos elementos pueden existir de cada lado. El asterisco (*) indica muchos,sin especificar cuántos. Según esto, el diagrama de la Figura 3 deja bien claro queuna escuela se compone de muchas aulas. Del mismo modo, si leemos la multipli-cidad en sentido inverso, podemos entender que un aula está sólo en una escuela.

Escuela

+ Nombre: String

Posee

1 1..*

Aula

+ Capacidad: int

Figura 3. UML permite especificar la relación de composición,indicando además cuántos elementos de una clase componen a la otra.

Además, sobre la línea que indica la relación, se puede colocar un texto acla-ratorio sobre el tipo de composición. En el ejemplo de la Figura 3, hemos espe-cificado Posee como nombre de la relación. Si bien es opcional, el nombre de

05_IntrodProg.qxd 23/7/07 20:16 Page 79

80

UML

la relación ayuda mucho a la claridad del diagrama y a su posterior implemen-tación en un lenguaje de programación.

Asociación simpleAnteriormente vimos que, si el tipo de dato de una propiedad es una clase, po-

demos escribirlo directamente o bien utilizar una relación de asociación. Hay unatercera opción que es usar ambos al mismo tiempo, pero no la veremos ahora.

La relación de asociación se representa de manera similar a la composición, perosin utilizar el rombo; simplemente se coloca una línea entre las dos clases asociadasy una flecha que indica el sentido de la asociación. Al igual que en la composición,puede agregarse el nombre de la relación para aumentar la riqueza del modelo.

Escuela

+ Nombre: String

Ubicada en

Dirección

+ Calle: String+ Numero: int

Figura 4. La relación de asociación es similar a la composición,pero se utiliza una flecha para indicar el sentido de la relación.

PROGRAMACION Y DISEÑO

Los conceptos introducidos por la POOcomo forma de trabajo, no sólo se apli-can a la programación propiamente di-cha, sino que también se puede hacer

análisis orientado a objetos, y diseñoorientado a objetos. UML está pensa-do para la creación de diagramasusando este paradigma.

05_IntrodProg.qxd 23/7/07 20:16 Page 80

81

›DIAGRAMA DE CLASES

HerenciaLa relación de herencia también tiene su forma particular dentro del lenguaje

UML. La representación de la herencia consiste en una flecha con la punta sinrellenar (en blanco). Lo más común es colocar las clases derivadas debajo de laclase base, de manera que la flecha que representa la herencia tenga sentido deabajo hacia arriba, generando un diagrama tipo árbol. Si la clase base es abstrac-ta, se debe colocar el nombre con letra itálica (por ejemplo, Figura). Aunque pa-rezca una obviedad (dada la definición de herencia) tengamos en cuenta que, enel diagrama de las clases derivadas, no es necesario volver a indicar las propieda-des y los métodos heredados.

Escuela

+ Nombre: String

Secundaria

Figura 5. La herencia se representa mediante flechas sin relleno, apuntando hacia la clase base.

En el caso de las interfaces, UML prevé una forma de representarlas, como asítambién una notación especial para indicar la implementación de una interfaz porparte de una clase. Para indicar que se trata de una interfaz y no de una clase, en eldiagrama de clases se debe colocar el indicador interfaz sobre el nombre, en la pri-

Primaria Terciaria

Publica Privada

05_IntrodProg.qxd 23/7/07 20:16 Page 81

82

UML

mera división del rectángulo que representa en este caso la interfaz. Además, si biendesde el punto de vista del polimorfismo la implementación de interfaces resultasimilar a la herencia, no es lo mismo, por lo que UML hace la distinción corres-pondiente. Para especificar que una clase implementa una interfaz, se debe colocaruna flecha de punta hueca apuntando hacia la interfaz, pero con línea punteada.

En la Figura 6 se aprecia una interfaz (IComunicador) y una clase, la que implemen-ta (ComunicadorPorModem). Notemos que, a diferencia del diagrama de herencia,aquí sí debemos especificar en la clase todos los métodos y propiedades de la inter-faz, ya que al aceptar el contrato que la interfaz nos impone, debemos implemen-tarlo completamente (caso contrario ni el modelo ni el código serán válidos).

Figura 6. Al modelar la implementación de una interfaz, debemos volvera indicar todas las propiedades y métodos en la clase que la implementa.

<<interface>>IComunicador

+ Inicializar() : void+ Finalizar() : void+ <<property>> DispositivoListo() : bool+ CadenaRecibida(string) : void+ EscribirCadena(string) : void+ AsignarReceptorDeDatos(RecepcionDeDatos) : void

IDisponibleComunicadorPorModem

– puerto: SerialPort

+ Inicializar(): void+ Finalizar(): void+ <<property>> DispositivoListo(): void+ CadenaRecibida(string): void+ EscribirCadena(string): void

<<interface>>IComunidor

+ Inicializar(): void+ Finalizar(): void+ <<property>> DispositivoListo(): bool+ CadenaRecibida(string): void+ EscribirCadena(string): void+ AsignarReceptorDeDatos(RecepciónDeDatos): void

05_IntrodProg.qxd 23/7/07 20:16 Page 82

83

›DIAGRAMA DE SECUENCIA

DIAGRAMA DE SECUENCIA

> Varias veces dijimos que la programación orientada a objetos se basa en la re-presentación en software de los objetos que intervienen en el dominio de la apli-cación junto con las relaciones e interacciones entre ellos. Mediante el diagramade clases, UML permite especificar de manera estática las clases del modelo y susrelaciones. Para expresar la forma en que los objetos (no las clases) interactúanpara llevar a cabo su objetivo dentro de la aplicación y solucionar un problema,UML provee el diagrama de secuencia, que permite especificar los mensajes queintercambian los objetos, el orden en que lo hacen y cómo reacciona cada obje-to ante la llegada de un mensaje proveniente de otro.

ELEMENTOS DEL DIAGRAMA DE SECUENCIAA diferencia del diagrama de clases, en el diagrama de secuencia intervienen ins-

tancias, es decir, objetos concretos que pertenecen a una determinada clase. Los ob-jetos se representan simplemente como rectángulos con su nombre y la clase a laque pertenecen dentro de él, separadas por dos puntos (:). En caso en que no inte-rese la identidad de una instancia en particular, se puede omitir el nombre, colo-cando sólo el nombre de la clase a la que pertenece, precedida por los dos puntos.

Otro elemento de este diagrama son los mensajes. Desde el punto de vista de laimplementación, podemos considerar los mensajes como invocación a métodos:cuando un objeto A envía un mensaje B a un objeto C, podemos traducir comoque el objeto A invoca el método B del objeto C. Los mensajes se representan me-diante flechas simples, con el nombre del mensaje escrito sobre ellas.

Por último, dado que para representar una secuencia debemos especificar el or-den en que los mensajes son enviados, UML permite indicar una línea de tiem-po, que se coloca en el diagrama de manera vertical, y que consiste en una líneapunteada por cada una de las instancias que intervienen en el diagrama.

Para entender cómo funciona el diagrama de secuencia, imaginemos que tene-mos que representar un escenario de matriculación de un alumno en un curso.Tenemos una clase Alumno, una clase Curso y una clase Facultad. La clase Facul-tad tiene la capacidad de determinar si un alumno puede inscribirse en un curso(porque conoce las correlatividades y las asignaturas aprobadas por el alumno).Cuando un alumno quiere inscribirse, hace la solicitud al curso (mediante un

05_IntrodProg.qxd 23/7/07 20:16 Page 83

84

UML

mensaje), y el curso consulta con la universidad si se cumplen las condiciones. Sitodo está bien, el curso acepta la inscripción del alumno.

La Figura 7 representa este escenario mediante un diagrama de secuencia.

Figura 7. El diagrama de secuencia muestra la interacciónentre los objetos en un determinado escenario.

unAlumno : Alumno

Solicitud aprobada

SolicitarInscripcion(unAlumno)

VerificarCorrelatividades(unAlumno, unCurso)

unCurso: Curso : Universidad

PuedeCursar

Como observamos en el diagrama, el objeto Alumno envía un mensaje Solicita-rInscripcion al objeto Curso. Luego, éste envía un mensaje VerificarCorrelativida-des al objeto de clase Universidad, quien contesta afirmativamente. Ante la lle-gada de la respuesta de la universidad, el objeto Curso le confirma la inscripciónal objeto Alumno. Observemos que el tiempo corre hacia abajo, por lo que el or-den en que aparece cada mensaje en el diagrama es cronológico.

En la Figura 7, hay algunos detalles que aún no mencionamos. Los mensajes delínea punteada corresponden a las respuestas de un objeto a un mensaje determi-nado. Los rectángulos delgados sobre las líneas de tiempo corresponden a instan-cias particulares, esto es, cada rectángulo en la línea de tiempo de un objeto co-rresponde a una instancia particular.

05_IntrodProg.qxd 23/7/07 20:16 Page 84

85

›DIAGRAMAS DE CASOS DE USO

DIAGRAMAS DE CASOS DE USO

> Un caso de uso es un resumen de un escenario particular, que describe laforma en que los elementos externos (usuarios u otros sistemas) interactúancon el software que se está modelando. UML permite crear diagramas paramodelar casos de uso, que resultan de gran utilidad para documentar y paranegociar con los usuarios y clientes sobre la funcionalidad que tendrá el soft-ware una vez implementado.

En los diagramas de caso de uso, intervienen actores y casos de uso. Los actoresson cualquier elemento que puede interactuar con el software (usuarios, organiza-ciones o sistemas). Los casos de uso son secuencias de acciones que proveen al-gún tipo de valor para los actores. Los casos de uso se dibujan mediante óvalos consu nombre adentro, mientras que los actores se representan mediante hombreci-tos. Opcionalmente, puede dibujarse un rectángulo para indicar los límites del sis-tema y así dejar bien claro cuáles son las responsabilidades que se asumirán a lahora de la implementación (todo lo que está fuera de los límites, se asume que noserá responsabilidad de los desarrolladores).

En la Figura 8, se aprecia cómo el gerente de personal interactúa con el siste-ma de sueldos, tanto renovando contratos de personal como generando liqui-daciones de sueldos. Además del gerente, un sistema que pertenece al estadointeractúa con el sistema de sueldos solicitando el cálculo de los impuestos pa-ra controlar el estado impositivo de los empleados. Observemos también queun caso de uso no es independiente, sino que puede utilizar a otro para cum-plir su tarea (representado en la figura como una línea que une Generar Li-quidaciones con Calcular Impuestos).

RECURSOS EN LA WEB

En Internet hay una gran cantidad deinformación sobre UML, desde deta-lles básicos hasta ejemplos comple-tos y de gran complejidad. Sin duda, elsitio de cabecera es el oficial de UML(en inglés): www.uml.org.

Otra página de gran interés, tambiénen idioma inglés, que se puede visitares Agile Modeling (www.agilemode-ling.com/artifacts), que cuenta conuna sección completa dedicada a dia-gramas y modelos UML.

05_IntrodProg.qxd 23/7/07 20:16 Page 85

86

UML

� CONCLUSIONES

A lo largo del capítulo, vimos algunos de los diagramas que permite crear UML ysu aplicación en el ciclo de vida del desarrollo de software, sobre todo para do-cumentar las primeras etapas (análisis y diseño). Si bien, al ser visual, UML re-sulta bastante fácil de aprender, es recomendable familiarizarse primero con lastécnicas y conceptos generales de la orientación a objetos y luego dedicarse aaprender UML, de manera de poder sacarle el mayor provecho posible a este po-deroso lenguaje de modelado. También será imprescindible la lectura del libroUML Distilled, de Martin Fowler (traducido al español como UML gota a gota).

Figura 8. El diagrama de casos de uso especifica cómo se relaciona el sistema con el mundo exterior.

Sistema de Sueldos

Renovar Contratos

Calcular Impuestos

Generar LiquidacionesGerente de Personal

Sistema estatal de Control

05_IntrodProg.qxd 23/7/07 20:16 Page 86

APÉNDICE

El examen

En este apéndice, haremos un repaso general

de los principales conceptos aprendidos y veremos

algunas preguntas del ejemplo del examen

correspondiente a la estrella cero del programa

Desarrollador Cinco Estrellas 2005

(http://www.dce2005.com).

ATENCIÓN AL LECTOR > [email protected]

06_IntrodProg_ApendA.qxd 23/7/07 20:17 Page 87

88

EL EXAMEN

ALGORITMOSUn algoritmo es una secuencia ordenada y sistemática de pasos que lleva a la

solución de un problema o a realizar cierto cálculo complejo. Recordemos que sedebe tener en cuenta la importancia del orden de las operaciones. Si contamoscon una secuencia de pasos para realizar una tarea, pero en ella no importa el or-den en que los llevemos a cabo, porque igual alcanzamos el objetivo, no se tratade un algoritmo. Todo programador debe tener la habilidad para deducir algo-ritmos a partir de un problema, ya que esta tarea conforma el primer paso parala implementación de cualquier aplicación de software.

Cuando creamos un algoritmo para un problema determinado, normalmente,deberemos expresarlo para poder comunicarlo a los demás o para dejar documen-tada la idea. Existen distintas formas de expresar algoritmos, pero las dos más co-munes y más usadas son el pseudocódigo y los diagramas de flujo. El pseudocó-digo es una forma flexible y abierta de expresar algoritmos, pero sin las ambigüe-dades del lenguaje natural. Resulta parecido a un lenguaje de programación, pe-ro no existen reglas precisas que deban ser cumplidas al usarlo, con lo cual cadaprogramador puede escribir pseudocódigo como mejor le resulte. Por otro lado,los diagramas de flujo son una herramienta visual y más precisa, ya que cuentacon reglas que definen exactamente cómo debe expresarse cada tipo de estructu-ra de un algoritmo (como por ejemplo, puntos de decisión).

LENGUAJES DE PROGRAMACIÓNLos lenguajes de programación permiten escribir instrucciones para una com-

putadora utilizando palabras y símbolos pertenecientes a algún idioma humano.El principal objetivo de los lenguajes de programación es proveer una herramien-ta que resulte más sencilla que ingresar las secuencias de números que es capazde interpretar una computadora como instrucciones.

Según el grado de abstracción o de lo mucho que se aleje un lenguaje del códi-go nativo de la máquina, se puede clasificar en lenguaje de bajo nivel (como As-sembler), lenguaje de nivel intermedio (como C) o lenguaje de alto nivel (comopor ejemplo los lenguajes de .Net). En general, los lenguajes de bajo nivel sonmás difíciles de utilizar, pero permiten escribir programas más eficientes, mien-tras que los de alto nivel poseen mayor expresividad, ya que con una instruccióndel lenguaje es posible darle varias instrucciones a la máquina, incluso con un es-fuerzo mental menor por parte del programador.

06_IntrodProg_ApendA.qxd 23/7/07 20:17 Page 88

89

›PROGRAMACIÓN ESTRUCTURADA

Como la computadora sólo puede interpretar instrucciones expresadas como se-cuencias de números binarios (unos y ceros), es necesario traducir los programasescritos en algún lenguaje, a instrucciones que la máquina pueda entender. Paraello, podemos utilizar un intérprete o un compilador. Los compiladores toman eltexto del programa (el código fuente) y generan un archivo con instrucciones eje-cutables por la computadora. El proceso de compilación se realiza una sola vez:cuando el programa está terminado y antes de poder correrlo en la computadora.Los intérpretes, en cambio, toman cada una de las instrucciones del programa, lasconvierten a código de máquina y las ejecutan. A diferencia de la compilación, elproceso de interpretación se lleva a cabo cada vez que el programa se ejecuta; poresto, generalmente, los programas compilados funcionan un poco más rápido quelos programas interpretados. En .Net, al momento de compilar, no se genera códi-go de máquina, sino que se produce código en un lenguaje intermedio que luego,durante la primera ejecución, es traducido a lenguaje de máquina.

En algunos lenguajes, el compilador no genera el código definitivo, sino que ge-nera un archivo llamado código objeto, que luego debe ser enlazado con las li-brerías utilizadas para generar un único archivo ejecutable. El encargado de rea-lizar esto es un programa llamado linker (enlazador).

PROGRAMACIÓN ESTRUCTURADALa programación estructurada es un paradigma que propone construir pro-

gramas utilizando sólo tres tipos de construcciones: la secuencia de instrucciones,la ejecución condicional y la repetición. Frente a la programación lineal que uti-liza las instrucciones de salto (GOTO) para modificar el curso de ejecución, laprogramación estructurada representa una importante mejora en las formas deconstruir software, ya que permite obtener código mucho mejor escrito, más cla-ro, más legible, fácil de mantener y de modificar. Repasemos algunos de los prin-cipales conceptos de la programación estructurada:

Identificadores: un identificador es una palabra que se utiliza para darle nom-bre a algún componente del programa, ya sea una instrucción, un subprogramao una variable. La mayoría de los lenguajes de programación poseen reglas estric-tas para la escritura de nuevos identificadores, como por ejemplo, que deban co-menzar necesariamente con una letra del alfabeto o con un guión bajo.

Variables: es una posición de memoria donde se encuentra un dato que debe-mos manejar dentro del programa. Casi siempre, las variables poseen un nom-

06_IntrodProg_ApendA.qxd 23/7/07 20:17 Page 89

90

EL EXAMEN

bre, y se utiliza un identificador para nombrarlas y referenciarlas en el códigofuente. Las variables poseen un alcance o ámbito, que determina las porciones decódigo desde donde se puede acceder al valor contenido en la variable.

Tipos de datos: definen el rango de valores y las operaciones que se puedenaplicar sobre una variable. No todos los lenguajes exigen asociar un tipo de datoa una variable (como por ejemplo Visual Basic). Los lenguajes que obligan a de-finir las variables con tipo, se denominan comúnmente fuertemente tipados. Loslenguajes de esta clase son más seguros en cuanto a errores en tiempo de ejecu-ción, ya que permiten detectar asignaciones incorrectas a las variables durante elproceso de compilación del programa.

Sentencias: son acciones que pueden ser ejecutadas como parte del programa.La principal diferencia entre sentencia e instrucción es que una sentencia puedetraducirse en cero o más instrucciones. Una sentencia que se traduce en cero ins-trucciones se denomina no ejecutable. El ejemplo más conocido de sentencia noejecutable son los comentarios utilizados para dejar mensajes en el código fuen-te, que explican alguna idea o cualquier otro aspecto que el programador consi-dere necesario para aumentar la legibilidad del código. Siempre resulta una bue-na práctica el uso de comentarios. Las sentencias pueden ser simples o compues-tas. Una sentencia simple es una sentencia en sí misma, mientras que una sen-tencia compuesta consiste en dos o más sentencias simples agrupadas mediantealguna estructura de control, como puede ser un condicional.

Procedimientos y funciones: una de las técnicas más usadas para simplificar laimplementación de un programa consiste en dividirlo en unidades más pequeñasllamadas módulos o subprogramas. Generalmente, los módulos son implemen-tados como procedimientos o funciones. Los procedimientos son unidades inde-pendientes que pueden ser llamadas desde cualquier otra parte del programa yconsisten de una secuencia de instrucciones que se ejecutan y terminan, pero sindevolver nada a quien lo llamó. Las funciones, en cambio, luego de ejecutarse,devuelven un valor como resultado. Por eso, se utilizan para realizar algún cálcu-lo o alguna operación que requiera devolver un resultado.

PROGRAMACIÓN ORIENTADA A OBJETOSLa programación orientada a objetos (POO u OOP, por sus siglas en inglés) es

un paradigma de programación que propone identificar los objetos propios deldominio del problema por resolver, y representar sus propiedades y sus interac-

06_IntrodProg_ApendA.qxd 23/7/07 20:17 Page 90

91

›PROGRAMACIÓN ORIENTADA A OBJETOS

ciones mediante el código del programa. La POO permite lograr programas aúnmás fáciles de entender que con la programación estructurada, ya que hay unacorrespondencia casi directa entre la realidad y la representación de esa realidadmediante un lenguaje de programación. Además, utilizada correctamente, la pro-gramación orientada a objetos permite una mayor reutilización de código y unmejor encapsulamiento, lo que facilita el mantenimiento tanto para corregirerrores como para agregar funcionalidades nuevas.

Los conceptos más importantes que hay que conocer son el de clase y el de ob-jeto. Una clase es una abstracción de un grupo de objetos que comparten ciertascaracterísticas y comportamiento. Un objeto es un elemento particular de unadeterminada clase, y como tal, posee las mismas propiedades y comportamientoque los demás miembros de la clase, pero posee una identidad única. Esto signi-fica que cualquier otro objeto será distinto, por más que tenga las mismas pro-piedades. Los objetos se caracterizan por tener un estado, que consiste en el con-junto de valores de sus propiedades en una unidad de tiempo específica.

Otro concepto importante es el de encapsulamiento. Éste consiste en ocultar den-tro de una clase la implementación real de una propiedad o método, de manera quedesde afuera se acceda mediante una interfaz que oculte los detalles internos. Lograrun buen nivel de encapsulamiento es fundamental para reducir el impacto de loscambios que harán en un futuro. Los lenguajes de .Net permiten el encapsulamien-to mediante el uso de propiedades, que básicamente son una forma de exponer atri-butos de la clase, pero ocultando la forma interna en que se almacena ese valor.

Muchas clases poseen las mismas características que otras, aunque tienen algunaspropias. En situaciones así, podemos hacer uso de la herencia. La herencia es unatécnica que permite definir una clase como derivada de otra. Al hacerlo, la nuevaclase recibe o hereda todo el comportamiento y las propiedades de su clase padre.Los programadores y analistas más experimentados buscan crear jerarquías de he-rencia, de manera de aprovechar al máximo la reutilización de código de las clasessuperiores en las clases inferiores. En ocasiones, puede ocurrir que la clase base (laclase de la que heredan las otras) no represente un conjunto de objetos concretos yexista sólo para contener comportamiento y código común. Este tipo de clases sedenominan abstractas. Algunos lenguajes permiten que una clase herede de varias,pero esto muchas veces desemboca en un problema de implementación. Los len-guajes de la plataforma .Net sólo permiten heredar de una única clase. En .Net (yen Java también), si necesitamos abstraer una cierta funcionalidad común a va-

06_IntrodProg_ApendA.qxd 23/7/07 20:17 Page 91

92

EL EXAMEN

rias clases no relacionadas entre sí, podemos hacer uso de las interfaces, pareci-das a las clases abstractas con la diferencia que no tienen ningún método imple-mentado y que una clase puede implementar más de una interfaz, además de he-redar de una clase. Una de las capacidades más interesantes brindadas por la pro-gramación orientada a objetos es el polimorfismo Éste consiste en conocer la cla-se real de un objeto recién durante la ejecución del programa. El polimorfismose basa en la herencia y es la clave para lograr código extensible y flexible, atribu-tos muy deseados en todo programa.

DESARROLLADOR 5 ESTRELLASVeamos algunas de las preguntas del examen cero del DCE 2005. Los exáme-

nes de Desarrollador 5 Estrellas incluyen 20 preguntas de tipo multiple choice,donde debemos elegir entre 4 posibles respuestas. Para aprobar, es necesario res-ponder bien al menos el 70% de las preguntas.

1) ¿Cuál es la utilidad de los modificadores de acceso? A. Permiten definir el nivel de acceso de los miembros de una clase. B. Permiten definir niveles de autenticación y autorización de los métodos

de una clase. C. Permiten relacionar clases entre sí. D. Permiten crear instancias de clases.

La respuesta correcta es la A. Los modificadores de acceso permiten definirquiénes pueden acceder a una propiedad o método. Los más comunes sonpublic, private y protected.

2) Las estructuras de control selectivas: A. Dirigen el flujo de ejecución según la evaluación de expresiones. B. Permiten ejecutar un conjunto de sentencias repetidamente una cierta

cantidad de veces o hasta que se cumpla una determinada condición. C. Todas las opciones son correctas. D. Ninguna opción es correcta.

La respuesta correcta es la A. Recordemos que las estructuras de selección enla mayoría de los lenguajes son dos: if y select case (o switch en C#).

06_IntrodProg_ApendA.qxd 23/7/07 20:17 Page 92

93

›DESARROLLADOR 5 ESTRELLAS

3) ¿Qué es un algoritmo? A. Un software de aplicación. B. Cualquier código escrito en un lenguaje de programación. C. Un método para resolver un problema mediante una serie de pasos pre-

cisos, definidos y finitos. D. Las opciones B y C son correctas.

Esta pregunta es un poco tramposa. La respuesta correcta es la C. La res-puesta D no puede ser correcta porque la opción B afirma que un algorit-mo es código escrito en un lenguaje de programación, y aprendimos que siestá escrito en un lenguaje de programación ya se trata de un programa(que, generalmente, es la implementación de un algoritmo).

4) Un entorno integrado de programación normalmente contiene: A. Un editor de código fuente. B. Un compilador. C. Un depurador. D. Todas las opciones son correctas.

Ésta es bastante sencilla. Los entornos integrados de desarrollo justamentese llaman se esa manera, porque integran todas las herramientas necesariaspara la escritura, compilación y depuración de programas. Por lo tanto, larespuesta correcta es la D.

5) ¿Para qué sirve el encapsulamiento? A. Permite ocultar los métodos de una clase. B. Permite ocultar la implementación de los métodos de una clase. C. Permite identificar objetos de forma unívoca. D. Permite generar relaciones de herencia.

Como vimos en el Capítulo 4 y repasamos en este apéndice, el principal objeti-vo del encapsulamiento es el de ocultar la implementación de los métodos (ypropiedades) de una clase. La respuesta correcta, entonces, es la B.

06_IntrodProg_ApendA.qxd 23/7/07 20:17 Page 93

94

EL EXAMEN

6) ¿Cuál es el bloque que utiliza .NET para proveer administración estructu-rada de excepciones? A. OnError/Goto B. If/Else C. Throw D. Try/Catch/Finally

La respuesta correcta es la D. En Visual Basic 6, se utilizaba el OnError/Go-to para manejar los errores; pero desde la primera versión de, .Net se utili-zó el Try/Match/Finally, y se denomina estructurada por no utilizar GoTo.

7) Si se desea definir un comportamiento para un conjunto de clases no ne-cesariamente relacionadas entre sí, la mejor opción es: A. Definir una jerarquía de herencia entre las clases. B. Encapsular el comportamiento en una clase agregada. C. Definir una interfaz. D. Relacionar las clases mediante una asociación bidireccional.

Como hemos visto, la herencia no es una relación sólo sintáctica, sino másbien semántica. Entre la clase base y la derivada, se define una relación es-un.Si las clases no están relacionadas, entonces, no es natural usar herencia, y po-demos hacer uso de las interfaces para definir el comportamiento común. Porlo tanto, la respuesta correcta es la C.

8) ¿A qué se denomina comúnmente Cast? A. A un conjunto de datos que serán convertidos. B. A la conversión implícita de un objeto/tipo o tipo/objeto. C. A una forma explicita de convertir tipos de datos entre sí. D. Ninguna opción es correcta.

La respuesta correcta es la C. El Cast o Typecast es una conversión explícitaentre tipos de datos. Mediante la operación de cast le estamos diciendo alcompilador que nos hacemos responsables de las consecuencias de la conver-sión (como pérdida de precisión o, incluso, que los tipos sean incompatibles).

06_IntrodProg_ApendA.qxd 23/7/07 20:17 Page 94