se un'interfaccia c # contiene solo la definizione getter e setter, è un odore di codice?

2

Un progetto a cui sto lavorando ha il seguente codice per l'interfaccia Esempio:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Test
{
    public interface IDeviceEssentials
    {
        string Model { get; set; }
        string Manufacturer { get; set; }
        string BIOSVersion { get; set; }
        string TotalPhysicalMemory { get; set; }
        string TotalVirtualmemory { get; set; }
        string OSName { get; set; }
    }
}

ogni altra classe che implementa questa interfaccia utilizza le proprietà Automatic che rendono inutilizzabili getter e setter, quindi l'implementazione effettiva viene ridotta a

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Test
{
    public interface IDeviceEssentials
    {
        string Model;
        string Manufacturer;
        string BIOSVersion;
        string TotalPhysicalMemory;
        string TotalVirtualmemory;
        string OSName;
    }
}

Per cui è sufficiente una struttura o una classe per contenere i dati ..

L'uso principale dell'interfaccia è il polimorfismo che si avvale della sostituzione di liskov, anche se il codice precedente usa il setter getter che viene effettivamente ridotto alla decodifica variabile da tutte le classi che lo implementano (usando la proprietà automatica). Questo è che non c'è bisogno che io voglia simulare l'interfaccia di cui sopra. anche se è stato progettato come una classe, posso semplicemente prendere in giro creando una nuova classe.

Le domande sono: -

  1. Penso che le proprietà di cui sopra forniscano solo la rappresentazione dei dati. va bene usare l'interfaccia solo per la rappresentazione dei dati?
posta k4vin 28.11.2014 - 00:37
fonte

3 risposte

7

No, non è un odore di codice in sé. Avere molte implementazioni usando solo le proprietà automatiche è un odore di codice - questo è il punto in cui si rafforza il codice comune in una classe base e lo si definisce come virtuale, in modo che la classe estesa possa sovrascriverlo dove necessario.

every other class implementing this interface uses Automatic properties which renders the getters and setters useless

No, le proprietà automatiche non rendono inutile la definizione dell'interfaccia. Le tue due interfacce illustrate non sono le stesse - in effetti la seconda è illegale in quanto non è possibile definire un campo in un'interfaccia. Le proprietà automatiche usano ancora getter e setter (vengono inseriti dal compilatore), quindi l'utilizzo delle proprietà automatiche soddisfa i requisiti dell'interfaccia. Dichiarare semplicemente il campo public string Model; nella tua implementazione non soddisfa l'interfaccia.

Vedrai dall'immagine seguente che anche se ho usato le proprietà automatiche nell'implementazione ci sono ancora getter e setter implementati per me:

Se ciò non ha ancora senso, pensaci in questo modo: l'interfaccia definisce un contratto. Se successivamente refactifico la mia implementazione in modo tale che non utilizzi le proprietà auto, l'interfaccia garantisce che espongo sia un getter che un setter. Il consumo del codice utilizza la mia implementazione tramite la sua interfaccia, non accedendo direttamente all'implementazione concreta. Ciò significa che posso rifattorizzare l'implementazione e che il chiamante non deve assolutamente cambiare.

    
risposta data 28.11.2014 - 01:55
fonte
2

Questa interfaccia è perfettamente a posto. Spesso vedo questo tipo di interfaccia utilizzata su un oggetto responsabile della memorizzazione dei dati, per nascondere il codice di archiviazione dei dati dal consumatore.

Se segui i principi SOLID nella progettazione della tua classe, non importa quali siano le tue interfacce definite.

  • La classe dietro questa interfaccia è responsabile solo di una cosa?
  • È aperto per l'estensione e chiuso per la modifica?
  • segue il principio di sostituzione di Liskov?
  • Segue il principio di separazione delle interfacce?
  • segue il principio di inversione delle dipendenze?

Se puoi rispondere di sì a ciascuna di queste domande, il tuo design di classe dovrebbe essere ok. L'interfaccia diventa quindi quasi un sottoprodotto di questo processo di pensiero.

    
risposta data 28.11.2014 - 00:44
fonte
1

Sembra che ti preoccupi della duplicazione del codice. Un modo per aggirare è una classe astratta come menzionato in altre risposte. Ma l'ereditarietà può avere i suoi problemi, motivo per cui esiste un altro principio: utilizzare la composizione sull'ereditarietà.

Poiché IDeviceEssentials è fondamentalmente una struct, potresti renderla una classe concreta con solo le proprietà automatiche e nessuna logica. Quindi avere questa classe come membro delle altre classi che rappresentano i dispositivi concreti. Se necessario, presenta un'interfaccia IDeviceEssentialsProvider .

Esempio (Non sto fluentemente in C # quindi potrebbe essere necessario modificarlo):

public class DeviceEssentials
{
    string Model { get; set; }
    string Manufacturer { get; set; }
    string BIOSVersion { get; set; }
    string TotalPhysicalMemory { get; set; }
    string TotalVirtualmemory { get; set; }
    string OSName { get; set; }
}

public interface IDeviceEssentialsProvider
{
    DeviceEssentials DeviceEssentials { get; }
}

public class DeviceA implements IDeviceEssentialsProvider
{
    DeviceEssentials DeviceEssentials { get; }
}
    
risposta data 01.02.2017 - 19:15
fonte

Leggi altre domande sui tag