Al crear un objeto Java que se hace referencia con frecuencia a muchos niveles, es mejor utilizar una instancia de la clase o hacer que la estática de clase?

CMB:

Tengo un juego Java que estoy escribiendo donde necesito una base de datos maestra de los arquetipos de la unidad. La base de datos es sólo una clase que contiene un HashMap que almacena un par de casos docena de clase que contiene las estadísticas de los tipos de unidades individuales. Cuando las huevas juego una nueva unidad, copia la unidad fuera de la base de datos, utilizando el nombre de la unidad para localizarlo en el HashMap. Esta base de datos se construye una vez, cuando el programa se inicia, y no cambia. Tampoco estoy prorrogar o modificar cualquiera de las clases almacenadas en el HashMap. Se supone que debe ser una referencia de sólo lectura para el uso de los sistemas de juego.

Tengo varias otras clases, básicamente ejércitos, que contienen un número de unidades. Cuando un ejército se pone una unidad, copia los datos de la unidad de la base de datos. Tengo tres maneras de proporcionar las clases del ejército con una forma de leer la base de datos maestra. Me gustaría conocer su opinión en cuanto a que es la mejor solución para la creación de una forma sencilla, código legible que no se cree bichos raros.

He incluido un código simple para ilustrar los diferentes enfoques (lo siento si me perdí un punto y coma o algo así, puse mis ejemplos, junto con rapidez y todavía estoy aprendiendo Java).

Método 1) que crear la base de datos como una instancia de clase, y cada vez que crear un nuevo ejército o llamar a un método ejército que añade una unidad al ejército, que paso por el ejército o el método de una referencia a la instancia de base de datos como un parámetro. Esto debería ser bastante fácil de visualizar.

Método 2) que crear la base de datos como una instancia de clase. En la clase del ejército, tengo una referencia estática a la instancia de base de datos que consigue el sistema inmediatamente por un método estático en la clase del ejército. Después de la base de datos se rellena con datos, el método estático se llama y establece la referencia estática a punto a la base de datos. A partir de entonces, la clase del ejército siempre será capaz de extraer información de la base de datos, simplemente haciendo referencia a la variable estática.

class database
{
    // HashMap of unit archetypes
    private HashMap<String, Unit> unitLibrary = new HashMap<String, Unit>();

    // method for storing units in HashMap
    void storeUnits(String fileName)
    {
        // load unit stats from file
        // add new Unit instances to unitLibrary
    }

    // getter method
    Unit getUnit(String unitName)
    {
        return unitLibrary.get(unitName);
    }
}

class Army
{
    // variables
    private static Database masterDatabase;
    private static boolean databaseSet = false;
    ArrayList<Unit> armyUnits = new ArrayList<Unit>();

    // method for creating static database reference
    void setReference(Database d)
    {
        // set static reference to main database if not previously set
        if (!databaseSet)
        {
            masterDatabase = d;
            databaseSet = true;
        }
    }

    // add unit to army
    void addUnit(String unitName)
    {
        armyUnits.add(masterDatabase.getUnit(unitName);
    }   
}

public class CodeTest
{
    public static void main(String[] args)
    {
        // create master database
        Database masterDatabase = new Database();
        masterDatabase.storeUnits("FileOfUnits.game");

        // set static reference in army class to point to master database
        Army.setReference(masterDatabase);

        // Create army
        Army army1 = new Army();
        army1.addUnit("Soldier");
    }
}

Método 3) que crean el HashMap en la clase de base de datos como estática, y utilizar un método estático para rellenar con datos. Los métodos getter en la clase base de datos también se hacen estática. Ahora no hay paso de referencias en absoluto, porque cada vez que un ejército necesidades instancia de clase para tirar de la base de datos, sólo se ejecuta Database.getUnit ().

class database
{
    // HashMap of unit archetypes
    private static HashMap<String, Unit> unitLibrary = new HashMap<String, Unit>();

    // method for storing units in HashMap
    static void storeUnits(String fileName)
    {
        // load unit stats from file
        // add new Unit instances to unitLibrary
    }

    // getter method
    static Unit getUnit(String unitName)
    {
        return unitLibrary.get(unitName);
    }
}

class Army
{
    ArrayList<Unit> armyUnits = new ArrayList<Unit>();

    // add unit to army
    void addUnit(String unitName)
    {
        armyUnits.add(Database.getUnit(unitName);
    }   
}

public class CodeTest
{
    public static void main(String[] args)
    {
        // prepare master database
        Database.storeUnits();

        // create army
        Army army2 = new army2();
        army2.add("Soldier");
    }
}

He probado todos los tres métodos, y todos trabajan, pero el código está todavía en su infancia y no quiero que encuentre errores difíciles en el futuro debido a mi arquitectura de principios. Entiendo que no está encapsulado en la forma tradicional orientado a objetos, pero en realidad Método 3 parece el más limpio para mí, porque la base de datos se crea en el fondo y nunca ha redirigirá a través de un montón de llamadas a métodos diferentes para ser visitada. El código también tiene un menor número de líneas y no hay trucos como el que está en el método 2.

Cualquier sugerencia o experiencia con algo como esto? Yo he hecho mucho con Python, pero sólo recientemente he empezado a aprender Java, y todavía tratando de acostumbrarse a las restricciones de encapsulación.

Miguel :

Método 1 es el mejor.

Método 3, pero en realidad parece el más limpio para mí, porque la base de datos se crea en el fondo y nunca ha redirigirá a través de un montón de llamadas a métodos diferentes para ser visitada

Esto se parece ser el quid de la cuestión para mí. Usted está tratando de resolver la inyección de dependencia con las variables estáticas y es una idea terrible. Marcos como la primavera se puede ahorrar la molestia de los objetos que pasan por la cadena con características tales como autowiring si usted piensa que eso es un problema.

¿Y si, en su segundo ejemplo, puedo crear un ejército y olvido para establecer la base de datos? Tengo un objeto que es efectiva en un estado de semi-creado. Los objetos nunca deben estar en estado tal. Si hubiera requerido que se pasa al constructor, entonces habría evitado este potencial de errores.

Hay un problema de mantenimiento con sus ejemplos segundo y tercero, así, en la que se restringen a una sola instancia cuando no se tiene idea de cómo podrían cambiar sus requerimientos. ¿Cómo sabes que dos ejércitos diferentes serán siempre compartir una base de datos? ¿Y si en el futuro desea una ModernUSArmyy un AncientMacedonianArmy- Cómo se sabe con certeza que van a compartir los mismos arquetipos?

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=201785&siteId=1
Recomendado
Clasificación