#210 olvídate de patrones. Como una primera "aproximación" intenta separar el programa en módulos. Por ejemplo, para este caso, en el servidor hay dos módulos claramente diferenciados:
- Servidor central
- Conexiones con cada cliente
Cada uno de ellos es una clase/módulo/loquesea (depende de cómo abstraiga tu lenguaje.) Yo además los separaría aún más:
- Servidor central
1.1. Aceptador de conexiones
1.2. Manejo de lista de clientes (nicks)
1.3. Reenvío de mensajes a todos los clientes (canal) - Conexiones con cada cliente
2.1. Manejo de la conexión
2.2. Manejo de mensajes
Cada una de estas sub-separaciones serían métodos concretos en este caso. Si quieres separar aún más la lógica puedes organizarlos como submódulos (o lo que sea), es decir, ahora ya te puedes plantear aplicar patrones para separar algo más la lógica del programa.
Yo lo que haría sería no ligar el manejo de mensajes en un sólo módulo si no separar cada mensaje en un manejador diferente, es decir, crearía una nueva clase manejador. La idea es la siguiente: en el momento en el que llega un mensaje, la clase ConexionCliente NO es la que se encarga de responder (2.2) si no que simplemente reenvía el mensaje al manejador. Este puede decidir realizar alguna acción (o no) y posteriormente consumir el mensaje (ya no lo tocan más manejadores) o reenviarlo (independientemente de si ha hecho algo o no.) Esto da un montón de flexibilidad porque desligas los mensajes de la conexión y permite crear diferentes tipos de conexión sin montarte películas. Ppor ejemplo, un admin podría tener manejadores para kickear y demás mientras que un usuario no, sin necesidad de añadir un "isAdmin" por todos lados.
La estructura quedaría algo así:
- Servidor central
1.1. Aceptador de conexiones
1.2. Manejo de lista de clientes (nicks)
1.3. Reenvío de mensajes a todos los clientes (canal) - Conexiones con cada cliente
2.1. Manejo de la conexión y mensajes (crear conexión y reenviar a manejadores cada mensaje) - Manejo de mensajes
3.1. Acción
Así en el momento en el que el servidor (1) crea una conexión (2) le asocia a esa conexión ciertos manejadores (3)
Toda la separación "física" ya es cosa del lenguaje. Por ejemplo, en Java el manejo de mensajes lo implementaría como un interfaz (que cada manejador implementaría) mientras que en Scala cada manejador sería una simple función.
Ojo, esto es sólo una de las múltiples estructuras que puedes crear, pero creo que muestro bien el proceso que hay detrás de la separación y encapsulación.
Vaya, ya me he marcado otro tocho.