DDD: delegare la regola aziendale dell'oggetto dominio al servizio esterno

2

Situazione:

Sto implementando DDD nel mio primo progetto e vorrei chiarire come implementare correttamente il modello di strategia ( nel mio caso controlla se il token API è attivo). Questa è una regola aziendale dell'istanza di ApiToken, ma potrebbero esserci varie implementazioni di questa strategia, quindi vorrei delegare questa logica all'implementazione esterna.

Implementazione:

ApiToken class:

public abstract class ApiToken {
    public abstract boolean isActive(TokenActiveStrategy strategy);
}

e questo è un contratto di strategia token:

public interface TokenStrategy {
    boolean isActive(final ApiToken token);
}

E utilizzo:

TokenStrategy tokenStrategy = new DatabaseTokenStrategy();

if (!token.isActive(tokenStrategy)) {
   throw new AuthenticationException(ExceptionCodeType.TOKEN_NOT_ACTIVE);
}

e classe ApiToken concreta:

@Override
    public boolean isActive(final TokenStrategy strategy) {
        return strategy.isActive(this);
    }

Domanda:

Va bene per quanto riguarda i principi di DDD per delegare il controllo della regola aziendale di dominio out dell'oggetto dominio?

    
posta Artegon 02.07.2018 - 22:00
fonte

2 risposte

3

Un oggetto dominio non è responsabile della fornitura di informazioni al di fuori del proprio contesto. Se un token API è attivo o meno non è qualcosa che il token stesso può rispondere, ma è invece una domanda per il provider API: il provider API è la fonte della verità.

Una buona analogia con il mondo reale è: può una macchina dirti se è registrata o no? No, anche se c'è una targa o documenti di registrazione nella cella a guanti, non può. Solo l'autorità locale Auto / Strade può rispondere a questa domanda in modo veritiero.

Per me, la funzionalità che stai cercando di implementare (controllare se un ApiToken è attivo) dovrebbe risiedere in un servizio di dominio. Quindi, quando esegui un'implementazione concreta del servizio di dominio, it può chiamare il provider dell'API (oppure puoi simulare lo stub se test delle unità):

if (!apiTokenService.isTokenActive(token)) {
    throw new AuthenticationException(ExceptionCodeType.TOKEN_NOT_ACTIVE);
}

(Scusa per la mancanza di codice, Java (?) non è il mio punto di forza)

    
risposta data 03.07.2018 - 12:09
fonte
0

Purtroppo non esiste un'unica verità oggettiva su come fare queste cose. Dipende sempre dalla tua interpretazione di DDD e dal contesto in cui stai lavorando.

Interpretazioni

In una interpretazione, Entità non sono altro che titolari di dati o record, con la maggior parte o tutta la logica in Servizi o altre classi di supporto. In questa interpretazione, il tuo ApiToken non avrebbe nemmeno un metodo isActive() , invece pubblicherebbe tutti i suoi dati (tramite getters ), e lascia che altre classi si occupino di ciò a loro piacimento.

Se lavori in un contesto orientato agli oggetti, tuttavia, l'interpretazione può differire in modo significativo. In questo caso la tua soluzione proposta avrebbe due problemi:

  1. Gli oggetti Strategy dovrebbero avere accesso completo a tutto in ApiToken . In altre parole, sarebbero strettamente accoppiati. Questo è disapprovato nel mondo OO.

  2. Le classi Strategy sono parte non del dominio. Non fa parte del vocabolario condiviso tra sviluppatori e aziende. Non fa parte della lingua onnipresente .

Una possibile soluzione con OO + DDD in mente

Con la solita dichiarazione di non responsabilità che non conosco tutti i tuoi requisiti, come fare per farlo:

public interface ApiToken {
    boolean isActive();
}

public final class DatabaseApiToken {
    ...
    @Override
    public boolean isActive() {
        ...sql or whatever...
    }
}

Questo è molto più semplice, risolve entrambi i problemi sopra menzionati, compatibile sia con DDD che con OO.

Altri punti

Inoltre, guarda perché hai bisogno del metodo isActive() ! A volte (non sempre) esiste in realtà un singolo caso d'uso per esso, che a sua volta può essere spostato in ApiToken , rendendo così isActive() superfluo e avendo più logica completa in ApiToken , che è buono!

Ecco una mia presentazione su Design orientato al dominio orientato agli oggetti con alcuni punti.

    
risposta data 03.07.2018 - 15:35
fonte