Salta al contenuto principale

18 - Preparazione Framework Enterprise

Preparazione ai Framework Enterprise Prima di affrontare framework come Spring , è fondamentale comprendere i pattern architetturali che li sottendono:...

Cosa ne pensi di questo articolo?

In Breve

Preparazione ai Framework Enterprise Prima di affrontare framework come Spring , è fondamentale comprendere i pattern architetturali che li sottendono:...

Preparazione ai Framework Enterprise

Prima di affrontare framework come Spring, è fondamentale comprendere i pattern architetturali che li sottendono: Dependency Injection e Inversion of Control.

Cosa Imparerai

  • Inversion of Control (IoC)
  • Dependency Injection (DI)
  • Pattern Repository e Service
  • Preparazione a Spring Framework

Inversion of Control (IoC)

Con IoC, il controllo della creazione e gestione delle dipendenze viene "invertito" dal codice applicativo a un container esterno.

Senza IoC vs Con IoC
// SENZA IoC: l'applicazione crea le dipendenze
class UserService {
    private UserRepository repository;

    public UserService() {
        // La classe decide come creare la dipendenza
        this.repository = new MySqlUserRepository();
    }
}

// CON IoC: le dipendenze vengono iniettate dall'esterno
class UserService {
    private final UserRepository repository;

    // La dipendenza è fornita da un container esterno
    public UserService(UserRepository repository) {
        this.repository = repository;
    }
}

Dependency Injection

Tipi di Injection
// 1. CONSTRUCTOR INJECTION (preferito)
class OrderService {
    private final OrderRepository repository;
    private final PaymentService paymentService;

    public OrderService(OrderRepository repository, PaymentService paymentService) {
        this.repository = repository;
        this.paymentService = paymentService;
    }
}

// 2. SETTER INJECTION
class OrderService {
    private OrderRepository repository;

    public void setRepository(OrderRepository repository) {
        this.repository = repository;
    }
}

// 3. FIELD INJECTION (non raccomandato senza framework)
class OrderService {
    @Inject  // Richiede framework DI
    private OrderRepository repository;
}

Container DI Semplice

Mini Container DI
import java.util.*;
import java.util.function.Supplier;

// Semplice container DI
class DIContainer {
    private Map<Class<?>, Supplier<?>> factories = new HashMap<>();
    private Map<Class<?>, Object> singletons = new HashMap<>();

    public <T> void register(Class<T> type, Supplier<T> factory) {
        factories.put(type, factory);
    }

    public <T> void registerSingleton(Class<T> type, T instance) {
        singletons.put(type, instance);
    }

    @SuppressWarnings("unchecked")
    public <T> T get(Class<T> type) {
        if (singletons.containsKey(type)) {
            return (T) singletons.get(type);
        }
        Supplier<?> factory = factories.get(type);
        if (factory == null) {
            throw new RuntimeException("No registration for: " + type);
        }
        return (T) factory.get();
    }
}

// Uso
public class Application {
    public static void main(String[] args) {
        DIContainer container = new DIContainer();

        // Registra dipendenze
        container.registerSingleton(UserRepository.class,
            new InMemoryUserRepository());
        container.register(UserService.class,
            () -> new UserService(container.get(UserRepository.class)));

        // Risolvi
        UserService service = container.get(UserService.class);
    }
}

Pattern Repository

Repository Pattern
// Interfaccia Repository
interface Repository<T, ID> {
    Optional<T> findById(ID id);
    List<T> findAll();
    T save(T entity);
    void delete(T entity);
    boolean existsById(ID id);
}

// Implementazione specifica
interface UserRepository extends Repository<User, Long> {
    Optional<User> findByEmail(String email);
    List<User> findByRole(String role);
}

// Implementazione concreta
class JpaUserRepository implements UserRepository {
    // Implementazione con JPA/JDBC
}

class InMemoryUserRepository implements UserRepository {
    private Map<Long, User> storage = new HashMap<>();
    private long nextId = 1;

    @Override
    public Optional<User> findById(Long id) {
        return Optional.ofNullable(storage.get(id));
    }

    @Override
    public User save(User user) {
        if (user.getId() == null) {
            user.setId(nextId++);
        }
        storage.put(user.getId(), user);
        return user;
    }

    // ... altri metodi
}

Architettura a Layer

Controller -> Service -> Repository
// LAYER 1: Controller (gestisce richieste HTTP)
class UserController {
    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    public Response createUser(CreateUserRequest request) {
        User user = userService.createUser(request);
        return Response.ok(user);
    }
}

// LAYER 2: Service (business logic)
class UserService {
    private final UserRepository repository;
    private final EmailService emailService;

    public UserService(UserRepository repository, EmailService emailService) {
        this.repository = repository;
        this.emailService = emailService;
    }

    public User createUser(CreateUserRequest request) {
        // Validazione
        if (repository.findByEmail(request.getEmail()).isPresent()) {
            throw new UserAlreadyExistsException();
        }

        // Creazione
        User user = new User(request.getName(), request.getEmail());
        User saved = repository.save(user);

        // Side effect
        emailService.sendWelcome(saved);

        return saved;
    }
}

// LAYER 3: Repository (accesso dati)
// Già definito sopra

Prossimi Passi: Spring Framework

Cosa Imparerai con Spring

  • Spring Core: IoC container, Bean, @Autowired
  • Spring Boot: auto-configuration, starter
  • Spring Data: JPA, MongoDB, Redis
  • Spring MVC: REST API, @Controller
  • Spring Security: autenticazione, autorizzazione
Anteprima Spring Boot
// Con Spring Boot, il codice diventa molto più semplice
@RestController
@RequestMapping("/api/users")
public class UserController {

    @Autowired
    private UserService userService;

    @PostMapping
    public ResponseEntity<User> createUser(@RequestBody CreateUserRequest request) {
        User user = userService.createUser(request);
        return ResponseEntity.status(HttpStatus.CREATED).body(user);
    }

    @GetMapping("/{id}")
    public ResponseEntity<User> getUser(@PathVariable Long id) {
        return userService.findById(id)
            .map(ResponseEntity::ok)
            .orElse(ResponseEntity.notFound().build());
    }
}

@Service
public class UserService {
    @Autowired
    private UserRepository repository;

    // Business logic...
}

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
    Optional<User> findByEmail(String email);
}

Congratulazioni!

Hai completato il corso Java! Ora hai le basi solide per affrontare framework enterprise come Spring, Jakarta EE, o Quarkus.

Domande frequenti

Qual è l'obiettivo principale della preparazione ai framework enterprise?

Comprendere i pattern architetturali che li sottendono, come Dependency Injection e Inversion of Control.

Cos'è l'Inversion of Control (IoC) e come funziona?

L'IoC "inverte" il controllo della creazione e gestione delle dipendenze dal codice applicativo a un container esterno.

Qual è la differenza tra Dependency Injection e Inversion of Control?

Il Dependency Injection si riferisce alla fornitura di dipendenze da parte del container, mentre l'IoC si riferisce all'inversione del controllo della creazione e gestione delle dipendenze.

Quali sono i prossimi passi dopo aver completato il corso Java?

Affrontare framework enterprise come Spring, Jakarta EE o Quarkus con le basi solide acquisite.

Fonti e approfondimenti

Prova Questi Strumenti

Strumenti gratuiti correlati a questo argomento.

Commenti

Caricamento commenti...

Accedi per commentare

Discuti questo articolo nella community

Unisciti al gruppo Telegram per discutere con altri sviluppatori, fare domande e condividere le tue esperienze.

Ti è piaciuto questo articolo?

Esplora altri contenuti sul blog o scopri i miei progetti