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:
->
' Desea calcular una función aleatoria.
' Repite una función aleatoria mil veces para
' conocer cuantas veces aparecen los números
' 1,2,3,4,5 o 6.
DIM x AS Integer
DIM w AS Integer
DIM a AS Integer
DIM b AS Integer
DIM c AS Integer
DIM d AS Integer
DIM e AS Integer
DIM f AS Integer
FOR x = 1 TO 1000
w = Int ( Rnd ( 6 ) + 1 )
SELECT CASE w
CASE 1
a = a + 1
CASE 2
b = b + 1
CASE 3
c = c + 1
CASE 4
d = d + 1
CASE 5
e = e + 1
CASE 6
f = f + 1
CASE ELSE
PRINT "¡Esto es imposible!"
END SELECT
NEXT
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:
->
' Gambas class file
Private ListaOpciones As New InterfaceOpcion[ ]
Public Sub _new( contadores As Integer [ ] )
'En el constructor indico que opciones estan disponibles
''------------------------------------------
''NOTE: Listado de Estrategias disponibles:
''------------------------------------------
''NOTE: Si hubieran mas opciones se añadirian continuacion
'--- poner aqui nuevas opciones... Dim XXXXXtmp as new OpcionXXXX
Dim Opcion1tmp As New Opcion1
Dim Opcion2tmp As New Opcion2
Dim Opcion3tmp As New Opcion3
Dim Opcion4tmp As New Opcion4
Dim Opcion5tmp As New Opcion5
Dim Opcion6tmp As New Opcion6
Opcion1tmp.numero = contadores
Opcion2tmp.numero = contadores
Opcion3tmp.numero = contadores
Opcion4tmp.numero = contadores
Opcion5tmp.numero = contadores
Opcion6tmp.numero = contadores
'añado las opciones a la lista de opciones
add( Opcion1tmp)
add( Opcion2tmp)
add( Opcion3tmp)
add( Opcion4tmp)
add( Opcion5tmp)
add( Opcion6tmp)
'aqui el programador podrá añadir más estrategias
End
Public Sub add( opcion As InterfaceOpcion)
'este médoto se puede usar tambien dinamicamente, durante la ejecución del programa..
ListaOpciones.Add ( opcion)
End
Public Sub remove( opcion As InterfaceOpcion)
'este método permite borrar dinamicamente durante la ejecución del programa, opciones
ListaOpciones.Remove ( ListaOpciones.Find ( opcion) )
End
Public Sub operar( expresion As String )
Dim opciontmp As New InterfaceOpcion
For Each opciontmp In ListaOpciones
If opciontmp.comprobar ( expresion) Then
opciontmp.operar ( expresion)
Return
Endif
Next
'no se ha encontrado ninguna opcion para la expresión
'se ejecuta la opcion por defecto
opcionDefecto( expresion)
End
Public Sub opcionDefecto( expresion As String )
Print "Error: " & expresion & " no reconocido "
End
Fijaos en la opcion "add" y "remove" que nos van a permitir añadir o quitar opciones.
Clase Interface:
->
' Gambas class file
Public Sub comprobar( expresion As String ) As Boolean
End
Public Sub operar( Optional valor As String )
End
Clase Opcion1:
->
' Gambas class file
Inherits InterfaceOpcion
Public numero As Integer [ ] 'lo pongo como array para que se pase por referencia
Public Sub comprobar( expresion As String ) As Boolean
If expresion = "1" Then
Return True
Else
Return False
Endif
End
Public Sub operar( Optional valor As String )
numero[ 0 ] += 1
End
Las demas opciones, son muy parecidas, vease el codigo fuente completo.
Programa Principal: Mmain
->
' Gambas module file
' Desea calcular una función aleatoria.
' Repite una función aleatoria mil veces para
' conocer cuantas veces aparecen los números
' 1,2,3,4,5 o 6.
'Se declaran publica para que se puedan acceder desde otros modulos/clases
Public valores As New Integer [ ] 'como es un array siempre se pasa por referencia
Public Sub Main( )
Dim x As Integer
Dim w As Integer
Dim SwitchNumero As Switch
valores.Resize ( 6 ) 'creo un array de 6 valores
SwitchNumero = New Switch( valores)
For x = 1 To 100
w = Int ( Rnd ( 6 ) + 1 )
SwitchNumero.operar ( w)
Next
Print "Valores: " , 1 , 2 , 3 , 4 , 5 , 6
Print " " , valores[ 0 ] , valores[ 1 ] , valores[ 2 ] , valores[ 3 ] , valores[ 4 ] , valores[ 5 ]
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