Atributos de Clase

31/07/2006 - 06:01 por Cristian | Informe spam
Estimados,

Estoy en el desarrollo de una aplicación y para ello estoy utilizando una
capa de conexión (App Block), una capa de negocio y la interfaz de usuario
(Aplicación). Debo aclarar que es primera vez que utilizo el modelado UML.
Durante el modelo de clases (después de analizar mis casos de usos y modelo
de clase de primer nivel) me surgió una duda que me tiene algo confundido.
Tengo una clase "Impresoras" de la siguiente manera:

Impresora
CodImpr: String
PathImpr: String
Description: String
Manager: String
GetPrinter() : Dataset
AddPrinter(): Void
...
...

Mi confusión pasa cuando quiero agregar una impresora, o sea utilizar el
método AddPrinter(), según yo tengo 2 formas de poder hacerlo.
1.- En la aplicación, al agregar la impresora, setear cada atributo de la
clase con su respectivo valor y al final llamar al método AddPrinter() que
tomará cada valor (entro de la clase) y lo insertará en la BD, o sea en mi
aplicación tendría algo asi

oImpresora.CodImpr = "001"
oImpresora.PathImpr = "\\serverprint\P5XCONTA"
oImpresora.Description = "Sector contable."
oImpresora.Manager = "Juan Gómez."
oImpresora.AddPrinter

2.- En la aplicación, al agregar la impresora, pasar cada atributo como
parte de la función AddPrinter(), o sea en mi aplicación tendría algo así..
...
oImpresora.AddPrinter("001", "\\serverprint\P5XCONTA", "Sector Contable",
"Juan Gomez")

(Acá obviamente el método de mi clase debe tener definido cada atributo:
AddPrinter(CodImpr as string, etc..))
Utilizando esa forma, no me hace mucho sentido tener los atributos definidos
dentro de la clase, o sea, a primera vista, no haría uso de ellos ya que el
método siempre pasará dichos valores.

La tabla en la BD esta con los mismos atributos de la clase (CodImpr,
PathImpr, Description, Manager)

Según lo que he leído, al modelar se deben definir las "caracteristicas" de
cada clase y las acciones que ella realiza, pero si en esas acciones
(métodos), se pasan los valores o "Caracterísitcas" para realizar la
operación. ¿cuál es la idea de tener esas "caracteristicas" definidas en
la clase si no se hacen uso de ellas?,
¿Cuál es la forma correcta de modelar y utilizar las clases?,

Si tienen links o ejemplos les estaría muy agradecido.

Desde ya agradezco sus comentarios.

Saludos.
Cristian.

Preguntas similare

Leer las respuestas

#1 Leonardo Azpurua [mvp vb]
01/08/2006 - 04:51 | Informe spam
"Cristian" escribió en el mensaje
news:%
Estimados,

Estoy en el desarrollo de una aplicación y para ello estoy utilizando una
capa de conexión (App Block), una capa de negocio y la interfaz de
usuario (Aplicación). Debo aclarar que es primera vez que utilizo el
modelado UML.
Durante el modelo de clases (después de analizar mis casos de usos y
modelo de clase de primer nivel) me surgió una duda que me tiene algo
confundido.
Tengo una clase "Impresoras" de la siguiente manera:

Impresora
CodImpr: String
PathImpr: String
Description: String
Manager: String
GetPrinter() : Dataset
AddPrinter(): Void
...
...

Mi confusión pasa cuando quiero agregar una impresora, o sea utilizar el
método AddPrinter(), según yo tengo 2 formas de poder hacerlo.
1.- En la aplicación, al agregar la impresora, setear cada atributo de la
clase con su respectivo valor y al final llamar al método AddPrinter() que
tomará cada valor (entro de la clase) y lo insertará en la BD, o sea en mi
aplicación tendría algo asi

oImpresora.CodImpr = "001"
oImpresora.PathImpr = "\\serverprint\P5XCONTA"
oImpresora.Description = "Sector contable."
oImpresora.Manager = "Juan Gómez."
oImpresora.AddPrinter

2.- En la aplicación, al agregar la impresora, pasar cada atributo como
parte de la función AddPrinter(), o sea en mi aplicación tendría algo
así..
...
oImpresora.AddPrinter("001", "\\serverprint\P5XCONTA", "Sector Contable",
"Juan Gomez")

(Acá obviamente el método de mi clase debe tener definido cada atributo:
AddPrinter(CodImpr as string, etc..))
Utilizando esa forma, no me hace mucho sentido tener los atributos
definidos dentro de la clase, o sea, a primera vista, no haría uso de
ellos ya que el método siempre pasará dichos valores.

La tabla en la BD esta con los mismos atributos de la clase (CodImpr,
PathImpr, Description, Manager)

Según lo que he leído, al modelar se deben definir las "caracteristicas"
de cada clase y las acciones que ella realiza, pero si en esas acciones
(métodos), se pasan los valores o "Caracterísitcas" para realizar la
operación. ¿cuál es la idea de tener esas "caracteristicas" definidas
en la clase si no se hacen uso de ellas?,
¿Cuál es la forma correcta de modelar y utilizar las clases?,

Si tienen links o ejemplos les estaría muy agradecido.

Desde ya agradezco sus comentarios.



Hola, Cristian:

La vara para medir la corrección de un diseño es el sentido común.

Las clases pueden tener o no tener atributos, y esos atributos pueden ser o
no ser visibles para los "clientes" de esa clase.

La norma general es la economía: si una clase debe tener un determinado
atributo, no te queda mas remedio que agregarlo.

Una extensión del principio de la economía material es la economía de las
interfaces: un atributo no debería ser visible a menos que esa visibilidad
sea necesaria para los clientes de la clase. Y si es visible, los accesos
permitidos deberían ser estrictamente los necesarios: si no es necesario
modificarlo desde afuera, debe ser de solo lectura. Igualmente, si sólo va a
asignarsele un valor destinado a ser "consumido" internamente, entonces
debería ser de solo escritura.

Al menos eso es lo que dice la teoría, y ese tipo de diseño tiene una gran
belleza formal: en lo personal muestro todo lo que no resulta incompresnible
desde fuera, y permito accesos lo mas amplios posibles, a menos que haya una
buena razón para lo contrario: mi objetivo es producir sistemas tan
extensibles y flexibles como sea posible. Pero eso es otra cuestión.

Ahora, volviendo a tu tema: VB permite la implementación de métodos
sobrecargados, por ejemplo:

Dim oImpresora As tuClaseImpresora = New tuClaseImpresora
With oImpresora
.CodImpr = "001"
.PathImpr = "\\serverprint\P5XCONTA"
.Description = "Sector contable."
.Manager = "Juan Gómez."
.AddPrinter
End With

(semánticamente, AddPrinter pareciera mas un metodo de una clase que
presente una colección de impresoras que de una impresora individual: por lo
general es mala idea responsabilizar a una clase de mantener las propiedades
y ofrecer los servicios de un objeto, a la vez que de mantener las
diferentes instancias de esa clase que existan: hay una especie de
anidamiento infinito que en el mejor de los casos rsulta confuso, y
catastrófico en el peor: tal vez oImpresora.Guardar(...), y esconder detrás
de este metodo la complejidad de la administración, delegada a una clase
especializada en esta actividad)

Pero lo mismo puedes escribir:

oImpresora.AddPrinter("001", "\\serverprint\P5XCONTA", "Sector
contable.", "Juan Gomez")

El tener propiedades te puede permitir, por ejemplo, cambiar la descripcion
de una impresora sin tener que eliminarla y crear una nueva:

oImpresora.Description = "Marketing"

conservando iguales el resto de las propiedades (claro que esto puede tener
o no tener logica en función de tu diseño, del cual solo veo una parte
minima).

Es decir, la diferencia entre un buen diseño y un mal diseño no reside en el
apego a determinadas reglas, sino en la adecuación de cada clase a los fines
para los que fue concebida.

Otro punto de vista es el metodológico: en su columna "Joel on Software",
Joel Spolsky publicó un artículo titulado "Disparar y Avanzar", cuya lectura
te recomiendo: si te pones a juzgar la calidad formal de tus diseños, nunca
estarás satisfecho, y nunca avanzarás. Lo mejor es diseñar
"superficialmente" cada clase e inmediatamente implementarla y ponerla en
uso. El 99% de los cambios a una clase surge durante sus primeros usos. El
proceso de desarrollo de software hace mucho tiempo que dejó de ser aquello
de definir hasta el último detalle para luego construir "según el plano" de
manera casi automática. La definición de los detalles se realiza mediante
código, y las pruebas se hacen con componentes reales. Si despues de
construir una clase descubres que le sobra o que le falta algo, se lo quitas
o se lo agregas: mientras respetes las interfaces definidas, podras hacer
con tu clase todo lo que quieras.

De modo que no te preocupes por "lo correcto": si tu clase debe proveer
algun elemento de información, agregale una propiedad.

Y ya en concreto: es mejor un metodo que tome cuatro argumentos de tipos
definidos (el compilador podrá determinar si la llamada es o no correcta,
previniendo los errores) que tener que asegurarte de haber asignado valores
correctos a cuatro propiedades para luego llamar a un metodo sin parámetros.
Es mas economico en terminos de escritura tambien (como puedes ver al
comparar cinco lineas contra una); mas aun cuando en la llamada con
parametros tienes la ayuda de Intellisense mientras que de lo contrario
tienes que hacerlo todo "a pelo".


Salud!
Respuesta Responder a este mensaje
#2 Cristian
01/08/2006 - 18:29 | Informe spam
Leonardo,

Muy agradecido por tu respuesta, seguro me será de mucha ayuda. Leeré el
artículo que me indicas.

Si tienes links sobre el tema interesantes, por favor reenvíamelos.

En cuanto a tu respuesta, comentas que en principio sería mas recomendable
un método que tome 4 argumentos, por un tema de validación de los argumentos.
Si utilizo propiedades, podría utilizar la propiedad Getter para, dentro de
la clase, validar que la información sea la correcta. ¿Esto es asi?, segun
entiendo, estas propiedades de los atributos (getter y setter) sirven
precisamente para (ademas de dar u obtener valor) para validar el valor
asignado.

Desde ya agradezco mucho tu ayuda.

Saludos.
Cristian.

"Leonardo Azpurua [mvp vb]" escribió:


"Cristian" escribió en el mensaje
news:%
> Estimados,
>
> Estoy en el desarrollo de una aplicación y para ello estoy utilizando una
> capa de conexión (App Block), una capa de negocio y la interfaz de
> usuario (Aplicación). Debo aclarar que es primera vez que utilizo el
> modelado UML.
> Durante el modelo de clases (después de analizar mis casos de usos y
> modelo de clase de primer nivel) me surgió una duda que me tiene algo
> confundido.
> Tengo una clase "Impresoras" de la siguiente manera:
>
> Impresora
> CodImpr: String
> PathImpr: String
> Description: String
> Manager: String
> GetPrinter() : Dataset
> AddPrinter(): Void
> ...
> ...
>
> Mi confusión pasa cuando quiero agregar una impresora, o sea utilizar el
> método AddPrinter(), según yo tengo 2 formas de poder hacerlo.
> 1.- En la aplicación, al agregar la impresora, setear cada atributo de la
> clase con su respectivo valor y al final llamar al método AddPrinter() que
> tomará cada valor (entro de la clase) y lo insertará en la BD, o sea en mi
> aplicación tendría algo asi
>
> oImpresora.CodImpr = "001"
> oImpresora.PathImpr = "\\serverprint\P5XCONTA"
> oImpresora.Description = "Sector contable."
> oImpresora.Manager = "Juan Gómez."
> oImpresora.AddPrinter
>
> 2.- En la aplicación, al agregar la impresora, pasar cada atributo como
> parte de la función AddPrinter(), o sea en mi aplicación tendría algo
> así..
> ...
> oImpresora.AddPrinter("001", "\\serverprint\P5XCONTA", "Sector Contable",
> "Juan Gomez")
>
> (Acá obviamente el método de mi clase debe tener definido cada atributo:
> AddPrinter(CodImpr as string, etc..))
> Utilizando esa forma, no me hace mucho sentido tener los atributos
> definidos dentro de la clase, o sea, a primera vista, no haría uso de
> ellos ya que el método siempre pasará dichos valores.
>
> La tabla en la BD esta con los mismos atributos de la clase (CodImpr,
> PathImpr, Description, Manager)
>
> Según lo que he leído, al modelar se deben definir las "caracteristicas"
> de cada clase y las acciones que ella realiza, pero si en esas acciones
> (métodos), se pasan los valores o "Caracterísitcas" para realizar la
> operación. ¿cuál es la idea de tener esas "caracteristicas" definidas
> en la clase si no se hacen uso de ellas?,
> ¿Cuál es la forma correcta de modelar y utilizar las clases?,
>
> Si tienen links o ejemplos les estaría muy agradecido.
>
> Desde ya agradezco sus comentarios.

Hola, Cristian:

La vara para medir la corrección de un diseño es el sentido común.

Las clases pueden tener o no tener atributos, y esos atributos pueden ser o
no ser visibles para los "clientes" de esa clase.

La norma general es la economía: si una clase debe tener un determinado
atributo, no te queda mas remedio que agregarlo.

Una extensión del principio de la economía material es la economía de las
interfaces: un atributo no debería ser visible a menos que esa visibilidad
sea necesaria para los clientes de la clase. Y si es visible, los accesos
permitidos deberían ser estrictamente los necesarios: si no es necesario
modificarlo desde afuera, debe ser de solo lectura. Igualmente, si sólo va a
asignarsele un valor destinado a ser "consumido" internamente, entonces
debería ser de solo escritura.

Al menos eso es lo que dice la teoría, y ese tipo de diseño tiene una gran
belleza formal: en lo personal muestro todo lo que no resulta incompresnible
desde fuera, y permito accesos lo mas amplios posibles, a menos que haya una
buena razón para lo contrario: mi objetivo es producir sistemas tan
extensibles y flexibles como sea posible. Pero eso es otra cuestión.

Ahora, volviendo a tu tema: VB permite la implementación de métodos
sobrecargados, por ejemplo:

Dim oImpresora As tuClaseImpresora = New tuClaseImpresora
With oImpresora
.CodImpr = "001"
.PathImpr = "\\serverprint\P5XCONTA"
.Description = "Sector contable."
.Manager = "Juan Gómez."
.AddPrinter
End With

(semánticamente, AddPrinter pareciera mas un metodo de una clase que
presente una colección de impresoras que de una impresora individual: por lo
general es mala idea responsabilizar a una clase de mantener las propiedades
y ofrecer los servicios de un objeto, a la vez que de mantener las
diferentes instancias de esa clase que existan: hay una especie de
anidamiento infinito que en el mejor de los casos rsulta confuso, y
catastrófico en el peor: tal vez oImpresora.Guardar(...), y esconder detrás
de este metodo la complejidad de la administración, delegada a una clase
especializada en esta actividad)

Pero lo mismo puedes escribir:

oImpresora.AddPrinter("001", "\\serverprint\P5XCONTA", "Sector
contable.", "Juan Gomez")

El tener propiedades te puede permitir, por ejemplo, cambiar la descripcion
de una impresora sin tener que eliminarla y crear una nueva:

oImpresora.Description = "Marketing"

conservando iguales el resto de las propiedades (claro que esto puede tener
o no tener logica en función de tu diseño, del cual solo veo una parte
minima).

Es decir, la diferencia entre un buen diseño y un mal diseño no reside en el
apego a determinadas reglas, sino en la adecuación de cada clase a los fines
para los que fue concebida.

Otro punto de vista es el metodológico: en su columna "Joel on Software",
Joel Spolsky publicó un artículo titulado "Disparar y Avanzar", cuya lectura
te recomiendo: si te pones a juzgar la calidad formal de tus diseños, nunca
estarás satisfecho, y nunca avanzarás. Lo mejor es diseñar
"superficialmente" cada clase e inmediatamente implementarla y ponerla en
uso. El 99% de los cambios a una clase surge durante sus primeros usos. El
proceso de desarrollo de software hace mucho tiempo que dejó de ser aquello
de definir hasta el último detalle para luego construir "según el plano" de
manera casi automática. La definición de los detalles se realiza mediante
código, y las pruebas se hacen con componentes reales. Si despues de
construir una clase descubres que le sobra o que le falta algo, se lo quitas
o se lo agregas: mientras respetes las interfaces definidas, podras hacer
con tu clase todo lo que quieras.

De modo que no te preocupes por "lo correcto": si tu clase debe proveer
algun elemento de información, agregale una propiedad.

Y ya en concreto: es mejor un metodo que tome cuatro argumentos de tipos
definidos (el compilador podrá determinar si la llamada es o no correcta,
previniendo los errores) que tener que asegurarte de haber asignado valores
correctos a cuatro propiedades para luego llamar a un metodo sin parámetros.
Es mas economico en terminos de escritura tambien (como puedes ver al
comparar cinco lineas contra una); mas aun cuando en la llamada con
parametros tienes la ayuda de Intellisense mientras que de lo contrario
tienes que hacerlo todo "a pelo".


Salud!



Respuesta Responder a este mensaje
#3 Leonardo Azpurua [mvp vb]
02/08/2006 - 05:32 | Informe spam
"Cristian" escribió en el mensaje
news:
Leonardo,

Muy agradecido por tu respuesta, seguro me será de mucha ayuda. Leeré el
artículo que me indicas.

Si tienes links sobre el tema interesantes, por favor reenvíamelos.



Hola, Cristian:

En realidad, para lo poco que he podido aprender de verdad sobre el tema, es
bien poca la información útil que he encontrado en la red. Hay obras
fundamentales que es necesario leerse y estudiarse a fondo: Analisis y
Diseño Orientado a Objetos, de Grady Booch, es una de ellas. Booch ha sido
una de las personalidades más influyentes en el desarrollo de las
metodologías OO. Despues de veinte años programando "al viejo estilo", me
costó un mundo cambiar mi manera de pensar. Ese libro de Booch me ayudó a
entender, despues de mucho tiempo tratando de abrirme camino, de qué va y
como funciona todo el asunto de la OO.

UML no es más que una herramienta: un lenguaje que incluye símbolos para las
categorías conceptuales de la OO. No es un método ni una guía para el
diseño, sino un auxiliar para darle forma a las ideas. Una excelente
explicación con mucho sentido practico es el libro de Martin Fowler "UML
Gota a gota" (en ingles UML Distilled).

Robert C. Martin publicó un libro llamado "Agile Software Development", en
el que expone una serie de principios generales del buen diseño OO,
excelente.

Por ultimo un libro que no es gran cosa, pero que me ayudó a entender mejor
fue "UML y Patrones" de Craig Larman.

En cuanto a tu respuesta, comentas que en principio sería mas recomendable
un método que tome 4 argumentos, por un tema de validación de los
argumentos.
Si utilizo propiedades, podría utilizar la propiedad Getter para, dentro
de
la clase, validar que la información sea la correcta. ¿Esto es asi?, segun
entiendo, estas propiedades de los atributos (getter y setter) sirven
precisamente para (ademas de dar u obtener valor) para validar el valor
asignado.



Es cierto que mediante un "setter" (bonitos perros, como unos cocker grandes
y pelirrojos) puedes validar la congruencia del valor que se intenta asignar
a una propiedad. Pero no era esa la validación de la que hablaba: si para
poder realizar una acción sobre un objeto necesitas que un conjunto dado de
sus propiedades tengan valores definidos, de nada te sirve tener validadores
en cada asignación, cuando no estas validando que la precondición del método
se cumpla (que cada una de las ropiedades del conjunto haya sido objeto de
una asignación válida); si no le has asignado un valor a una de las
propiedades, no has podido determinar si es o no correcta, porque el codigo
de validación no ha sido ejecutado.

De manera que implementar el metodo como una función que reciba los
argumentos requeridos del exterior, garantizará que todas las activaciones
sean correctas. No es que no pueda hacerse de otra manera: de todas maneras,
es irresponsable iniciar la ejecución de un método sin verificar que todas
sus precondiciones han sido satisfechas. Simplemente es mas seguro si se
piden los argumentos en la firma de la subrutina o función: .NET y el IDE se
asegurarán de que las condiciones sean cumplidas, y ni el mas distraido de
los programadores podrá olvidar que tiene que pasar los argumentos
requeridos. Y siempre tienes la posibilidad de sobrecargar el metodo: una
implementacion sin argumentos, que tome los valores de los atributos del
objeto, y una implementación con los argumentos completos. Asi, si alguien
mete la pata, siempre tendrás la excusa de poder decir que si no sabia como
llamarlo, pudo haber usado la versión completa :-)

Grady Booch tiene un "Manual de Arquitectura de Software" (detesto la
expresión) en http://www.booch.com. Martin Fowler tiene un blog con
articulos más o menos interesantes (es decir, unos más y otros menos) en
http://www.martinfowler.com. Desde hace un tiempo, Microsoft viene tratando
de adoptar el metodo "Agile" en sus procesos de desarrollo, y tiene un grupo
de tarea dedicado a la identificación y codificación de Patrones y
Practicas. Su trabajo -que comenzó siendo interesante pero que cada vez
tiene mas de evangelización y menos de novedoso- puede ser consultado aquí:
http://msdn.microsoft.com/practices. Igual si te enrollas bien con las
paginas podrías encontrar algo verdaderamente esclarecedor.


Salud!
email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaRespuesta Tengo una respuesta
Search Busqueda sugerida