La considerazione principale qui è il principio di segregazione intefrace
The interface-segregation principle (ISP) states that no client should be forced to depend on methods it does not use. ISP splits interfaces that are very large into smaller and more specific ones so that clients will only have to know about the methods that are of interest to them.
Per maggiore chiarezza, diamo un'occhiata a un altro esempio (scusa la sintassi C #).
public interface IManageUserService()
{
void SaveUser();
void DeleteUser();
}
Queste interfacce dovrebbero essere divise in ISaveUserService
e IDeleteUserService
?
La risposta a ciò si basa sulla possibilità per una classe di implementare una e non l'altra . Se la tua logica aziendale richiede un servizio per implementare entrambi (o nessuno dei due), allora dovrebbero stare insieme. Se è perfettamente possibile per un servizio eseguire solo una delle attività, è necessario separarle.
Tornando al tuo esempio, possiamo porre la stessa domanda qui:
Ci possono essere classi che hanno solo Name
o un Age
, ma non entrambe?
Supporrei di sì. Ciò significa che è davvero corretto dividere le interfacce.
Footnote
There is, however, an argument of reasonability. If it's technically possible to use only part of an interface, but it doesn't actually ever occur in practice; then it might be better to keep the interface together in favor of writing less boilerplate code.
In such a case, you need to consider the likelihood that you will have to split the interface in the future (if an object is developed which does only use half of the interface). If the odds are low, then it's fair to avoid unnecessarily splitting the interface. If the odds are high, you're better off doing it now instead of having to refactor it later.
Dividere l'interfaccia in sub-interfacce
Potremmo raggiungere un punto in cui tentare di suddividere gli atomi qui. Hai intenzione di creare un'interfaccia per ogni proprietà esistente? Perché è un sacco di lavoro, il che non offre alcun vantaggio diretto per quanto posso vedere.
- Every DTO will always have the same field signature, for example: Name will always have String getName(), avoiding mistakes
Tecnicamente corretto, ma non vale la pena di creare interfacce per ogni proprietà. A mio parere.
A parte il completamento dell'intelligenza e il controllo ortografico in fase di compilazione, esiste una ragione logica per fare ciò?
- Centralize Annotation, avoid duplication
Questo sembra lo stesso argomento del precedente punto elenco.
3.1. Easier to distinguish different fields from differnt DTOs, so getName from ChangeUserPasswordDTO is the same as getName from RegisterUserDTO since they both extends the same Name
Se non ci sono relazioni tra Foo.Name
e Bar.Name
, c'è davvero qualcosa da guadagnare dall'avere Foo e Bar implementare la stessa interfaccia IName
?
Non sono convinto che stai guadagnando nulla che superi lo sforzo di renderlo tale. L'unico vantaggio di avere un'interfaccia è garantire un contratto tra diverse classi che implementano la stessa interfaccia. Perché mai sarà rilevante per FooDto
e BarDto
per essere indirizzati in modo intercambiabile (cioè come una variabile di tipo IName
)?
3.2. but different from getName from BlogDTO
Sono un po 'in difficoltà qui; ma questo può essere specifico della lingua. Manca questo dal tuo codice di esempio?
Pensavo che il tuo obiettivo fosse utilizzare la stessa interfaccia per ogni classe (dto) che ha una proprietà Name
? Perché BlogDTO
dovrebbe essere diverso da allora?