Programmazione su interfacce orientate ai dati

9

C'è una parte del nostro codice base scritta nel seguente stile:

// IScheduledTask.cs
public interface IScheduledTask
{
    string TaskName { get; set; }
    int TaskPriority { get; set; }
    List<IScheduledTask> Subtasks { get; set; }
    // ... several more properties in this vein
}

// ScheduledTaskImpl.cs
public class ScheduledTaskImpl : IScheduledTask
{
    public string TaskName { get; set; }
    public int TaskPriority { get; set; }
    public List<IScheduledTask> Subtasks { get; set; }
    // ... several more properties in this vein, 
    // perhaps a constructor or two for convenience.
}

Cioè, ci sono un gran numero di interfacce che specificano solo un insieme di proprietà senza alcun comportamento ciascuna con una sola implementazione corrispondente che le implementa con proprietà automatiche. Il codice è scritto da qualcuno abbastanza anziano (molto più di me) ed è separato da questo uso di codice procedurale ragionevole per le interfacce. Mi chiedevo se qualcun altro avesse incontrato / usato questo stile e se avesse qualche vantaggio rispetto all'utilizzo di DTO in calcestruzzo ovunque senza le interfacce.

    
posta walpen 07.01.2016 - 01:40
fonte

2 risposte

5

Ecco i miei due centesimi:

  • Non siamo sicuri che un DTO non avrà mai almeno un po 'di comportamento. Quindi per me ci sono oggetti che potrebbero avere o meno comportamenti in futuro.
  • Una possibile causa di avere così tante classi di implementazione sole è la mancanza di design , ad esempio non riuscire a vedere che ScheduledTask , ScheduledJob , ScheduledEvent , ScheduledInspection , ecc. solo un'interfaccia Schedulable segregata che rende qualsiasi programma implementabile.
  • Creare prima le interfacce è un'ottima pratica, ti dà un'idea di ciò che ti serve. Molte interfacce iniziano senza alcuna implementazione. Poi qualcuno scrive un'implementazione e loro hanno quella. Lo stato di avere una sola implementazione è temporaneo se si evita ciò che cito nel secondo punto. Come fai a sapere in anticipo che alcune interfacce non avranno mai una seconda parte della terza implementazione?
  • Il nome che scegliamo per un'interfaccia ben pensata ha la tendenza a non cambiare in futuro, quindi le dipendenze su quell'interfaccia non saranno influenzate. D'altra parte una classe concreta può essere rinominata quando qualcosa di importante nel modo in cui viene implementata cambia, ad esempio una classe concreta chiamata TaxSheet potrebbe cambiare in SessionAwareTaxSheet perché è stata apportata una revisione significativa ma l'interfaccia ITaxSheet probabilmente non verrà rinominato così facilmente.

Bottom-line:

  • Buone pratiche di progettazione si applicano anche ai DTO.
  • I DTO possono essere aggiunti un po 'di comportamento lungo la strada.
  • Ogni interfaccia inizia con una sola implementazione.
  • D'altra parte, se hai troppe combo di una sola interfaccia e una sola classe, potrebbe esserci una mancanza di design che dovrebbe essere evidenziata. La tua preocupazione potrebbe essere giustificata .
risposta data 07.01.2016 - 16:16
fonte
1

Un problema particolare che ho riscontrato con i DTO che utilizzano le interfacce è che consente questo:

public interface ISomeDTO { string SomeProperty { get; set; }}

public class SomeDTO : ISomeDTO
{
    public string SomeProperty { get; set; }
    string ISomeDTO.SomeProperty { get { /* different behavior */ } set { SomeProperty = value; } }
}

Ho visto questo schema applicato come un trucco rapido e sporco per implementare alcuni comportamenti critici. Questo porta al codice che può avere un comportamento molto confuso:

SomeDTO a = GetSomeDTO();
ISomeDTO ia = a;
Assert.IsTrue(a.SomeProperty == ia.SomeProperty); // assert fails!

Questo è difficile da mantenere e confondere per cercare di districare o refactoring. IMO, l'aggiunta di comportamenti a DTO viola il principio di responsabilità unica. Lo scopo di un DTO è rappresentare i dati in un formato che può essere persistito e popolato da un framework di persistenza.

I DTO non sono modelli di dominio. Non dovremmo essere preoccupati se le DTO sono anemiche. Per citare la discussione di Martin Fowler sul modello di dominio anemico :

It's also worth emphasizing that putting behavior into the domain objects should not contradict the solid approach of using layering to separate domain logic from such things as persistence and presentation responsibilities.

    
risposta data 08.01.2016 - 22:21
fonte

Leggi altre domande sui tag