Architettura pulita di zio Bob - Entità composte

1

Sto costruendo un'applicazione Android e sto cercando di seguire il modello Clean Architecture.

Sono un po 'confuso su come dovrebbero apparire le mie entità riguardo ad alcuni dei miei casi d'uso.

Esempio

Ho una lista di canali e ogni canale ha programmi. Voglio visualizzare un elenco del programma corrente per ciascun canale e quando viene fatto clic su un elemento, visualizzo una pagina canale con le informazioni dettagliate sul canale e le informazioni sul programma corrente.

Enti

Posso vedere qui che dovrei avere un canale e un'entità del programma. Ma il canale dovrebbe avere un campo List<Program> programs (dato che ci sono programmi mutiple durante il giorno)? E un altro Program currentProgram ? Oppure il canale deve essere separato

Usa caso

Dovrebbero restituire entità o alcuni oggetti? Attualmente, i miei casi d'uso restituiscono entità, ma sono mappate ad alcuni oggetti dto nei presentatori.

TL; DR

Quale delle seguenti proposizioni è la strada da percorrere?

Proposte di pseudo-codice

Caso A

Enti

Channel
{
  id()
  name()
  logo()
}

Program
{
  id()
  name()
  thumbnail()
  start_date()
  end_date()
}

Casi di utilizzo
List<Channel> GetChannelsUseCase()
Program GetCurrentProgramForChannel(channelId)

Presenter

fetchChannels()
{
    // Builds a List<CurrentProgramViewModel> based on
    // GetChannelsUseCase composed with GetCurrentProgramForChannel for each channel
}

Caso B

Enti

Channel
{
  id()
  name()
  logo()
  programs()
}

Program
{
  id()
  name()
  thumbnail()
  start_date()
  end_date()
}

Casi di utilizzo
List<Channel> GetChannelsUseCase()

Presenter

fetchChannels()
{
    // Builds a List<CurrentProgramViewModel> based on
    // GetChannelsUseCase and filtering the programs()
    // to extract the 'current' program
}

Caso C

Enti

Channel
{
  id()
  name()
  logo()
}

Program
{
  id()
  name()
  thumbnail()
  start_date()
  end_date()
}

Repository
List<Channel> GetChannelsUseCase()
Program GetCurrentProgramForChannel(channelId)

Casi di utilizzo
List<ProgramDto> GetCurrentProgramUseCase()

{
    // The Use Case requests the repository to get the entities
    // and builds a ProgramDto object
}

Presenter

fetchChannels()
{
    // Maps a List<CurrentProgramViewModel> based on the
    // List<ProgramDto> returned by GetCurrentProgramUseCase
}

ps: chiederò informazioni sull'origine dati e repository più avanti / su un altro argomento, se necessario

    
posta w00ly 07.02.2018 - 12:54
fonte

2 risposte

2

Nella mia esperienza, un Program non è legato in modo permanente a Channel . Infatti, un Program può apparire su diversi Channels a volte anche allo stesso tempo!

Penso che manchi un'entità Listing che si occupa di associare Programs a un orario specifico. Ciò significa che il tuo Programs non dovrebbe più tracciare i loro orari di inizio e fine, ma probabilmente dovrebbero tracciare il loro duration . Potresti anche beneficiare di un Schedule per collegare un Listing con un Channel .

Pseudocodice :

Channel
{
  id,
  name,
  logo,
}

Program
{
  id,
  name,
  thumbnail,
  duration,
}

Schedule
{
  channelId,
  date,
  listings = Collection<Listing>
}

Listing
{
  program,
  startTime,
  endTime = () => startTime + program.duration,
}

Avresti quindi un servizio che ti consente di interrogare Schedule s base sul canale e sulla data.

    
risposta data 07.02.2018 - 13:31
fonte
1

Credo che un Presenter dovrebbe avere la minore logica possibile e interagire solo con un singolo UseCase.

Nel esempio di Uncle Bob, in realtà passa il Presenter a UseCase come parametro. (UseCase accetta un'interfaccia OutputBoundary.) UseCase passa un ResponseModel al Presenter che contiene tutte le informazioni che il relatore deve sapere per creare ViewModel. Nel complesso, questo è il più vicino al tuo caso C.

Nota: sono un po 'insicuro se ResponseModel dovrebbe contenere entità o proprietà.

E secondo la raccomandazione di MetaFight sulle entità mancanti ed evitando l'entità composta.

    
risposta data 05.04.2018 - 18:48
fonte