Consultas, desarrollo de programas y petición de presupuestos:

domingo, 14 de septiembre de 2014

Como eliminar los Select Case ( switch ) usando POO y el patrón Strategy.

Como eliminar los Select Case ( switch ) usando POO y el patrón Strategy.

La orden Select Case (o Switch en otros lenguajes de programación), tiene el inconveniente de que cada vez que tengamos que añadir más casos, supone que tengamos que modificar el código ya escrito anteriormente.

Aunque ya lo he comentado en otras entradas (ver referencia), voy a hacer un ejemplo simple para que veais el mecanismo de como se sustituye usando clases y el patrón Strategy:

Vamos a partir de este simple ejemplo:

->
Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. ' Desea calcular una función aleatoria.
  2. ' Repite una función aleatoria mil veces para
  3. ' conocer cuantas veces aparecen los números
  4. ' 1,2,3,4,5 o 6.
  5.  
  6. DIM x AS Integer
  7. DIM w AS Integer
  8. DIM a AS Integer
  9. DIM b AS Integer
  10. DIM c AS Integer
  11. DIM d AS Integer
  12. DIM e AS Integer
  13. DIM f AS Integer
  14.  
  15. FOR x = 1 TO 1000
  16.  
  17.   w = Int(Rnd(6) + 1)
  18.  
  19.   SELECT CASE w
  20.     CASE 1
  21.       a = a + 1
  22.     CASE 2
  23.       b = b + 1
  24.     CASE 3
  25.       c = c + 1
  26.     CASE 4
  27.       d = d + 1
  28.     CASE 5
  29.       e = e + 1
  30.     CASE 6
  31.       f = f + 1
  32.     CASE ELSE
  33.       PRINT "¡Esto es imposible!"
  34.   END SELECT
  35.  
  36. NEXT
  37.  
  38. PRINT a, b, c, d, e, f


El bucle Select  Case lo vamos a sustituir por la siguiente estructura de clases:



Estructura del proyecto:



Código de las Clases:
Clase Switch:
->
Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. ' Gambas class file
  2.  
  3. Private ListaOpciones As New InterfaceOpcion[]
  4.  
  5. Public Sub _new(contadores As Integer[])
  6.   'En el constructor indico que opciones estan disponibles
  7.   ''------------------------------------------
  8.   ''NOTE: Listado de Estrategias disponibles:
  9.   ''------------------------------------------
  10.   ''NOTE: Si hubieran mas opciones se añadirian continuacion
  11.   '--- poner aqui nuevas opciones... Dim XXXXXtmp as new OpcionXXXX
  12.  
  13.   Dim Opcion1tmp As New Opcion1
  14.   Dim Opcion2tmp As New Opcion2
  15.   Dim Opcion3tmp As New Opcion3
  16.   Dim Opcion4tmp As New Opcion4
  17.   Dim Opcion5tmp As New Opcion5
  18.   Dim Opcion6tmp As New Opcion6
  19.  
  20.   Opcion1tmp.numero = contadores
  21.   Opcion2tmp.numero = contadores
  22.   Opcion3tmp.numero = contadores
  23.   Opcion4tmp.numero = contadores
  24.   Opcion5tmp.numero = contadores
  25.   Opcion6tmp.numero = contadores
  26.  
  27.   'añado las opciones  a la lista de opciones
  28.   add(Opcion1tmp)
  29.   add(Opcion2tmp)
  30.   add(Opcion3tmp)  
  31.   add(Opcion4tmp)
  32.   add(Opcion5tmp)
  33.   add(Opcion6tmp)
  34.   'aqui el programador podrá añadir más estrategias
  35.  
  36. End
  37.  
  38. Public Sub add(opcion As InterfaceOpcion)
  39.   'este médoto se puede usar tambien dinamicamente, durante la ejecución del programa..
  40.  
  41.   ListaOpciones.Add(opcion)
  42.  
  43. End
  44.  
  45. Public Sub remove(opcion As InterfaceOpcion)
  46.   'este método permite borrar dinamicamente durante la ejecución del programa, opciones
  47.  
  48.   ListaOpciones.Remove(ListaOpciones.Find(opcion))
  49.  
  50. End
  51.  
  52. Public Sub operar(expresion As String)
  53.  
  54.   Dim opciontmp As New InterfaceOpcion
  55.  
  56.   For Each opciontmp In ListaOpciones
  57.     If opciontmp.comprobar(expresion) Then
  58.       opciontmp.operar(expresion)
  59.       Return  
  60.     Endif
  61.   Next
  62.   'no se ha encontrado ninguna opcion para la expresión
  63.   'se ejecuta la opcion por defecto
  64.   opcionDefecto(expresion)
  65.  
  66. End
  67.  
  68. Public Sub opcionDefecto(expresion As String)
  69.  
  70.   Print "Error:  " & expresion & " no reconocido "
  71.  
  72. End


Fijaos en la opcion "add" y "remove" que nos van a permitir añadir o quitar opciones.

Clase Interface:
->
Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. ' Gambas class file
  2.  
  3. Public Sub comprobar(expresion As String) As Boolean
  4.  
  5. End
  6.  
  7.  
  8. Public Sub operar(Optional valor As String)
  9.  
  10. End


Clase Opcion1:
->
Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. ' Gambas class file
  2.  
  3. Inherits InterfaceOpcion
  4. Public numero As Integer[] 'lo pongo como array para que se pase por referencia
  5.  
  6. Public Sub comprobar(expresion As String) As Boolean
  7.  
  8.   If expresion = "1" Then
  9.     Return True
  10.   Else
  11.     Return False
  12.   Endif
  13.  
  14. End
  15.  
  16. Public Sub operar(Optional valor As String)
  17.  
  18.   numero[0] += 1
  19.  
  20. End


Las demas opciones, son muy parecidas, vease el codigo fuente completo.

Programa Principal: Mmain
->
Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. ' Gambas module file
  2.  
  3. ' Desea calcular una función aleatoria.
  4. ' Repite una función aleatoria mil veces para
  5. ' conocer cuantas veces aparecen los números
  6. ' 1,2,3,4,5 o 6.
  7.  
  8. 'Se declaran publica para que se puedan acceder desde otros modulos/clases
  9. Public valores As New Integer[] 'como es un array siempre se pasa por referencia
  10.  
  11. Public Sub Main()
  12.  
  13.   Dim x As Integer
  14.   Dim w As Integer
  15.   Dim SwitchNumero As Switch
  16.  
  17.   valores.Resize(6) 'creo un array de 6 valores
  18.  
  19.   SwitchNumero = New Switch(valores)
  20.  
  21.   For x = 1 To 100
  22.     w = Int(Rnd(6) + 1)
  23.    
  24.     SwitchNumero.operar(w)
  25.    
  26.   Next
  27.  
  28.   Print "Valores: ", 1, 2, 3, 4, 5, 6
  29.   Print "              ", valores[0], valores[1], valores[2], valores[3], valores[4], valores[5]
  30.  
  31. End



Bueno, y pensareis ¿es mucho trabajo y más código para hacer lo mismo? ¿que ventajas obtengo?

La primera ventaja que teneis es que el código es fácilmente ampliable, ya que simplemente se le vais que tener que nuevas clases "opciones".
Y otra muy importante, durante la ejecución del programa, podemos añadir o quitar dinamicamente opciones, cosas que es imposible hacerlo usando un Select Case.

Próximamente os enseñaré un ejemplo de esto último que os comento "añadir o quitar dinámicamente en ejecución, opciones".

Codigo fuente completo: alojada en Box.Com

Entradas Relacionadas:
http://jsbsan.blogspot.com.es/2014/01/combinar-patrones-de-diseno-ejemplo-de.html

No hay comentarios:

Publicar un comentario