Imposta i dati in oggetti multi-livello (potrebbe usare Java Reflection)

0

Voglio possibilmente usare Java Reflection per impostare alcuni dati su RunTime. Il mio problema è che non riesco a capire come posso ottenere informazioni sulle sottoclassi e utilizzare come parte della riflessione.

Voglio usare Reflection per mantenerlo generico per una flessibilità futura.

Struttura Java - Classe e amp; Campi (tipo di dati di campo tra parentesi) che seguono nei punti elenco. Sono presenti metodi Setter / Getter per ogni campo. Questa è una rappresentazione di esempio.

Restaurant
  - RestaurantId (long)
  - RestaurantName (String)
  - RestaurantCity (String)
  - Employee (Employee object)
  - Menu (Menu object)

   Employee
     - EmployeeId (long)
     - EmployeeName (String)

   Menu
     - MenuId (long)
     - MenuItem (String)
     - MenuCategory (String)
     - MenuIngredients (Ingredients object)

       Ingredients
         - IngredientId (long)
         - IngredientName (String)

Come possiamo vedere, ho più livelli di struttura degli oggetti. Quindi Restaurant come l'oggetto più in alto, quindi entro Restaurant c'è l'oggetto di Employee e Menu e all'interno di Menu oggetto c'è un oggetto Ingredients .

Requisiti

Riceverò il nome e il campo della classe (nome del metodo) per impostare il valore. Per esempio. Otterrò qualcosa come Class = Restaurant & Field Method = setRestaurantCity e valore da impostare in Città. Potrei anche ottenere Class = Menu & Field Method = setMenuItem o diciamo Class = Ingredients & Field Method = setIngredientName e rispettivi valori per loro.

Ho fornito un codice java di esempio con il quale sto provando a testare. Come abbiamo potuto vedere nel codice java che funziona bene per l'impostazione del valore in Restaurant oggetto. Tuttavia mi piacerebbe impostare i dati in un altro oggetto che in realtà è di due livelli fino a Restaurant , cioè R estaurant --> Menu --> Ingredients . per valueObject2 .

Non voglio usare instanceOf in quanto avrebbe bisogno di me per verificare ogni singolo oggetto. Dato che la struttura corrente non è solo di 2 livelli ma molto più profonda, qualcosa come andare su fino a 5 livelli con oggetti di classe totale contando fino a 25 di essi.

Sto cercando una soluzione in cui posso abbinare i nomi della classe e impostare i rispettivi valori. Quindi, se ottengo valueObject3 e Respetive Class & Il campo viene inviato in futuro, quindi la soluzione dovrebbe funzionare.

Aperto per qualsiasi altra soluzione oltre a Reflection

Codice Java

public static void main(String[] args) {

        try {
            Object valueObject1 = "Mumbai";
            String fromClass1 = "com.test.Restaurant";
            String fromMethod1 = "setRestaurantCity";

            Object valueObject2 = "Bread";
            String fromClass2 = "com.test.Ingredients";
            String fromMethod2 = "setIngredientName";

            Object restnt = new Restaurant();
            Class<? extends Object> clsRestnt = restnt.getClass();
            System.out.println(clsRestnt.getCanonicalName());

            Method[] toRestMethods = clsRestnt.getMethods();

            for (int i = 0; i<toRestMethods.length; i++)
            {
                System.out.println(toRestMethods[i].getName());
                if(toRestMethods[i].getName().equalsIgnoreCase(fromMethod1))
                {
                    System.out.println("Found Method " + toRestMethods[i]);
                    valueObject1 = toRestMethods[i].invoke(restnt, valueObject1);

                }
            }

        } catch (ClassNotFoundException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
posta vnkotak 27.04.2016 - 13:31
fonte

2 risposte

2

La riflessione sembra un modo molto fragile e non intuitivo per implementarlo. Invece penso che dovresti essere che dice agli oggetti cosa fare , e collaboreranno tra loro per determinarlo. per es.

restaurant.switchToSpringMenu();

e l'oggetto Restaurant può scambiare tra istanze di menu che ha.

Exact requirement is that I will be getting some task to be done and corresponding value.. Now every task can be at different level in the hierarchy of the class... So I am not how else should I implement this

Forse ciò potrebbe essere ottenuto tramite un modello di visitatore . per esempio. fai qualcosa come:

restaurant.reorganise(forSummer);

dove forSummer è un'implementazione di un'attività. L'oggetto Restaurant collabora con questo oggetto compito, quindi chiama le classi Employee / Menu sottostanti, che faranno lo stesso.

Se vuoi davvero un mezzo più generico per navigare in queste gerarchie, puoi consultare JXPath , che consente di utilizzare espressioni simili a XPath per trovare oggetti, ad esempio

 (Ingredient)JXPathContext.newContext(restaurants).
         getValue("restaurant[address/zipCode='90210']/menu/ingredients[1]");
    
risposta data 27.04.2016 - 15:30
fonte
1

Questa è una pessima idea. Non dovresti farlo. Se vuoi davvero farlo, smetti di usare java - è del tutto inappropriato per l'attività in corso. Sembra che tu non capisca OO - se lo facessi non faresti questa domanda. Java, nonostante i suoi abusi comuni, è un linguaggio OO e dovrebbe essere trattato come tale.

La prima cosa che dovresti provare è il polimorfismo. Chiedi a tutte le classi di implementare un'interfaccia albero / grafico di base e un metodo setValue() che imposta il valore sull'oggetto specificato e passa il grafico a ciascun oggetto correlato chiamando anche setValue() .

La prossima cosa che dovresti provare è un approccio guidato dagli eventi. Gli oggetti devono essere registrati come gestori di eventi, quindi generare un evento contenente il valore da impostare. Chiedi ai gestori di impostare i valori appropriati nel modo appropriato.

Se usi la riflessione, finirai con codice illeggibile / non gestibile che è molto soggetto a errori e che probabilmente smetterà di funzionare non appena aggiornerai java o cambierai classe. Avrà una shelf-life molto breve.

    
risposta data 27.04.2016 - 15:45
fonte

Leggi altre domande sui tag