Tengo el siguiente mapa:
Map<Double, List<SoundEvent>> soundEventCells = new HashMap<Double, List<SoundEvent>>();
Esto HashMap
asigna double
valores (que son puntos en el tiempo) a la SoundEvent
'celda' correspondiente : cada 'celda' puede contener un número de SoundEvent
s. Por eso se implementa como unList<SoundEvent>
, porque eso es exactamente lo que es.
En aras de una mejor legibilidad del código, pensé en implementar una clase interna estática muy simple como esta:
private static class SoundEventCell {
private List<SoundEvent> soundEvents = new ArrayList<SoundEvent>();
public void addEvent(SoundEvent event){
soundEvents.add(event);
}
public int getSize(){
return soundEvents.size();
}
public SoundEvent getEvent(int index){
return soundEvents.get(index);
}
// .. remove() method unneeded
}
Y que la declaración del mapa (y muchos otros códigos) se vería mejor, por ejemplo:
Map<Double, SoundEventCell> soundEventCells = new HashMap<Double, SoundEventCell>();
¿Es esto excesivo? ¿Harías esto en tus proyectos?
java
design
object-oriented
Aviv Cohn
fuente
fuente
private static
debe a que solo será utilizada por la clase externa, pero no está relacionada con ninguna instancia específica de la clase externa. ¿No es exactamente el uso apropiado deprivate static
?Respuestas:
No es exagerado en absoluto. Comience con las operaciones que necesita, en lugar de comenzar con "Puedo usar un HashMap". A veces, un HashMap es justo lo que necesitas.
En tu caso sospecho que no lo es. Lo que probablemente quieras hacer es algo como esto:
Definitivamente no quieres tener un montón de código que diga esto:
O tal vez podría usar una de las implementaciones de Guava Multimap .
fuente
TimeLine
clase exactamente para ese tipo de cosas :) Es una envoltura delgada alrededor de unHashMap<Double, SoundEventCell>
(eventualmente fui con la idea enSoundEventCell
lugar de laList<SoundEvent>
idea). Así que puedo hacertimeline.addEvent(4.5, new SoundEvent(..))
y encapsular las cosas de nivel inferior :)Si bien puede ayudar a la legibilidad en algunas áreas, también puede complicar las cosas. Personalmente, me inclino por envolver o extender colecciones por fluidez, ya que el nuevo contenedor, en la lectura inicial, me implica que puede haber un comportamiento que debo tener en cuenta. Considérelo una sombra del Principio de la menor sorpresa.
Seguir con la implementación de la interfaz significa que solo necesito preocuparme por la interfaz. La implementación concreta puede, por supuesto, albergar un comportamiento adicional, pero no debería tener que preocuparme por eso. Entonces, cuando intento encontrar el camino a través del código de alguien, prefiero las interfaces simples para facilitar la lectura.
Si, por otro lado, está encontrando un caso de uso que se beneficia del comportamiento agregado, entonces tiene un argumento para mejorar el código al crear una clase completa.
fuente
List
puede hacer, y hace todas esas cosas por una buena razón.SoundEventCell
podría implementarseIterable
paraSoundEvent
s, que ofrecería el iterador desoundEvents
miembro, por lo que podría leer (pero no escribir) como cualquier lista. Dudo en enmascarar la complejidad casi tanto como dudo en usar unList
cuando necesito algo más dinámico en el futuro.Ajustarlo limita su funcionalidad a solo aquellos métodos que decida decidir escribir, básicamente aumentando su código sin ningún beneficio. Por lo menos, intentaría lo siguiente:
Todavía puede escribir el código de su ejemplo.
Dicho esto, solo he hecho esto cuando hay alguna funcionalidad que la lista misma necesita. Pero creo que tu método sería excesivo para esto. A menos que tenga una razón para querer limitar el acceso a la mayoría de los métodos de List.
fuente
Otra solución podría ser definir su clase de contenedor con un único método que exponga la lista:
Esto le da a su clase bien nombrada con un código mínimo, pero aún así le proporciona encapsulación, lo que le permite, por ejemplo, hacer que la clase sea inmutable (haciendo una copia defensiva en el constructor y usando
Collections.unmodifiableList
en el descriptor de acceso).(Sin embargo, si estas listas solo se usan en esta clase, creo que sería mejor reemplazarlas
Map<Double, List<SoundEvent>>
por unMultimap<Double, SoundEvent>
( docs ), ya que eso a menudo ahorra mucha lógica y errores de verificación nula).fuente