Mostrando las entradas con la etiqueta diseño. Mostrar todas las entradas
Mostrando las entradas con la etiqueta diseño. Mostrar todas las entradas

sábado, 21 de febrero de 2015

Algoritmos y Programación - Python [0]

Problemas no computables [1]
Son aquellos problemas que nunca podrán ser resueltos por una computadora por más poderosa que sea.

Problemas intratables [2]
Son aquellos problemas que pueden ser resueltos pero que requieren de un enorme poder de computo y memoria.

Algoritmo
es cualquier metodo para obtener un resultado. [3]

Construcción de Programas

1. Analizar el problema
    Entender profundamente cual es el problema y dejarlo por escrito.

2. Especificar la solución
    Describir qué debe hacer el programa, especificar datos de entrada, de salida y la relación entre ellos.

3. Diseñar la solución
    Cómo vamos a resolver el problema, cuales son los algortimos y las estructuras de datos que usaremos.

4. Implementar el diseño
    Traducir en un lenguaje de programación el diseño.

5. Probar el programa.
    Diseñar un conjunto de pruebas para probar cada una de sus partes.

6. Mantener el programa
    Realizar los cambios en respuesta a nuevas demandas.

Todos estos pasos deben ser documentados.

[4] Guia para diseño

  • ¿Han visto este problema antes, aunque sea de manera ligeramente diferente?
  • ¿Conocen un problema relacionado? ¿Conocen un programa que puede ser útil?
  • Fijense en la especificación. Traten de encontrar un problema que les resulte familiar y que tenga la misma especificación o una parecido.
  • Acá hay un problema relacionado con el que ustedes tienen y que ya fue resuelto. ¿Lo pueden usar? ¿Puede usar sus resultados? ¿Pueden usar sus métodos? ¿Pueden agregarle alguna parte auxiliar a ese programa del que ya disponen?
  • Si no pueden resolver el propuesto, traten de resolver uno relacionado. ¿Pueden imaginarse uno relacionado que sea más fácil de resolver? ¿Uno más general? ¿Uno más especifico? ¿Un problema analogo?
  • ¿Pueden resolver una parte del problema? ¿Pueden sacar algo útil de los datos de entrada? ¿Pueden pensar que információn es útil para calcular las salidas? ¿De qué manera se pueden manipular las entradas y las salidas de modo tal que estén "más cerca" unas de las otras?
  • ¿Usaron todos los datos de entrada? ¿Usaron las condiciones especiales sobre los datos de entrada que aparecen en el enunciado? ¿Han tenido en cuenta todos los requisitos que se enuncian en la especificación?
Las funciones

Una función es un conjunto de instrucciones que llevan a cabo la solución de una parte particular del problema. Las funciones llevan ninguno, uno o más argumentos que son la parte variable que se debe definir en cada ejecución de la función. Es recomentable documentar las funciones ya que con el crecimiento del programa crece su complejidad y tener las funciones documentadas ayudar a la mantenibilidad.

Las variables y parametros que se declaran dentro de una función no existen fuera de ella. Por consiguiente en lenguajes como python de utiliza "return" para decirle a una función que el valor debe ser retornado al hilo principal para que el programa pueda utilzar esa salida para hacer otras tareas.

[0] Algoritmos y Programación - Python
[1][2][3] Algoritmos y Programación - Python  Pagina 9
[4] Algoritmos y Programación - Python  Pagina 28
[5] http://www.cs.kent.ac.uk/people/staff/sjt/Haskell_craft/HowToProgIt.html
[6] Algoritmos y Programación - Python  Pagina 30

lunes, 17 de marzo de 2014

Patrones de Diseño - Factory Method y Prototype

Factory Method

Proposito,

      Define una interfaz para crear un objeto, pero permite a las subclases decidir que clases instancia. Factory Method permite a una clase derivar la instanciación a las subclases.

Motivo

    Los Frameworks usan clases abstractas para definir y mantener relaciones entre objetos. Un framework es normalmente responsable por crear estos objetos.
Considerar un framework para aplicaciones que pueda presentar multiples documentos a el usuario. Dos abstracciones claves en este framework son las clases Aplicacion y Documento. Ambas clases son abstractas, y los clientes tienen las subclases de ellas para realizar la implementación especifica de la aplicación. Para crear una aplicación de dibujo, por ejemplo, nosotros definimos las clases DrawingApplication y DrawingDocument. la clase Application es responsable para manejar Documents y los creará como sea requerido - cuando el usuario selección Abrir o nuevo desde un menu, por ejemplo.

El patrón Factory Method ofrece una solución. Este encapsula el conocimiento de que subclase Document crear y mueve este conocimiento por fuera del Framework.

Aplicabilidad

     Usa el patrón Factory Method cuando,

  • Una clase no puede anticipar la clase del objeto que debe crear.
  • Una clase quiere que sus subclases especifiquen el objeto a crear.
  • Las clases delegan la responsabilidad a una o muchas subclases auxiliares, y tu deseas localizar el conocimiento de que subclase auxiliar es la delegada.
Participantes,
  • Product, define la interfaz de objetos que el Factory Method crea.
  • ConcreteProduct, implementa la interfaz de Product.
  • Creator, declara el Factory Method, que retorna un objeto de tipo Product. El creador también puede definir una implementación predeterminada de el Factory method que retorne un objeto ConcreteProduct predeterminado. Puede llamar al Factory Method para crear un objeto Product.
  • ConcreteCreator, sobreescribe el Factory Method para return una instancia de un ConcreteProduct.

Ejemplos de Factory Method en Python.
Estos son dos ejemplos más que interesantes. [0][1]

Prototype

Intento,
       Especificar los tipos de objetos a crear usando una instancia como prototipo. y crear nuevos objeto copiando este.

Motivación,

       Podrías construir un editor para partituras personalizando un framework general para editores gráficos, y agregando nuevos objetos que representen notas, silencios, y pentagramas. El Framework editor podría tener una paleta de herramientas para agregar estos objetos de música a la partitura. La paleta debería también incluir herramientas para seleccionar, mover y otro tipo de manipulación de objetos musicales. 

El framework provee un clase Graphics abstracta para los componentes gráficos, como son las notas y pentagramas. Provee una clase Tools para definir herramientas como esas en la paleta. El Framework también predefine un subclase Graphic-Tool para herramientas que crean instancias de objetos gráficos y agrega estos al documento.

Pero GraphicTool presenta un problema al diseñador del framework. Las clases para notas y pentagramas son especificas de nuestra aplicación, pero la clase GraphicTool pertence al framwork. GraphicTool no sabe como crear instancias de nuestras clases de musica para agregarlas a la partitura. Nosotros podríamos definir subclases de GraphicTool para cada tipo de objeto de música que instancia. Nosotros sabemos que la composición de objetos es una alternativa flexible al subclaseo. La pregunta es, como puede el framework usarlo para parametrizar instancias de GraphicTool por la clase de Graphic que se supone crear?.


La solución está en hacer que GraphicTool cree un nuevo Graphic copiando o "clonando" una instancia de una subclase de Graphic. Nosotros llamamos a esta instancia un prototipo. GraphicTool es parametrizado por el prototipo que debería clonar y agregar a el documento. Si toda Subclase de Graphic soporta una operación Clone, entonces la GraphicTool puede clonar cualquier tipo de Graphic.

Aplicabilidad,

     Usa el patrón Prototype cuando un sistema deberia ser independiente de como sus productos son creados, compestos y representados; and

  • Cuando las clases a instancia son especificadas en tiempo de  ejecución, por ejemplo, por carga dinámica, o
  • para evitar la construcción de una jerarquia de clases de Factories que sean paralelas a la jerarquia de clases de productos, o
  • cuando las instancias de una clase puedan tener una de solo unas pocas combinaciones diferentes de estado. Esta deberia ser más conveniente para instalar un número correspondiente de prototupos y clonarlos en lugar de instanciar la clase manualmente, cada vez con el estado apropiado.
Participantes
  • Prototype, declara una interfaz para clonarse a si mismo.
  • ConcretePrototype, implementa una operación para clonarse a si mismo.
  • Cliente, crea un nuevo objeto pidiendole a un prototipo que se clone a si mismo.
Ejemplos del Patron Prototype en Python que tiene hasta formas PreConstruidas para este fin.
[2] [3]

domingo, 9 de marzo de 2014

Patrones de Diseño - Builder

Builder

Objetivo, Separa la construcción de un objeto complejo de su representación de modo que el mismo proceso de construcción puede crear diferentes representaciones.

Motivo:

Un lector para el formato de intercambio de documentos RTF (Rich Text Format) debería ser capaz de convertir RTF a muchos formato de texto. El lector puede convertir documentos RTF en texto plano ASCII o en un Widget de texto que pueden ser editados interactivamente. El problema, sin embargo, es que el número de conversiones posible es abierto. Por lo tanto, debe ser fácil de añadir una nueva conversión sin modificar el lector.

Aplicabilidad

Usar el patrón Builder cuando:

  • El algoritmo para crear un objeto complejo deber ser independiente de las partes que conforman el objeto y como están ensambladas.
  • El proceso de construcción debe permitir diferentes representaciones para el objeto que es construido.
Participantes

Builder,
- especifica una interfaz abstracta para crear partes de un objeto Product.
ConcreteBuilder
- construye y ensambla partes del productopara implementar la interfaz Builder.
- define y mantiene un seguimiento de la representación que crea.
- provee una interfaz para obtener el producto
Director
- construye un objeto usando la interfaz del Builder.
Product
- representa el objeto complejo en construcción. El ConcreteBuilder construye la representación interna del producto y define el procesos por el cual este es ensamblado.
- incluye clases que definen las partes constituyentes, inclyendo interfaces para ensamblar las partes en el resultado final.

Ejemplos de Código [0] [1]

La diferencia entre el Builder y el Abstract Factory
La principal diferencia es que el Builder se enfoca en construir un objeto complejo paso a paso. El Abstract Factory hace incapié en la familia de objetos producto (ya sea sencilla o compleja). El Builder retorna el producto como un paso final, pero en cuanto al Abstract Factory el producto es retornado inmediatamente.


[0] http://es.wikipedia.org/wiki/Builder_(patr%C3%B3n_de_dise%C3%B1o)
[1] http://tratandodeentenderlo.blogspot.com.ar/2010/02/patrones-de-diseno-builder.html

sábado, 8 de marzo de 2014

Patrones de Diseño Creacionales - Abstract Factory

Los patrones de diseño creacionales son aquellos que abstraen el proceso de instanciación. Ellos ayudan a hacer un sistema independiente de como sus objetos son creados, compuestos, y representados. Una patrón creacional de clase usa herencia para variar la clase que es instanciada, mientras un patron creacional de objeto delegará la instanciación a otro objeto.

Los patrones creacionales se vuelven importantes en sistemas que pasan a depender más de la composición de objetos que de la herencia de clases. Como eso sucede, el enfasis cambia de modificar dificilmente un conjunto fijo de comportamientos hacia definir un conjunto pequeño de comportamientos fundamentales que pueden ser compuestos dentro de cualquier numero de los más complejos. Creando así objetos con un comportamiento particular que requiere más que simplemente instanciar una clase.

Abstract Factory

Intenta:
proveer una interfaz para la creación de familias objetos relacionados o dependientes sin especificar sus clases concretas.

Aplicación:

  • Un sistema debería ser independiente de como sus productos son creados, compuestos, y representados.
  • Un sistema debería ser configurado con una de múltiples familias de productos.
  • Una familia de objetos producto relacionados es diseñada para ser usados juntos y necestás hacer cumplir esta restricción.
  • Buscás proveer una biblioteca de clases de productos, y buscas revelar solo sus interfaces, no su implementación.
Participantes:
  • Abstract Factory - declara una interfaz para operaciones que crean objetos producto abstractos.
  • ConcreteFactory - implementa las operaciones para crear objetos producto concretos.
  • AbstractProduct - declara una interfaz para un tipo de objeto producto.
  • ConcreteProduct - define un producto objeto para ser creado por el correspondiente Concrete Factory. - implementa la interfaz del AbstractProduct.
  • Client - usa solo las interfaces declaradas por las clases AbstractFactory y AbstractProduct
Ejemplos de Abstract Factory en Python
[0][1][2]

[0] http://python-3-patterns-idioms-test.readthedocs.org/en/latest/Factory.html#abstract-factories
[1] http://ginstrom.com/scribbles/2007/10/08/design-patterns-python-style/
[2] http://jpython.blogspot.com.ar/2012/09/python-design-pattern-abstract-factory.html




sábado, 1 de marzo de 2014

Patrones de Diseño - GoF - Introducción


"Programa una interfaz, no una implementación"

No declares variables para ser instancias especiales de una clase concreta. En su lugar, genera solo una interfaz definida por una clase abstracta.

Herencia Vs Composición

La herencia indica que una clase hereda muchas o todas sus características de una (o más) clase padre.

Cuando en Python hacemos

class Padre(object):
    def saltar(self):
        print 'Estoy saltando'

class Hijo(Padre):
    pass

Estamos diciendo que la clase Hijo hereda de Padre y le escribimos un "pass" para decir que no vamos a definir nada nuevo en esa clase. Entonces lo que sucederá es que el hijo va a heredar todo el comportamiento de su padre en este caso la clase hijo tiene de manera implícita el método "saltar" que hereda de su "Padre"

Hay otros detalles sobre el uso de herencias múltiples en Python que van a poder ver con más detalle en los links de referencia al final del Post [0]

La composición es definida en tiempo de ejecución a través de un objeto que adquiere referencias a otro objeto.Es un objeto que usa la interfaz de otro objeto lo que genera que se tenga que tener especial cuidado en el diseño. Y el objeto referenciado puede ser cambiado siempre que mantenga las mismas interfaces.

Un ejemplo de composición podría ser el siguiente:

Class HabilidadSalto(objetc):
    def ejecutar(self):
        print 'Estoy saltando'

Class Persona(object):
    def __init__(self):
        self.habilidadSaltar = HabilidadSalto()

    def saltar(self):
        self.habilidadSaltar.ejecutar()

No estoy seguro de que sea un ejemplo muy adecuado pero es aproximadamente a lo que se refiere básicamente un objeto tiene dentro suyo una referencia a otro objeto y usa la interfaz de este último para llamar a acciones concretas.

"Favorece la composición de objetos por sobre la herencia de clases"

Delegación

La delegación es una manera de hacer composición tan potente para su reutilización como la herencia.
Dos objetos son los involucrados donde uno recibe el pedido y delega la operación a su delegado. Un ejemplo podría ser el siguiente que yo escribí en Python basándome en la explicación del libro [1] Design Patterns de GoF.

class Rectangulo(object):
    def __init__(self, ancho, alto):
        self.ancho = ancho
        self.alto = alto

    def Area(self):
        return self.ancho * self.alto

class Ventana(object)
    def __init__(self, ancho, alto):
        self.rectangulo = Rectangulo(ancho, alto)

    def Area(self):
        self.rectangulo.Area()

Esto tiene ventajas como que la ventana podría cambiar su comportamiento en tiempo de ejecución tan solo reemplazando la referencia a la clase Rectángulo por una referencia a otra clase Circular. Esto suponiendo que Circular y Rectángulo son del mismo tipo.

Las siguientes son causas comunes para el rediseño y como los patrones de diseño ayudan en ellas.

1. La creación de un objeto especificando una clase explicitamente. Especificar una nombre de clase cuando creas un objeto te compromete con una implementación particular, en vez de una particular interfaz.
Patrones de Diseño: Abstract Factory, Factory Method, Prototype.

2. Dependencia de operaciones especificas. Cuando especificas una operación particular, te comprometes a una manera de satisfacer un pedido. Para evitar solicitudes codificadas específicamente, deberías hacer más fácil cambiar la manera en que un pedido es satisfecho ambos en tiempo de compilación y en tiempo de ejecución.
Patrones de Diseño: Chain of Responsibility, Command.

3. Dependencia de la plataforma de Software y Hardware. Las Interfaces externas del sistema operativo y de la interfaces de programación de la aplicación (APIs) son diferentes en diferentes plataformas de  hardware  y software. Es importante por lo tanto que el diseño de tu sistema limite las dependencias de la plataforma.
Patrones de Diseño: Abstract Factory, Bridge

4. Dependencia de representaciones de objetos o implementaciones. Los clientes que conocen como un objeto es representado, almacenado, asignado o implementado. puede ser que necesiten ser cambiados cuando el objeto cambie.  Esconder esta infroma de los clientes mantiene los cambios en cascada.
Patrones de Diseño,: Abstract Factory, Bridge, Memento, Proxy.

5. Dependencias Algorítmicas. Los algoritmos son a menudo extendidos, optimizados, y reemplazados durante el desarrollo y reuso. Los objetos que dependan de un algoritmo tendrán que cambiar cuando el algoritmo cambie.
Patrones de diseño: Builder, Iterator, Strategy, Template, Method, Visitor.

6. Estrecho acoplamiento. Las clases que están estrechamente acopladas son dificiles de reusar en aislación, ya que dependen una de otra. El estrecho acoplamiento lleva a sistema moniliticos, donde no puedes cambiar o eliminar una clase sin entender o cambiar muchas otras clases.
El Acoplamiento débil incrementa la probabilidad de que una clase puede ser reusada por si misma y que un sistema pueda ser aprendido, portado, modificado, y extendido más fácilmente.
Patrones de Diseño: Abstract Factory, Bridge, Chain of responsibility, Command, Facade, Mediator, Observer.

7. Extender funcionalidad subclasificando. La personalización de un objeto por subclaseo a menudo no es fácil. Cada nueva clase tiene un implementación fijada desde el vamos (inicialización, finalización, etc). Definir una subclase requiere un profundo entendimiento de la clase padre.
La composición en general y la delegación en paticular proveen alternativas flexibles a la herencia por combinación de comportamientos. Nuevas funcionalidades pueden ser agregadas a nuevas subclases por la composición de objetos en nuevas maneras antes que definir nuevas subclases de clases existentes.
Patrons de Diseño: Bridge, Chain of Reponsibility, Composite, Decorator, Observer, Strategy

8 Inhabilidad de alterar clases convenientemente. A veces tiene que modificar una clase que no puede ser modificada convenientemente. Quizás necesitas el código fuente y no lo tienes (como sería el caso de una librería comercial). O tal vez cualquier cambio requerirá la modificación de muchas de las subclases existentes. Los patrones de diseño ofrecen varias maneras de modificar clases en estas circunstancias.
Patrones de Diseño: Adapter, Decorator, Visitor.

En subsiguientes Posts estaré resumiendo o explicando según mi entendimiento otras partes de este libro que comencé a leer y que me interesa bastante.

[0] http://learnpythonthehardway.org/book/ex44.html
[1] http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612