Perché il servizio EJB Injection richiede la creazione della sottoclasse specifica?

-2

La maggior parte delle linee guida Java EE suggeriscono che dovremmo definire i servizi EJB astratti (API) e quindi definire le implementazioni concrete per conformarsi ai principi di progettazione OO.

Ma al punto di iniezione, l'EJB è locale o remoto, siamo costretti a fornire la classe di implementazione concreta.

Esempio:

@EJB(jndi="java:global/moduleName/ConcreteClassName:fullyQualifiedInterfaceName")
ServiceI service;

Pertanto, la domanda: come mai questa iniezione mantiene Inversion of Control e un ulteriore passo avanti: come può essere polimorfico?

EDIT:

Avendo capito che la domanda potrebbe non essere chiara, cercherò di dare un esempio.

Diamo un sistema che deve calcolare gli stipendi per i dipendenti. Esistono due tipi di stipendio per ora, è altamente possibile che un terzo arriverà:

public class Employee{
    String name;
    SalaryCalcService salaryService;
}

public interface SalaryCalcService {
  public double abstract calculateSalary();
}

public class PerMonthCalc implements SalaryCalcService {
  public double calculateSalary(){
     //return salary with per month calculations
  }
}

public class PerHourCalc implements SalaryCalcService {
  public double calculateSalary(){
     //return salary with per hour calculations
  }
}

Da qualche parte nel sistema vengono creati oggetti concreti:

SalaryCalcService perMonth = new PerMonthCalc();
SalaryCalcService perHour = new PerHourCalc();

Durante il lavoro quotidiano di sistema, vengono creati nuovi dipendenti:

Employee emp1 = new Employee();
emp1.serSalaryService(perMonth);
 //...

Infine, il codice cliente deve utilizzare tutte queste entità ed eseguire un calcolo per i pagamenti:

for(Employee emp : employees){
   double salary = emp.getSalaryService().calculateSalary();
}

Nel codice client, non ho bisogno di sapere, né preoccuparsi di quale sia l'implementazione specifica di SalaryCalcService.

Ancora più importante, se arriverà un terzo metodo di calcolo dello stipendio. Creerò solo una terza sottoclasse di SalaryCalcService e modificherò il punto in cui vengono creati gli oggetti Concrete. NO CODICE CLIENTE VERRÀ MODIFICATO.

Come posso implementarlo in un ambiente Java EE, in cui il servizio esegue DB e altre transazioni e deve essere un EJB?

    
posta Theodore 22.06.2018 - 20:23
fonte

1 risposta

2

Farò un tentativo di risposta, inventando un esempio concreto avendo scritto pochissimo Java e non avendo mai usato Enterprise Java Beans, quindi ecco qui.

Non viola il comportamento polimorfico perché i metodi di istanza della classe non usano il tipo concreto e utilizzano invece l'interfaccia.

Facciamo un esempio più concreto.

Abbiamo un'interfaccia "UserDataAccess" per gestire gli utenti nel sistema.

public interface UserDataAccess {
    User find(String username);
    void create(User user);
}

Ora abbiamo un oggetto "UserService" cablato dal contenitore EJB:

public class UserService {
    @EJB(name="OracleUserDataAccess")
    private UserDataAccess users;

    public User createNewUser(String username, String password) {
        User user = new User(username, password);

        users.create(user);

        return user;
    }
}

Vediamo l'annotazione @EJB che fa riferimento a un tipo concreto (OracleUserDataAccess), che sa come parlare direttamente con un database Oracle. Questa annotazione viene valutata in fase di esecuzione e, tramite la riflessione della classe, a un'istanza di UserService viene assegnato un oggetto OracleUserDataAccess, tuttavia UserService lo vede ancora come un oggetto UserDataAccess - l'interfaccia. Ciò è dovuto al tipo specificato per la proprietà "users" in UserService.

Quindi quando qualsiasi metodo di istanza di UserService chiama i metodi sulla proprietà "users", si tratta di un'interfaccia, non di un'implementazione concreta, e quindi non viola il polimorfismo.

    
risposta data 22.06.2018 - 21:44
fonte