This is default featured slide 1 title

Go to Blogger edit html and find these sentences.Now replace these sentences with your own descriptions..

This is default featured slide 2 title

Go to Blogger edit html and find these sentences.Now replace these sentences with your own descriptions..

This is default featured slide 3 title

Go to Blogger edit html and find these sentences.Now replace these sentences with your own descriptions..

This is default featured slide 4 title

Go to Blogger edit html and find these sentences.Now replace these sentences with your own descriptions..

This is default featured slide 5 title

Go to Blogger edit html and find these sentences.Now replace these sentences with your own descriptions..

viernes, 30 de agosto de 2013

TIPOS DE MEDIOS FISICOS

Tipos de medios físicos

Cable coaxial: consiste en un conductor de cobre rodeado de una capa de aislante flexible,una malla de hilos de cobre o aluminio y una cubierta exterior, como se muestra en la figura.
                     

Cable UTP:  Par trenzado no blindado, consiste en cuatro pares de cables codificados por color que han sido trenzados y cubiertos por un revestimiento de plástico flexible. los cogidos de color identifican los pares individuales de sus alambres y sirven para ayudar a la terminación de sus cables.

                              


Fibra óptica: el cableado de fibra óptica utiliza fibras de plástico o de vidrio para guiar los impulsos de luz desde el origen hasta el destino. los bits se codifican en la fibra como impulso de luz.
el medio es inmune a la interferencia electromagnética y no conduce corriente eléctrica no deseada cuando existe un problema de conexión a tierra. las fibras ópticas pueden utilizarse en longitudes muchos mayores que los medios de cobre sin la necesidad de regenerar la señal, ya que son finas y tienen una perdidas de señal baja.
se requieren dos fibras para una conexión full duplex ya que la luz solo puede viajar en un solo sentido a través de la fibra óptica.

                       

jueves, 22 de agosto de 2013

Packet tracer


Es un simulador de redes de la empresa CISCO, esta herramienta esta hecha para poder crear topologías, configurar los dispositivos y enviar paquetes en una red virtual que se crea en el mismo programa con el fin de enseñar de una manera  interactiva y sencilla  la creación, el funcionamiento y el uso de una red y de sus componentes.
Soporta los siguientes protocolos:
  • HTTP, TCP/IP, Telnet, SSH, TFTP, DHCP y DNS.
  • TCP/UDP, IPv4, IPv6, ICMPv4 e ICMPv6.
  • RIP, EIGRP, OSPF Multiárea, enrutamiento estático y redistribución de rutas.
  • Ethernet 802.3 y 802.11, HDLC, Frame Relay y PPP.
  • ARP, CDP, STP, RSTP, 802.1q, VTP, DTP y PAgP, Polly Mkt.
Nuevos recursos, actividades y demostraciones:
  • OSPF, IPv6, SSH, RSTP, Frame Relay, VLAN's, Spanning Tree, Mike mkt etc.
No soporta IGRP y los archivos hechos con Packet Tracer 5 no son compatibles con las versiones anteriores.

Tutoriales:

martes, 6 de agosto de 2013

Tipos Abstractos de Datos y Programación por Objetos

Tipos Abstractos de Datos y Programación por Objetos


Se discute qué es Abstracción de Datos y Programación por Objetos, usando como base el lenguaje Pascal.
La ingeniería de sistemas de información ha progresado gracias a la introducción de nuevas técnicas para construir programas. El primer gran avance lo constituye la programación modular, que complementa a la programación estructurada. Otros logros lo constituyen los llamados lenguajes de cuarta generación, que permiten desarrollar sistemas de información en un lenguaje muy especializado. Pero conforme avanza la tecnología de computadores es necesario crear programas cada vez más sofisticados. En la última década ha tomado gran auge el uso de la programación por objetos, que tiene como requisito la abstracción de datos, y que implica una nueva manera de diseñar programas. El lenguaje Smalltalk  ha causado gran revuelo, hasta tal punto que existen compiladores para lenguajes como C++, que han sacado la programación por objetos de los laboratorios de investigación, para ser utilizados en el quehacer diario de las empresas.
La programación que utiliza abstracción de datos se basa en el hecho de que en un programa se deben integrar y combinar los tipos básicos de datos, como números y caracteres, para formar estructuras de datos más complejas y así representar información dentro del computador. En general existe una fuerte relación entre todos los datos manipulados por un programa, por lo que es conveniente que esa relación esté claramente especificada y controlada, de forma que cada parte del programa "vea" sólo lo que necesita. 
Esto último es muy importante para separar el programa en partes independientes, o módulos, evitando así que cambios en una parte produzcan errores en otras partes del programa. Por ejemplo, en un programa que usa varios arreglos y matrices para almacenar información, es frecuente que al aumentar el tamaño de una dimensión se olvide aumentar la de los demás arreglos, por lo que el mantenimiento del programa es más difícil. El objetivo perseguido al usar abstracción de datos es lograr aislar todas estas dependencias, de forma que los cambios puedan ser hechos con un mínimo de esfuerzo y en una forma localizada. En nada ayuda tener que buscar por todo el programa en qué lugar debe hacerse cada cambio. También es importante especificar mediante la abstracción de datos qué es cada estructura de datos. Una lista, por ejemplo, es una estructura de datos que tiene un comportamiento muy bien definido: pueden insertársele nuevos elementos, recorrérsela, encontrar el primer y último elemento, etc. Un programador que use el tipo de datos Lista no debe necesitar descubrir de nuevo ese concepto: simplemente debe poderlo importar de una biblioteca.
Al implementar la Lista como un Tipo Abstracto de Datos (ADT: Abstract Data Type en inglés), el programador decide cuáles procedimientos se necesitan para manipular una lista, y define su interrelación. Un usuario del tipo de datos "lista" no necesitará entonces conocer cómo se interrelacionan (a nivel de implementación) los datos ni los procedimientos que manipulan listas pues le bastará usar las operaciones de la Lista para manejarla.  Al usar abstracción de datos el programador define cómo puede comportarse cada una de las variables de su programa. O sea que además de usar abstracción de procedimientos para construir el programa modularmente, deben especificarse las operaciones válidas sobre los datos. El objetivo es programar módulos que definan nuevos tipos de datos, y además que incluyan varios procedimientos (operaciones) que permitan manipularlos. Este dúo procedimiento-dato es un Tipo Abstracto de Datos. El programador-usuario del ADT podrá manipular las variables del tipo de datos únicamente por medio de sus procedimientos asociados. En un sólo módulo se "encapsula" el nuevo tipo de datos junto con sus procedimientos.
Al hablar de ADTs se dice que se usa Abstracción de Datos porque al definir un ADT el programdor especifica cuáles son las estructuras de datos que su programa utiliza. Se dice que se usa Encapsulamiento de Datos porque junto al tipo de datos también se definen las rutinas que permitirán utilizarlo. Por medio del Ocultamiento de Datos se evita que un programador-usuario del Tipo de Datos Abstracto cambie de forma impropia el valor de una variable. Generalmente al usar ADTs también se usan iteradores, que son módulos que permiten obtener todos los valores almacenados en una variable compuesta, como lo son la lista o el arreglo.
                  { Ejemplo de Encapsulamiento }

{ Turbo Pascal v5.5 }            { ADTs, sin ocultamiento }
TYPE                              TYPE
  Persona_T = OBJECT                Persona_T = RECORD
    direccion: STRING[20];            direccion: STRING[20];
    telefono : STRING[6];             telefono : STRING[6];
    nombre   : STRING[35];            nombre   : STRING[35];
    cedula   : STRING[9];             cedula   : STRING[9];
    nacido   : INTEGER;               nacido   : INTEGER;
      { ... más campos ... }            { ... más campos ... }
    FUNCTION Edad : INTEGER;        END;  { Persona_T }
      { ... más métodos ... }           { más operaciones ... }
                                    FUNCTION Edad(VAR p: Person_T)
  END;  { Persona_T }                                  : INTEGER;

  VAR                               VAR
    p : Person_T;                     p : Person_T;
  {...}                             {...}
    i := p.Edad;                      i := Edad(p);

   { "p recibe el mensaje Edad" }   { Se "calcula" la Edad de p }
Figura N° 2
Un lenguaje de programación soporta el uso de Abstracción de Datos si tiene construcciones sintácticas que le permiten al programador usar ADTs cómodamente. Por ejemplo, el Turbo Pascal v5.5 soporta encapsulamiento, pues le permite al programador definir un tipo de datos junto a sus operaciones, como se muestra en la Figura 2. Sin embargo, la versión 5.0 de ese mismo lenguaje no soporta encapsulamiento, aunque el programador puede simular encapsulamiento usando módulos Turbo Pascal (unidades).  El ejemplo de la Figura 2 muestra que al implementar un ADT deben definirse dos cosas: primero, los campos que se necesitan para almacenar los valores del dato, y segundo los procedimientos que permiten utilizarlo.
El asociar un tipo de datos con sus procedimientos en un módulo se conoce como encapsulamiento. En Pascal el encapsulamiento se simula mediante unidades, y en Modula-2 usando módulos. En otros lenguajes, como Turbo Pascal, Smalltalk, Simula y C++, el lenguaje incluye construcciones sintácticas que permiten encapsular un tipo de datos, también llamado una clase, con sus procedimientos. En este caso, los procedimientos se conocen por los nombres "operación", "procedimiento miembro" o "método".  La diferencia entre una operación, en el contexto de los ADTs, y un método, en el contexto de un lenguaje que soporta encapsulamiento, es puramente sintáctica. En el ejemplo Turbo Pascal v5.5 de la Figura 2 la forma sintácticamente correcta de invocar al método Edad() de Person_T es "p.Edad;" mientras que si se usa un lenguaje que no soporta encapsulamiento (como Modula-2) debe usarse la conocida forma sintáctica "Edad(p);".
La única diferencia entre las dos formas de invocar a la operación (o método) Edad() es el lugar en que la variable de tipo Person_T debe escribirse. La primera es la forma "Orientada o los Objetos" porque la variable "p" aparece de primero, mientras que la segunda es orientada a los procedimientos porque lo primero que aparece es el nombre de la rutina. Es este el simple cambio sintáctico que, con demasiada pompa, ha dado el nombre a la Programación Orientada a los Objetos (OOP: Object Oriented Programming en inglés). En el ejemplo de la Figura 2 la forma sintáctica "p.Edad;" se interpreta como si el objeto "p" es un ente activo en el programa, mientras que la forma "Edad(p);" es interpretada como si el trabajo en un programa lo realizan los procedimientos (que calculan), y no los objetos.
Encapsulación
Procedimiento
Tipo de Dato
Mensaje
Encapsulación
Procedimiento
Tipo de Dato
Mensaje
Abstracción
Subrutina
Objeto
Parámetro
Especificación
Rutina
Clase
Argumento
Diseño
Método
ADT
 
Ocultamiento
Operación
Tipo Abstracto de Datos
 
Figura N° 3: Tabla de sinónimos
Los computólogos hemos tenido la costumbre de crear muchos nuevos términos para viejos conceptos. Los términos estructuran de datos, tipo de datos, tipo abstracto de datos, objeto, clase y variable son muy similares. Todos sirven básicamente para lo mismo: definir variables en un programa, o sea, instancias del tipo de datos (aunque tiene más prestigio hablar de "objetos" o de ADTs, que de simples tipos). La Figura 3 es una lista de los términos usados para referirse a los mismos conceptos (aunque no todos son sinónimos exactos). Sin embargo, el contexto del discurso es muy importante: al hablar de ADTs en Smalltalk necesariamente debe suponerse que el concepto incluye cualidades como herencia y funciones virtuales. Las mismas palabras dichas en el contexto de Pascal o Modula-2 no pueden significar más que abstracción de datos.  Entonces, una operación es una rutina que está asociada a un tipo de datos, y que permite manipularlo, examinarlo y cambiarlo. El término "método" es sinónimo de operación y, aunque es bastante confuso, es el utilizado en ambientes Smalltalk.
Intrínsecamente ligado al concepto de encapsulamiento y abstracción está el concepto de ocultamiento de datos. Al ocultar datos, básicamente lo que se persigue es evitar que la representación usada para un ADT sea accesible a un programador-usuario. Por ejemplo, al implementar el ADT pila puede usarse una lista de nodos con punteros, o un arreglo. Si la representación del ADT es privada, entonces al usar una pila el programador no podría saber si la implementación que usa es una o la otra. El ocultamiento de datos es muy importante para lograr una mejor modularización, pues garantiza que el programador descuidado tenga acceso controlado a las campos que conforman una instancia de un ADT, evitando así que destruya inadvertidamente alguna relación necesaria entre esos campos. Paradójicamente, los muy conocidos lenguajes Smalltalk y Simula soportan tanto abstracción como encapsulamiento de datos, pero que no soportan ocultamiento de datos. El que los diseñadores de esos lenguajes no consideraran necesario el ocultamiento de datos indica que no es hasta hace muy pocos años que se ha llegado a entender bien cuáles son las cualidades que debe tener un programa que está bien modularizado.
 La Programación por Objetos es una extensión natural del uso de abstracción de datos. Si los conceptos asociados con ADTs se les agrega la Herencia y le Polimorfismo el resultado es OOP. Sin embargo, en la mente de muchos autores y programdores el término Programación por Objetos sólo significa usar herencia y polimorfismo, aunque no se utilice ocultamiento de datos o programación estructurada. OOP introduce nuevos vocablos para viejos conceptos, lo que en muchos casos confunde al neófito.
      La herencia es una facilidad puramente sintáctica del lenguaje de programación que permite extender un tipo de datos, agregándole al final nuevos campos. El efecto de la herencia puede simularse en la mayoría de los lenguajes tradicionales, pero el resultado es un programa menos elegante.
{ SIN Herencia }                { CON Herencia }
TYPE                            TYPE
  Punto_T = RECORD                Punto_T = OBJECT
   x,y : INTEGER                   x,y : INTEGER
  END;                            END;
 
  Circulo_T = RECORD              Circulo_T = OBJECT(Punto_T)
    p : Punto_T;
    r : REAL;                       r : REAL;
  END;                            END;
 
PROCEDURE Mueva(VAR p: Punto_T); PROCEDURE Mueva(VAR p: Punto_T);
 
VAR                               VAR
  p : Punto_T;                      p : Punto_T;
  c : Circulo_T;                    c : Circulo_T;
BEGIN                             BEGIN
  p.x   := ...                      p.x := ...
  c.p.y := ...  { .p se ve feo }    c.y := ...  { Uso directo de }
  c.r   := ...                      c.r := ...  { los campos.    }
  Mueva(p);                         Mueva(p);
  Mueva(c.p);   { otra vez .p! }    Mueva(c);   { SIN .p!!!      }
END;                              END;
Figura N° 4
      En la Figura 4 se muestra como es posible extender un tipo de datos por medio de la herencia. Como cualquier instancia del tipo extendido tiene como prefijo al tipo base, entonces cualquier función que utiliza una variable del tipo base puede también aplicarse al tipo extendido. Es por eso que en la columna derecha de laFigura 4 el procedimiento Mueva() se puede aplicar a las variables "p" y "c" indistintamente: como "c" es una variable de tipo Circulo_T necesariamente contiene a una variable de tipo Punto_T, sobre la que el procedimiento Mueva() puede operar.
      La reutilización de componentes, tan mentada por los adeptos a la OOP, es precisamente la posibilidad de usar una función sobre un tipo extendido. Pero esto realmente no es nada nuevo, como puede verse en la columna izquierda de la Figura 4, en la que basta incluir una referencia a un campo en un registro (.p) para obtener el mismo efecto que se logra por medio de la herencia.
      El otro componente importante de la programación por objetos es el uso del polimorfismo, que se implementa por medio del uso de punteros a funciones. Cuando se usa herencia para extender de muchas formas un tipo de datos, puede resultar luego conveniente que el procedimiento que se use para operar sobre un dato dependa del dato en sí, aunque el programador no haya especificado exactamente cuál es ese procedimiento.
       Punto_T         PROCEDURE Punto_T.Despliegue();    VIRTUAL;
          .
        /   \
      /       \
     __      _____
    /  \    |     |    PROCEDURE Circulo_T.Despliegue();  VIRTUAL;
   |    |   |     |
    \__/    |_____|    PROCEDURE Cuadrado_T.Despliegue(); VIRTUAL;
 
Circulo_T    Cuadrado_T
 
VAR
  VEC : ARRAY [1..3] OF ^Punto_T;
  p : Punto_T;
  c : Circulo_T;
  r : Cuadrado_T;
 
BEGIN
  { ... }
  VEC[1] := ADDR(p);
  VEC[2] := ADDR(c);
  VEC[3] := ADDR(r);
  { ... }
  FOR i := 1 TO 3 DO BEGIN
    VEC[i]^.Despliegue;
  END;
Figura N° 5

Por ejemplo, en la Figura 5 se muestra una jeraquía de objetos en que, por medio de la herencia, se extiende el tipo de datos Punto_T a un Circulo_T o a unCuadrado_T. Es natural que el procedimiento para desplegar un círculo sea totalmente diferente al que despliega un cuadrado. Sin embargo, ambos procedimientos tiene en común que existe un procedimiento llamado Despliegue() que permite desplegar variables de tipo Punto_T, que es el tipo base para Circulo_T yCuadrado_T.
      El código al final de la Figura 5 muestra como es posible tener un arreglo de punteros a variables de tipo Punto_T, en el que el procedimiento a usar para hacer el despliegue se escoge en tiempo de ejecución. Para que la decisión de cuál es "polimórficamente" el procedimiento que debe usarse para operar sobre una variable se tome en tiempo de ejecución, lo que se hace es almacenar en cada variable la dirección del procedimiento que le corresponde. Así, la variable "p" tendrá un puntero al procedimiento Punto_T.Despliegue(), "c" a Circulo_T.Despliegue() y "r" a Rectangulo_T.Despliegue(). A estas operacionesDespliegue() se les conoce como métodos virtuales, pues es en tiempo de ejecución cuando se decide cuál de ellas será invocada para cada una de las variables.
 
             ┌─────>o<*>────>Punto_T::Dibuje()
VEC[]        │      P
┌───┐        │
│ *─┼────────┘     __
├───┤             /  \
│ *─│───────────>│  C │<*>──>Circulo_T::Dibuje()
├───┤             \__/
│ *─┼────────┐     __
└───┘        │    /  \
             │    │ ││
             └───>││ │<*>───>Cilindro_T::Dibuje()
                  │ ││
                  \__/
                    T
Figura N° 6
En la Figura 6 se ve que cada valor de una clase polimórfica incluye un puntero a su método polimórfico. Por eso, el valor de la variable "P" incluye un puntero aPunto_T::Dibuje(), la variable "C" tiene un puntero al método polimórfico Circulo_T::Dibuje() así como la variable "T" incluye su puntero polimórfico haciaCilindro_T::Dibuje(). Este puntero polimórfico es el que se usa en la ejecución del ciclo "FOR" en que se invoca VEC[i]^.Despliegue, pues es usando el puntero polimórfico que siempre es posible determinar cuál es el método correcto que hay que invocar. Aunque parece que los valores del vector son uniformes, en realidad cada uno de ellos apunta a un valor de un tipo diferente que está bien identificado por su puntero polimórfico. De hecho, el tipo de "VEC[1]" es diferente al de "VEC[0]" ya al de "VEC[2]" aunque todos tienen en comúm que también son de tipo Punto_T.

 
VEC[]          P
┌───┐        ┌───┐
│ *─┼───────>│ x │
├───┤        ├───┤
│ *─┼──>C    │ y │     VMT Punto_T (Virtual Method Table)
├───┤        ├───┤     ┌───┐
│ *─┼──>T    │VMT│────>│ 8 │ == 2 + 2 + 4        sizeof(Punto_T)
└───┘        └───┘     ├───┤
                       │ *─┼───>"class Punto_T"  Hilera con el nombre RTTI
                       ├───┤
                       │ *─┼───>Punto_T::Dibuje()  Método virtual No.1
                       ├───┤
                       │ *─┼───>Punto_T::Borre()   Método virtual No.2
                       └───┘
Figura N° 7
      En realidad es muy honeroso repetir en cada valor todos los punteros polimórficos. Por eso, para cada tipo polimórfico el compilador crea una tabla de métodos virtuales (VMT: Virtual Method Table), en la que están unificados todos los punteros a métodos polimórficos, como se muesta en la Figura 7. De esta manera, cuando un valor tiene métodos virtuales, este hecho se represanta con un puntero a la VMT.
 
                ┌─────┬─────┬─┐
                │  x  │  y  │!│ Punto_T
                └─────┴─────┴─┘
                     ││
                     ││
                     \/
   //───────────────────────────────────\\
   ││───────────────────────────────────││
   ││                                   ││
   \/   Circulo_T                       \/   Cuadrado_T
┌───────────┬─┬───────┐                ┌───────────┬─┬───────┐
│  x  │  y  │!│ radio │                │  x  │  y  │!│ largo │
└───────────┴─┴───────┘                └───────────┴─┴───────┘
   ││                                   ││
   ││                                   ││
   \/  Cilindro_T                       \/   Rectangulo_T
┌───────────┬─┬───────┬────────┐       ┌───────────┬─┬───────┬───────┐
│  x  │  y  │!│ radio │ altura │       │  x  │  y  │!│ largo │ ancho │
└───────────┴─┴───────┴────────┘       └───────────┴─┴───────┴───────┘
Figura N° 8
      En la Figura 8 se muestran los campos de la jerarquía de tipos ( Punto_T ( Circulo_T ( Cilindro_T ) Cuadrado_T ( Rectangulo_T ) ) . El campo marcado "!" es el puntero a la VMT.
      Cabe mencionar que a las variables de programas que siguen el paradigma OOP se les llama objetos, o sea, que un objeto es una instancia de un tipo.
      En el argot popular se acepta que un lenguaje soporta la Programación por Objetos si brinda facilidades para implementar herencia (extensión de tipos), polimorfismo (funciones virtuales) y encapsulamiento. Sin embargo, cada lenguaje orientados a objeto soporta de manera distinta cada uno de estos conceptos. Como ha sucedido con otros lenguajes y paradigmas de programación, el ser orientado a objetos es una cuestión más de fé que académica.


                                   
TIPOS ABSTRACTOS DE DATOS

1.      La Abstracción
A pesar de que estamos acostumbrados a utilizar el término abstracción dentro del contexto de la programación, la verdad es que esta palabra tiene un origen mucho más lejano. Desde siempre, el hombre se ha tenido que enfrentar a problemas muy complejos, sin embargo con el paso del tiempo hemos descubierto un buen método para enfrentarnos a ellos: la abstracción. Abstraer consiste en centrarse sólo en la parte principal y esencial de los problemas, dejando así a un lado todos los detalles insignificantes o menos importantes.
Un buen ejemplo de la capacidad humana para la abstracción es la elaboración y lectura y un mapa. Cuando dibujamos un mapa de carreteras, reflejamos en él los elementos principales, los que tienen utilidad para su interpretación, como por ejemplo las autopistas, autovías, carreteras nacionales, áreas de servicio, gasolineras, etc. Otros datos como podrían ser museos, parques o monumentos no aparecen ya que se consideran innecesarios en este tipo de mapas. La abstracción es una de las herramientas fundamentales de la mente humana, ya que nos permite dividir los problemas en partes independientes y solucionar cada una por separado.

2.      La Evolución De La Abstracción En La Programación
En los primeros tiempos de la informática, los programadores se comunicaban con las máquinas en binario, lo cual resultaba ser una tarea extremadamente larga y complicada. Al cabo de un tiempo apareció el código ensamblador, cuyos nemotécnicos facilitaron notablemente el trabajo de los programadores al evitar que tuviesen que recordar las secuencias de unos y ceros que formaban cada instrucción. Estos nemotécnicos constituyeron la primera escala de abstracción de la era informática.
Unos años más tarde llegaron los lenguajes de alto nivel y con ellos las macroinstrucciones. Gracias a estos lenguajes, los programadores pudieron comenzar a escribir software genérico, es decir, podían programar sin preocuparse de la máquina sobre la que iba a correr el programa. Esto se debía a que las instrucciones de los lenguajes de alto nivel producían varias acciones en la máquina, independientemente de las arquitecturas concretas de cada una de ellas. Con este tipo de lenguajes llegaron también las sentencias de control más habituales como los bucles o sentencias if-then.
En definitiva, la complejidad iba creciendo a medida que lo hacía la abstracción. Así fueron surgiendo los procedimientos y funciones, los módulos y posteriormente los tipos abstractos de datos.

3.       Abstracción Funcional Y Abstracción De Datos
En la programación, la abstracción puede aplicarse de dos modos distintos dando lugar a la abstracción funcional y la abstracción de datos.
La abstracción funcional aparece al pensar de manera abstracta las operaciones que necesitamos para resolver un problema. Este tipo de abstracción nos permite definir operaciones nuevas en una aplicación que anteriormente carecía de ellas. La abstracción funcional fue la primera en aparecer ya que es fácil de llevar a la práctica debido a que su implementación es posible en la gran mayoría de los lenguajes de programación. Suele corresponderse con el uso de procedimientos o funciones.
La abstracción de datos surge cuando se abstrae el significado de los diferentes tipos de datos que aparecen en nuestro problema. Este tipo de abstracción nos permite crear nuevos tipos de datos pensando en los posibles valores que pueden tomar y en las operaciones que los manipulan. Como cabe esperar, estas operaciones serán a su vez abstracciones funcionales.
La abstracción de datos es más reciente que la funcional, ya que los primeros lenguajes de programación no ofrecían demasiadas facilidades para su uso. Uno de los primeros mecanismos que permitió esta abstracción fueron las clases de Simula.

4.      Datos, Tipos De Datos Y TAD
Para hablar de la abstracción es necesario tener clara la diferencia que existe entre los datos, los tipos de datos y los tipos abstractos de datos.
Los datos son los valores que manejamos en la resolución de un problema, tanto los valores de entrada, como los de proceso y los de salida. Es decir, los datos son información y por lo tanto distinguimos varios tipos de datos.
Un tipo de dato se puede definir como un conjunto de valores y un conjunto de operaciones definidas por esos valores. Clasificar los datos en distintos tipos aporta muchas ventajas, como por ejemplo indicarle al compilador la cantidad de memoria que debe reservar para cada instancia dependiendo del tipo de dato al que pertenezca.
Los tipos de datos abstractos van todavía más lejos; extienden la función de un tipo de dato ocultando la implementación de las operaciones definidas por el usuario. Esta capacidad de ocultamiento nos permite desarrollar software reutilizable y extensible, lo cual veremos más adelante cuando hablemos de modularidad.
Tipos Abstractos De Datos
Un tipo de datos definido por el programador se denomina tipo abstracto de datos (TAD) para distinguirlo de los tipos predefinidos de datos. Los tipos abstractos de datos están formados por los datos (estructuras de datos) y las operaciones (procedimientos o funciones) que se realizan sobre esos datos. El conjunto de operaciones definidas sobre el TAD debe ser cerrado, es decir, sólo se debe acceder a los datos mediante las operaciones abstractas definidas sobre ellos. La abstracción de datos sólo permite acceder a ellos de manera controlada.
Las estructuras de los TAD se componen de dos partes: la interfaz y la implementación. Esto se debe a que las estructuras de datos reales que utilizamos para almacenar la representación de un tipo abstracto de datos son invisibles para los usuarios o clientes. Mientras que en la interfaz se declaran las operaciones y los datos, la implementación contiene el código fuente de las operaciones y lo mantiene oculto al usuario.
Las principales ventajas que nos aportan los TAD son las siguientes:
1. Mejoran la conceptualización y hacen más claro y comprensible el código.
2. Hacen que el sistema sea más robusto.
3. Reducen el tiempo de compilación.
4. Permiten modificar la implementación sin que afecte al interfaz público.
5. Facilitan la extensibilidad.

5.    Construcción De Un TAD
La construcción de un TAD consta de dos fases bien diferenciadas entre ellas: la especificación (formal e informal) y la implementación.
Las características de un TAD no deben depender de su realización concreta, sino solamente de cómo queremos que sea su comportamiento, lo cual llamamos especificación. Para la especificación de un tipo abstracto de datos en lenguaje natural (especificación informal) hemos de seguir el siguiente esquema:
TIPO DE DATOS Nombre del tipo (Lista de operaciones)
VALORES: Descripción de los posibles valores
OPERACIONES: Descripción de cada operación
Primero indicaremos el nombre del TAD y citaremos todas las operaciones definidas. En el apartado valores describiremos los posibles valores de los datos de este tipo, pero lo haremos desde un punto de vista abstracto, sin pensar en la posible realización concreta. Finalmente en el apartado operaciones haremos una descripción de cada una de las operaciones definidas sobre el TAD. En la especificación informal, habitualmente hacemos referencia a conceptos con los cuales el lector está familiarizado (como por ejemplo conceptos matemáticos). El problema surge cuando estos datos auxiliares no están definidos tan precisamente.
La especificación formal nos permite definir conceptos de manera mucho más precisa. Para ello utilizaremos este esquema:
Tipo: Nombre del tipo de datos
Sintaxis: Forma de las operaciones
Semántica: Significado de las operaciones
En el apartado sintaxis proporcionamos el tipo de datos de entrada y de salida de cada una de las funciones definidas sobre el TAD, mientras que en semántica describiremos sus comportamientos. Sin embargo, ésta vez lo haremos siguiendo unas normas algebraicas básicas.
En la implementación del TAD lo que hacemos es elegir la forma en que se van a representar los distintos valores que tomarán los datos. También seleccionaremos la manera en que se realizarán las operaciones. Para esta elección debemos tener en cuenta que todas las operaciones se realicen de la forma más eficiente posible, aunque con la práctica veremos que la mayoría de las veces una implementación facilita mucho algunas operaciones mientras que complica otras.
6.    Modularidad
La programación modular descompone un programa en un pequeño número de abstracciones independientes unas de otras pero fáciles de conectar entre sí. Como hemos visto anteriormente, un módulo se caracteriza principalmente por su interfaz y su implementación. La programación modular sigue el criterio de ocultación de información: si no se necesita algún tipo de información, no se debe tener acceso a ella.
La modularidad es un aspecto muy importante en los TAD, ya que es el reflejo de la independencia de la especificación y la implementación. Es la demostración de que un TAD puede funcionar con diferentes implementaciones.
Además de esto, la programación modular ofrece otras ventajas, como por ejemplo un mejor reparto del trabajo y una detección de fallos mucho mejor.
7.    TAD Más Comunes
Los tipos abstractos de datos básicos se clasifican habitualmente, atendiendo a su estructura, en lineales y no lineales.
8.1. TAD lineales
8.1.1  Listas
Esta forma de almacenar elementos consiste en colocarlos en una lista lineal que tiene un enlace por cada elemente para determinar cual es el elemento siguiente. Las listas se utilizan habitualmente para guardar elementos del mismo tipo y se caracterizan porque pueden contener un número indeterminado de elementos y porque siguen un orden explícito. La lista de cero elementos se denomina lista vacía.
8.1.2 Colas
En el contexto de la programación, una cola es una lista en la que los elementos se insertan por un extremo (llamado fondo) y se suprimen por el otro (llamado frente). En esta estructura de datos el primer elemento que entra es el primero en salir. Es un tipo de dato muy común tanto dentro de la informática como en la vida real.
8.1.3 Pilas
Una pila es una estructura de datos en la cual todas las inserciones y las eliminaciones se realizan por el mismo extremo, denominado cima de la pila. En una pila, el último elemento en entrar es el primero en salir, al contrario de lo que pasa en las colas.
8.2 TAD no lineales
8.2.1 Árboles
El árbol es un TAD que organiza sus elementos (nodos) de forma jerárquica. Si una rama va del nodo a al nodo b, entonces a es el padre de b. Todos los nodos tienen un padre, excepto el nodo principal, denominado raíz del árbol.
8.2.2 Árboles binarios de búsqueda
El árbol binario de búsqueda es una variación del TAD árbol. Se trata de aquellos árboles binarios (cada nodo tiene dos hijos como máximo) en los cuales todos los datos del subárbol izquierdo son menores que los datos del nodo, y los datos del subárbol derecho son mayores que los datos del nodo.
8.2.3 Grafos
Hemos visto que los árboles binarios representan datos entre los cuales existe una jerarquía. Los grafos sin embargo se utilizan para representar relaciones arbitrarias entre datos. En su representación, cada elemento de problema forma un nodo. La relación entre nodos forma una arista que puede ser dirigida o bidireccional (no dirigida).

Cibergrafia.