lunes, 17 de junio de 2013

Escribir un programa orientado a objetos (I)


Se trata de una serie de artículos prácticos para crear un primer Programa Orientado a Objetos con Visual Basic .Net se comienza con un programa sencillo y se le van añadiendo complejidad con nuevos elementos.


Con este artículo aprenderemos a:



Decidir las clases que debe tener el programa.

Crear una clase con variables, propiedades y métodos.


Los bloques principales de un programa orientado a objetos son las clases, un objeto es una ocurrencia concreta de una clase (un coche concreto es una ocurrencia concreta de la clase coche genérica). Un objeto al ser concreto toma atributos concretos definidos en sus propiedades (en un coche sería el color, modelo, etc.) y métodos que son las acciones que tienen permitido hacer (en un coche los métodos serían acelerar, frenar, girar).


Diseñaremos e implementaremos las clases usando propiedades y métodos. A continuación, declararemos e inicializaremos las variables de las clases. Por último, implementaremos una solución llamando a los métodos, propiedades y a las variables de la clase.


Hospital: Un primer Programa Orientado a Objetos


En la construcción de un sistema de información para el control hospitalario se revelaron los siguientes conceptos:

- Hospital: con los datos, Nombre, Dirección y Teléfono

- Sala: con los datos, Número y Cantidad de camas

- Médico: con los datos, Identidad, Nombre y Especialidad

- Paciente: con los datos, Identidad, Nombre, Dirección y Fecha de nacimiento.

Por otra parte, las relaciones reveladas entre dichos conceptos son:

-Cada hospital tiene varias salas. Todas y cada una de ellas pertenecen a un hospital (y sólo a uno).

-Cada médico trabaja en un único hospital, todo hospital tiene al menos 10 médicos.

-Un paciente puede estar internado; si lo está, estará en una sala y sólo en una.

-La capacidad máxima de camas que puede tener una sala es de cinco pacientes.

-Cada paciente puede ser atendido por más de un médico (pero por lo menos por uno) y a su vez un médico puede atender a varios pacientes.

Se trata de implementar un programa que permita la gestión de un grupo de hospitales.

El programa tendría varias pestañas para añadir/cambiar/eliminar los datos correspondientes, la pestaña paciente sería la más compleja y sería de este tipo:

Escribir un programa orientado a objetos




Diseño de las clases


Para encontrar las clases que se necesitan, hay que definir los objetos que usaremos, así como las propiedades de estos objetos y los métodos de comportamiento de estos objetos.

Hay muchas formas de diseñar clases, aquí se inicia con un análisis del texto del problema.

Los nombres son seleccionados como candidatos para las clases, mientras que los verbos se convierten en candidatos para los métodos. En el curso del análisis, se eliminarán muchos de los nombres de los candidatos, y se pueden descubrir clases que no se encuentran entre los nombres de la especificación. Después de determinar los objetos, propiedades y métodos que pertenecen a sus clases, a continuación, se puede entonces escribir especificación de la clase que se va a utilizar en la ejecución.

Búsqueda de Clases


Dado un enunciado, buscar los Nombres del enunciado para encontrar las Clases.

Por ejemplo:

Se genera en el ordenador un programa que gestione un grupo de hospitales en el que se debe definir que médico trabaja en cada hospital y que pacientes atiende. También se necesita saber en que sala de que hospital se ubica cada paciente. Los médicos atenderán a los pacientes en función de su especialidad y de la dolencia del paciente.

Hay que gestionar las altas y bajas de los pacientes, así como la sala y médicos asignados.

Por motivos obvios descartamos las clases ordenador y programa, quedando hospital, médico, paciente, sala, especialidad y dolencia.


Especialidad y dolencia son atributos de médico y paciente, por lo que los dejamos como propiedades de sus respectivas clases.

Búsqueda de Propiedades y Métodos

Para buscar los métodos se buscan los verbos en el enunciado:

Se genera en el ordenador un programa que gestione un grupo de hospitales en el que se debe definir que médico trabaja en cada hospital y que pacientes atiende. También se necesita saber en que sala de que hospital se ubica cada paciente. Los médicos atenderán a los pacientes en función de su especialidad y de la dolencia del paciente.

Hay que gestionar las altas y bajas de los pacientes, así como la sala y médicos asignados.

Generar no es relevante, gestionar y definir tampoco. Trabaja y Atiende son métodos del Médico, saber es irrelevante.

Ubicar (un paciente) es un método del hospital, Atendido por (un médico) parece razonable incluirlo como un método del hospital más que del Médico. Trabaja en (un hospital) también parece referido al hospital. Por lo que parece evidente que tendremos una clase CHospital.

Tanto pacientes como médicos son personas con atributos muy similares, por lo que se puede optar por fusionarlos en una única clase CPersona que distinga si en Médico o no con un atributo booleano

Finalmente se revisa de nuevo el enunciado para ver si las clases y los métodos hacen lo que les pedimos y se ordenan en una tabla.


Clase

Propiedades

Métodos

CHospital

Salas

Teléfono

Direccion

AltaMedicoHos

BajaMedicoHos

UbicarPaciente

CPersona

DNI

Fecha_Nacimiento

Direccion

Dolencia/Especialidad

Medico

Alta

Baja

AsignarMedicoPac

El objetivo es que la mayor parte de la implementación de una clase sea invisible al usuario externo, es decir que sea privada en la mayor medida posible para que el usuario la utilice como una caja cerrada. (Cuando nos referimos al usuario no nos referimos al usuario de la aplicación sino al usuario del código, es decir al desarrollador que utilizará luego estas clases para implementar la funcionalidad de la aplicación)

Para construir código como una caja cerrada, en vez de definir las variables como públicas, se crean como variables privadas y luego se crea una propiedad por cada variable para acceder a ella desde el exterior sin tocarla en la clase.

Por ejemplo, puedo acceder a m_telefono desde el exterior a través de este código:

Private m_telefono as string <- Variable
Public Property Telefono() As String <- Propiedad

Get

   Return (m_telefono)

End Get

Set(ByVal value As String)

    m_telefono = value

End Set

End Property

El orden en el que deben aparecer en una clase es:

Declaraciones de los campos

Constructores

Propiedades

Métodos.

Probar el diseño de la clase

Conviene leer de nuevo el enunciado para determinar si las clases, sus propiedades y sus métodos se ajustan a la funcionalidad necesaria para resolver el problema.

Clases Propiedades y Métodos

----------------------------------------------------------------------

Clase CHospital

Propiedades:
Dim num_salas as integer
Dim direccion as string
Dim telefono as string

Métodos:
AltaMedicoHos
BajaMedicoHos
UbicarPaciente

----------------------------------------------------------------------

Clase CPersona

Propiedades:
Dim DNI as string
Dim Fecha_Nacimiento as date
Dim Direccion as string
Dim Dolen_Espec as string
Dim Medico as boolean

Métodos:

Alta
Baja
AsignarMedicoPac

----------------------------------------------------------------------

Crear la Clase CHospital


El siguiente ejercicio cubre los conceptos básicos de la implementación de la clase con la clase CHospital como ejemplo. Para implementar la biblioteca de clases, vamos a usar algunas de las herramientas de desarrollo proporcionado por Microsoft Visual Studio. En el entorno de desarrollo integrado (IDE).

1. En el IDE, hacer clic en el menú Archivo, seleccionar Nuevo y, a continuación, hacer clic en Proyecto. El cuadro de diálogo Nuevo proyecto se abre.


Nuevo proyecto Visual Studio



2. Seleccionar Proyectos de Visual Basic en el árbol tipos de proyecto (1), hacer clic en aplicación para Windows (2) en la lista de plantillas.

Nueva windows aplication Visual Studio


3. Introducir Hospital en el cuadro Nombre y hacer clic en Aceptar.

4. Mostrar el Explorador de soluciones, seleccionar el Explorador de soluciones en la vista del menú.

proyecto visual studio


5. Hacer clic en el proyecto Hospital en el Explorador de soluciones. Botón derecho del ratón y añadir (add), y nuevo objeto (new item).


Añadir objeto visual studio


añadir clase visual studio


6. Elegir Class y Teclear CHospital.vb en el cuadro Nombre, tener en cuenta que el nombre de clase se inicia con una mayúscula y se escribe en singular.

7. Hacer clic en Añadir (Add). El IDE agrega un archivo a su proyecto. El archivo incluye la definición básica de una clase, como se muestra en la pantalla siguiente.

Clase visual basic

La clase de Visual Basic contiene el mínimo para una declaración de clase. Ésta es la sintaxis
para la declaración de una clase en Visual Basic:

Class NombreClase

End Class

En este caso, la clase se denomina “CHospital”. El IDE agrega el modificador público que se muestra e indica que la clase se puede utilizar durante todo el proyecto

Añadir los campos NumSalas, Telefono y Direccion a la clase


Un campo es una variable declarada en un bloque de clase. Los campos pueden ser de cualquier tipo de .NET tal como entero o booleano, etc;. O de una clase de .NET, como de tipo TextBox o ListBox, o cualquier otra clase que se haya creado.

1. Localizar el principio de la definición de clase.

En Visual Basic, la definición de clase se inicia inmediatamente después de la línea que

muestra el nombre de la clase.

2. Agregar el siguiente código dentro de la clase para crear los campos Salas, Teléfono y Dirección.


Public NumSalas As Integer = 0
Public Telefono As string = ""
Public Direccion as string = ""

Sugerencia. Por convención, las letras iniciales de los nombres de los miembros públicos (campos, propiedades, métodos y eventos) de una clase se capitalizan (Campotexto) o se intercapitalizan (CampoTexto).

De acuerdo con el código, que se ha especificado, los valores iniciales de los campos: cero para el campo entero NumSalas, y cadena vacía para los campos de cadena de texto Telefono y Direccion. Un principio básico de programación orientada a objetos es que un objeto debe mantenerse en un estado coherente. Esto significa que el estado del objeto (los valores de sus campos) Deben representar a un estado usable. Si no se ha inicializado el campo, Los valores por defecto deben ser "" para los campos string y 0 para los campos integer.

Aunque los valores sean aceptables para un Hospital, y se podría dejarlos sin inicializar. Debido a que los compiladores pueden cambiar los valores por defecto, se deben evitar dichos problemas inicializando los campos.

El código de cliente (el código que utiliza un objeto de la clase Hospital) es capaz de leer y escribir en cualquier campo declarado con la palabra clave pública (Public).

Proporcionar acceso directo a los datos de la clase es una violación del principio de orientación a objetos. La ocultación de información estipula que el cliente no debe tener conocimiento de la
estructura subyacente de los datos de un objeto. En la siguiente sección, aprenderemos cómo permitir que el código de cliente escriba y lea campos de la clase CHospital sin revelar detalles sobre la implementación interna de la clase.

Añadir la propiedad Salas


Una propiedad es una construcción de programación que permite al código obtener y establecer un valor. Por lo general, los códigos constructores de la propiedad Get y Set deben ser campos privados de la clase.

En el código de cliente, un campo público y una propiedad se usan de la misma forma, por ejemplo.

HospitalNorte.Salas y HospitalNorte.Direccion

Añadir el siguiente código a la clase CHospital después de las declaraciones de Salas, Telefono y Direccion.

Private m_num_salas As integer

Este código crea un campo privado en la clase CHospital. El código de cliente no tiene el acceso a esta propiedad.

Sugerencia: Los campos privados de una clase se declaran mediante el prefijo m_ para identificarlos como datos de los miembros. Los nombres particulares de campo no se capitalizan.

Añadir el siguiente código a la clase CHospital después de la declaración m_direccion.

Public Property NumSalas() As Integer

Get

       Return m_num_salas

End Get

Set(ByVal value As Integer)

       m_num_salas = value

End Set

End Property

Estos bloques de sintaxis definen las propiedades de la clase. La propiedad aparece en el título
Y con IntelliSense sale una lista desplegable mostrando sus propiedades. El bloque de propiedades permite controlar el acceso a la propiedad.

Se puede agregar código de validación para el bloque Set para garantizar que sólo recoge valores razonables asignados al campo m_salas subyacente.

Nota: Hay que tener en cuenta una diferencia importante entre los campos y las propiedades.

En un campo se reserva un lugar en la memoria, y contienen los datos reales de la clase.

Las propiedades proveen el acceso a los datos pero no son ellas mismas los datos.

En estos ejercicios, se usa la palabra Set en el sentido de establecer el cambio de una propiedad.

Y se usa la palabra Get en el sentido de recuperar el valor de una propiedad.

Los bloques Get y Set de una propiedad pueden ser llamados getters y setters, o accesores.

El bloque de propiedad es más flexible de lo que se ha visto aquí. Las propiedades pueden ser públicas o privadas, de lectura/escritura, sólo lectura o sólo escritura. En Visual Basic, las declaraciones de la propiedad pueden incluso tomar un parámetro.

Un poco sobre las propiedades


Se puede usar la palabra propiedades como significado de la información sobre un objeto (por ejemplo el color de un coche es una propiedad del coche) o también utilizarla en el sentido de la construcción sintáctica de un programa (propiedad color de la clase CCoche) El significado de la palabra se determinará por el contexto. Las propiedades deben validar los datos de la clase y ocultar su implementación.

Añadir una propiedad a una clase para controlar el acceso a los datos de la clase requiere un esfuerzo muy bajo y se obtiene con ello un beneficio al poder agregar fácilmente una validación o cambiar incluso la implementación si fuera necesario sin afectar por ello al resto del programa.

En cualquier caso no se deben usar campos públicos en la clase a no ser que se tenga una fuerte razón para ello.

Añadir el método AltaMedicoHos

Antes de nada hay que añadir el Objeto Microsoft Remote Data Object 2.0 al proyecto para poder acceder a la base de datos. Para ello procedemos del siguiente modo:

añadir una referencia a un proyecto Visual Studio


Y elegimos Microsoft Remote Data Object 2.0

Microsoft Remote Data Object 2.0

Creamos un módulo general para colocar las variables globales.

Module General

     Public glbBaseDatos As RDO.rdoConnection

End Module

Y esta es la definición que quedaría dentro de la clase CHospital

Public Function AltaMedicoHos(ByVal Nom_Medico As CPersona, ByVal Hospital As CHospital) As Boolean

Dim Reg As RDO.rdoResultset
Dim strSQL As String
Reg = Nothing

On Error GoTo Errores_AltaMedicoHos

strSQL = "INSERT INTO dbo.tbMedHos (strId_MED,strID_HOS) VALUES (" & Nom_Medico.Medico & "," & Hospital.Codigo & ")"

glbBaseDatos.Execute(strSQL)

Reg.Close()
Return True

Errores_AltaMedicoHos:
Return False
End Function

Se muestra a continuación la definición completa de la clase para este proyecto:

Public Class CHospital
Private m_codigo As String
Private m_num_salas As integer = 0
Private m_telefono As String = ""
Private m_direccion As String = ""

Public Property Codigo() As Integer

Get
      Return m_codigo
End Get

Set(ByVal value As Integer)
        m_codigo = value
End Set
End Property

Public Property NumSalas() As Integer
Get
      Return m_num_salas
End Get

Set(ByVal value As Integer)
        m_num_salas = value
End Set
End Property

Public Property Telefono() As String

Get
         Return m_telefono
End Get

Set(ByVal value As String)
          m_telefono = value
End Set
End Property

Public Property Direccion() As String

Get
        Return m_direccion
End Get

Set(ByVal value As String)
         m_direccion = value
End Set
End Property

Public Function AltaMedicoHos(ByVal Nom_Medico As CPersona, ByVal Hospital As CHospital) As Boolean

Dim Reg As RDO.rdoResultset
Dim strSQL As String
Reg = Nothing

On Error GoTo Errores_AltaMedicoHos

strSQL = "INSERT INTO dbo.tbMedHos (strId_MED,strID_HOS) VALUES (" & Nom_Medico.Medico & "," & Hospital.Codigo & ")"






glbBaseDatos.Execute(strSQL)
Reg.Close()
Return True
Errores_AltaMedicoHos:
Return False
End Function
End Class

Campos, propiedades, métodos y constructores deben aparecer en una definición de una clase


Para una buena organización conviene seguir el siguiente orden:

Declaraciones de campos
Constructores
Propiedades
Métodos

Resumen


Añadir una clase al proyecto. En el menú de proyecto clicar Add Class o escribir

Class NombreClase
End Class

Añadir un campo a la clase, declarar una variable en el bloque de la clase.

Class NombreClase
Dim Campo as string
End Class

Añadir una propiedad a la clase, escribir el método dentro del bloque de la clase

Public Property Titulo() As String
Get
‘ Aquí retorna un valor del campo
End Get

Set(ByVal Value As String)

‘ Aqui pone un valor al campo
End Set
End Property

Añadir un método a la clase, escribir el método dentro del bloque de la clase

Class NombreClase
Private Sub Metodo()
End sub
End Class


No hay comentarios:

Publicar un comentario