2 abr 2013

Solución 12 - Patrón de diseño Builder


El patrón de diseño Builder te permite encapsular la funcionalidad y propiedades comunes entre diferentes objetos en un proceso de creación común.  Con ello, se obtiene mantenibilidad de los objetos resultantes, creando los contratos de clase para que su uso sea lo más robusto posible.


Definición de wikipedia: Como Patrón de diseño, el patrón builder (Constructor) es usado para permitir la creación de una variedad de objetos complejos desde un objeto fuente (Producto), el objeto fuente se compone de una variedad de partes que contribuyen individualmente a la creación de cada objeto complejo a través de un conjunto de llamadas a interfaces comunes de la clase Abstract Builder.


El patrón Builder se compone de 4 clases:
Director : Encargado de realizar el proceso de creación del objeto paso a paso.
AbstractBuilder (Builder) :  Contrato donde se especifica qué pasos son los del proceso de creación. De forma generalizada.
ConcreteBuilder : Implementa los pasos de forma individual.
Product : Objeto final a elaborar.




Ejemplo:
El ejemplo es un Builder de pizzas. El añadir nuevas pizzas consistirá en crear un nueva Pizza (Product) y un nuevo PizzaBuilder (ConcreteBuilder). Esta nueva Pizza heredará la plantilla del proceso de creación común a todas las pizzas.


/** "Abstract Builder" */
abstract
class PizzaBuilder {
   
protected Pizza pizza;

   
public Pizza getPizza() { return pizza; }
   
public void crearNuevaPizza() { pizza = new Pizza(); }

   
public abstract void buildMasa();
   
public abstract void buildSalsa();
   
public abstract void buildRelleno();
}
La clase AbstractBuilder tiene el contrato que cumplirá al ConcreteBuilder.
/** "ConcreteBuilder" */
class HawaiPizzaBuilder extends PizzaBuilder {
   
public void buildMasa()   { pizza.setMasa("suave"); }
   
public void buildSalsa()   { pizza.setSalsa("dulce"); }
   
public void buildRelleno() { pizza.setRelleno("chorizo+alcachofas"); }
}
/** "ConcreteBuilder" */
class PicantePizzaBuilder extends PizzaBuilder {
   
public void buildMasa()   { pizza.setMasa("cocida"); }
   
public void buildSalsa()   { pizza.setSalsa("picante"); }
   
public void buildRelleno() { pizza.setRelleno("pimienta+salchichón"); }
}

/** "Director" */
class Cocina {
   
private PizzaBuilder pizzaBuilder;

   
public void setPizzaBuilder(PizzaBuilder pb) { pizzaBuilder = pb; }
   
public Pizza getPizza() { return pizzaBuilder.getPizza(); }

   
public void construirPizza() {
      pizzaBuilder
.crearNuevaPizza();
      pizzaBuilder
.buildMasa();
      pizzaBuilder
.buildSalsa();
      pizzaBuilder
.buildRelleno();
   
}
}

El proceso de elaboración se puede ver en el AbstractBuilder y se define de manera individual en los ConcreteBuilder. El Director solo pone en marcha el proceso paso a paso.

/** Un cliente pidiendo una pizza. */
class BuilderExample {
   
public static void main(String[] args) {
       Cocina cocina
= new Cocina();
       PizzaBuilder hawai_pizzabuilder
= new HawaiPizzaBuilder();
       PizzaBuilder picante_pizzabuilder
= new PicantePizzaBuilder();

       cocina
.setPizzaBuilder( hawai_pizzabuilder );
       cocina
.construirPizza();

       Pizza pizza
= cocina.getPizza();
   
}
}


21 mar 2013

Solucion 11 - Patron de diseño Strategy

Lo patrones de diseño son la evolución natural y sofisticada de la programación orientada a objeto (OO), son técnicas para aprovechar al máximo el potencial de la OO. Soluciones optimas que en caso de usarlas de forma adecuada darán un valor añadido a nuestros algoritmos  facilitando en el futuro las tareas mantenimiento y extensión de la misma.

Empezaremos con el patrón de diseño Strategy.

Definición Wikipedia: El patrón Estrategia (Strategy) es un patrón de diseño para el desarrollo de software. Se clasifica como patrón de comportamiento porque determina como se debe realizar el intercambio de mensajes entre diferentes objetos para resolver una tarea. El patrón estrategia permite mantener un conjunto de algoritmos de entre los cuales el objeto cliente puede elegir aquel que le conviene e intercambiarlo dinámicamente según sus necesidades. 

Dada una clase llamada Strategy tenemos dos clases hijas que tienen un método strategicMethod() cada una con diferentes implementaciones, caso claro de Polimorfismo. Después desde la clase Context podremos escoger en setStrategy() que clase hija y implementacion nos interesa más. Al instanciar en Context la clase hija que queramos, la ConcreteStrategy escogida, dispondremos de sus funcionalidades. También cabe destacar la posibilidad de cambiar cuando queramos de estrategia instanciando en Context otra ConcreteSrategy.


Ejemplo:
public class CreadorDibujos {
    private EstrategiaDibujo _estrategia;
    private float[] _x,_y;
 
    public CreadorDibujos() {
        // Establecer estrategia por defecto.
    }
 
    public void establecerDibujoBarras() {
        _estrategia = new EstrategiaDibujoConcreta1();
    }
 
    public void establecerDibujoLineas() {
        _estrategia = new EstrategiaDibujoConcreta2();
    }
 
    ..............
 
    public void dibuja() {
        _estrategia.dibujar(_x,_y);
    }
}
La clase Context seria CreadorDibujos, y dependiendo si escogemos Barras o Lineas, la implementación del método dibuja() cambiará. Se podría por ejemplo añadir nuevas estrategias como Círculos  Cuadrados, Rombos, etc. y de manera rápida y eficiente con pocos cambios en el sistema creado realizar cambios consistentes.
public abstract class EstrategiaDibujo extends JFrame {
    private float[] _x,_y;
    private Color _c;
    private int _ancho,_alto;
 
    public EstrategiaDibujo() {
    }
 
    public abstract void dibujar(float[] px, float[] py);
}

public class EstrategiaDibujoConcreta1 extends EstrategiaDibujo{
        //...
        public void dibujar(float[] px, float[] py){ ... }
        //...
}

public class EstrategiaDibujoConcreta2 extends EstrategiaDibujo{
        //...
        public void dibujar(float[] px, float[] py){ ... }
        //...
}

7 nov 2012

Solución 10 - Principios SOLID

Los principios SOLID son, tal y como lo entiendo yo, una serie de reglas que si se cumplen, el diseño de una aplicación queda blindada, siendo mínimos los costes de crear nuevas funcionalidades y se asegura que el mantenimiento sea mínimo. 
Se trata de dedicar cierto tiempo extra en crear cimientos "sólidos" en el diseño, para facilitar el mantenimiento y/o evolución a posterior de la aplicación. 

Definición Wikipedia: http://es.wikipedia.org/wiki/SOLID_(object-oriented_design)


Significaco de las SIGLAS:

  • S: Single Responsibility Principle (SRP) - Principio de Responsabilidad Única
  • O: Open-Closed Principle (OCP) – Principio de Abierto-Cerrado
  • L: Liskov Substitution Principle (LSP) – Principio de Substitución de Liskov
  • I: Interface Segregation Principle (ISP) – Principio de Segregación de Interface
  • D: Dependency Inversion Principle (DIP) – Principio de Inversión de Dependencia
Resumen:
El Principio de Responsabilidad Única (SRP) nos dice que una clase sólo debe tener una única razón para cambiar. Este principio nos ayuda a dirigir la cohesión y controlar el acoplamiento.
El Principio de Abierto-Cerrado (OCP) nos indica cómo diseñar clases de manera que estas se puedan extender sin tener que modificar su funcionalidad principal. Aplicando este principio conseguimos sistemas bien encapsulados y altamente cohesivos.
El Principio de Substitución de Liskov (LSP) se centra en los conceptos de encapsulación y cohesión. Y dice que una clase que implemente una interfaz o herede de una clase base no debe violar la intención o la semántica de la abstracción heredada.
El Principio de Segregación de la Interfaz (ISP) nos habla de como las clases no deben exponer interfaces que las aplicaciones que las usan no necesitan. Aplicando este principio se obtiene una mejora en la encapsulación y cohesión de sistemas.
El Principio de Inversión de Dependencias (DIP) está enfocado en hacernos entender de como los detalles de implementación debe depender de la funcionalidad de alto nivel que requiere el sistema y no al revés. Y de como conseguir invertir esta relación de manera satisfactoria.

Fuente principal:
Otras fuentes: 

18 oct 2012

Solución 9 - Buscar tabla de una columna en SQL Server

¿Cuantas veces sabías el nombre de la columna pero no en que tabla estaba?
Si el numero de tablas es pequeño la tarea de búsqueda no es difícil.
Pero si el número de tablas es de un tamaño importante como 1000 tablas?
Vaya locura no?

Esta solución encuentra la tabla a partir del nombre de la columna en una BBDD SQL Server.

SELECT name FROM sysobjects WHERE id IN SELECT id FROM syscolumns WHEREname 'THE_COLUMN_NAME' )

Fuente: http://www.dzone.com/snippets/find-table-column-sql-server


24 sept 2011

Solución 8 - Excel 2007 API en Windows Server 2008 x64

Una vez creada y publicada la aplicación que usa la API Excel 2007 en Windows Server 2008 x64, puede lanzaros este error al intentar abrir un xlsx con la función Open() de la API :

Microsoft Office Excel cannot access the file 'c:\temp\test.xls'. There are several possible reasons:
• The file name or path does not exist.
• The file is being used by another program.
• The workbook you are trying to save has the same name as a currently open workbook.


Por mágica que parezca la solución, está reside en crear una nueva carpeta llamada Desktop en C:\Windows\SysWOW64\config\systemprofile\, quedando de esta manera: 

C:\Windows\SysWOW64\config\systemprofile\Desktop

Hay que dar permisos "Control Total" a esta carpeta de la aplicación del IIS (AppPool) de la aplicación web que usa la API Excel 2007. Debe utilizar internamente esta carpeta de forma temporal para realizar la lectura del xlsx.

Aquí tenéis parte de dónde encontré la solución, que nos dice que la creación de la carpeta varia dependiendo la versión del servidor:

...

This solution is ...
・Windows 2008 Server x64

  Please make this folder.

  C:\Windows\SysWOW64\config\systemprofile\Desktop
・Windows 2008 Server x86
  Please make this folder.
  C:\Windows\System32\config\systemprofile\Desktop
  ...instead of dcomcnfg.exe.

...