Digamos que tengo una clase de Enemigo, y el constructor se vería así:
public Enemy(String name, float width, float height, Vector2 position,
float speed, int maxHp, int attackDamage, int defense... etc.){}
Esto se ve mal porque el constructor tiene muchos parámetros, pero cuando creo una instancia de Enemy necesito especificar todas estas cosas. También quiero estos atributos en la clase Enemy, para poder iterar a través de una lista de ellos y obtener / establecer estos parámetros. Estaba pensando en subclasificar Enemy en EnemyB, EnemyA, mientras codificaba su maxHp y otros atributos específicos, pero luego perdería el acceso a sus atributos codificados si quisiera recorrer una lista de Enemy (que consta de EnemyA, EnemyB y EnemyC's).
Solo estoy tratando de aprender a codificar limpiamente. Si hace la diferencia, trabajo en Java / C ++ / C #. Cualquier punto en la dirección correcta es apreciado.
Respuestas:
La solución es agrupar los parámetros en tipos compuestos. El ancho y la altura están relacionados conceptualmente: especifican las dimensiones del enemigo y generalmente se necesitarán juntos. Podrían reemplazarse con un
Dimensions
tipo, o tal vez unRectangle
tipo que también incluya la posición. Por otro lado, podría tener más sentido agruparposition
yspeed
formar unMovementData
tipo, especialmente si la aceleración luego entra en escena. A partir del contexto AsumomaxHp
,attackDamage
,defense
,, etc también pertenecen juntos en unStats
tipo. Entonces, una firma revisada podría verse así:Los detalles finos de dónde dibujar las líneas dependerán del resto de su código y qué datos se usan comúnmente juntos.
fuente
Enemy
es solo la clase que apunta alPlayer
, pero su clase base comúnCombatant
necesita las estadísticas de lucha.Dimensions
/MovementData
como contenedores de datos antiguos) o métodos (si los convierte en datos abstractos tipos / objetos). Como ejemplo, si aún no hubiera creado unVector2
tipo, podría haber terminado haciendo matemática vectorialEnemy
.Es posible que desee echar un vistazo al patrón Builder . Desde el enlace (con ejemplos del patrón versus las alternativas):
fuente
Usar subclases para preestablecer algunos valores no es deseable. Solo subclase cuando un nuevo tipo de enemigo tiene un comportamiento diferente o nuevos atributos.
El patrón de fábrica generalmente se usa para abstraer sobre la clase exacta utilizada, pero también se puede usar para proporcionar plantillas para la creación de objetos:
fuente
Me gustaría reservar subclases para las clases que representan objetos que tal vez quieras usar de forma independiente, por ejemplo, la clase de personaje donde todos los personajes, no solo los enemigos, tienen nombre, velocidad, maxHp o una clase para representar sprites que tienen presencia en pantalla con ancho, altura, posición.
No veo nada inherentemente incorrecto con un constructor con muchos parámetros de entrada, pero si desea dividirlo un poco, entonces podría tener un constructor que configure la mayoría de los parámetros y otro constructor (sobrecargado) que pueda usarse para establecer valores específicos y hacer que otros establezcan valores predeterminados.
Dependiendo del idioma que elija usar, algunos pueden establecer valores predeterminados para los parámetros de entrada de su constructor como:
fuente
Un ejemplo de código para agregar a la respuesta de Rory Hunter (en Java):
Ahora, puedes crear nuevas instancias de Enemy como esta:
fuente