Perché l'uso della programmazione basata su interfaccia sembra essere limitato al comportamento?

1

Ho riflettuto un po 'sull'ereditarietà e sulla realizzazione rispetto alla composizione. Non sto per pubblicare l'intero dettaglio qui. Quindi mi stavo chiedendo, quando non stiamo parlando di creare interfacce per facilitare i test unitari: perché la programmazione basata sull'interfaccia sembra concentrarsi sul raggruppamento di comportamenti comuni, ad esempio IPettable (per un animale), IEditable (per un controllo utente) , ISubmitable (per un modulo), ecc. Perché l'uso della programmazione basata sull'interfaccia sembra essere limitato al comportamento e non alle essenze. Potremmo usare pragmaticamente un'interfaccia, non tanto per realizzare un comportamento ma per realizzare somiglianze fisiche di senso comune che non potrebbero avere nulla a che fare con il comportamento? Non è che ci sia qualche caratteristica limitante all'interno della programmazione basata sull'interfaccia che non pensiamo di fare questo. Ciò significa che c'è una tendenza a utilizzare un'interfaccia in una frazione dei suoi possibili modi; quindi come mai?

    
posta CarneyCode 27.02.2011 - 12:23
fonte

5 risposte

4

Non è una limitazione, ma piuttosto un vantaggio - Le interfacce dovrebbero essere scritte per rendere la vita facile per il consumatore di un'interfaccia, e il consumatore è interessato a ciò che può fare con l'oggetto. Pertanto, le interfacce di successo sono quelle che si allineano strettamente con il modo in cui un oggetto viene utilizzato da altri (tramite petting, modifica o invio per utilizzare i propri esempi).

In ogni caso esistono interfacce marcatori in natura, come Serializable nel Javaverse o IDisposable nel mondo .NET. Personalmente li ho sempre trovati un po 'goffi, ma il tuo chilometraggio può variare.

    
risposta data 27.02.2011 - 12:58
fonte
1

Le interfacce sono un piccolo blocco di base che può essere utilizzato per creare una serie di modelli di progettazione (vedi Design Patterns , Gamma et al. o link ) per un sommario). Una scansione dei diversi tipi di schemi di progettazione ti mostrerà una più ampia varietà di modi in cui le interfacce vengono utilizzate.

In particolare, potresti voler confrontare il pattern decoratore e il pattern facciata . Gli esempi che hai sono quasi tutti decoratori, piccoli add-on che aggiungono funzionalità. Al contrario, le facciate sono come i contratti che definiscono un insieme di azioni previste da attuare. (nota: quelle sono entrambe spiegazioni semplificate, riesaminarle nei miei riferimenti suggeriti). Le interfacce possono essere utilizzate per implementare entrambi questi pattern e li troverete implementati in questo modo spesso in linguaggi interfacciati come Java.

    
risposta data 27.02.2011 - 20:53
fonte
1

Ho l'impressione che quello che stai cercando sia Programmazione generale ... non sono sicuro però: /

Nella programmazione generale avrai:

interface Pettable {
  void eat(Food f);
  void move(Direction, Distance);
}

E poi creerai una classe:

class Cat {
  void eat(Food f);
  void move(Direction, Distance);
}

E qualsiasi metodo che accetta un Pettable accetterà immediatamente un Cat , non perché hai derivato da Pettable ma perché semplicemente lo modella e il compilatore lo realizza.

Alcune lingue sono ancora più "generiche" e non richiedono di dichiarare affatto un'interfaccia, piuttosto la derivano dai requisiti del metodo (C ++ in modelli in fase di compilazione, Python in fase di runtime).

    
risposta data 27.02.2011 - 21:04
fonte
1

Le interfacce definiscono in modo efficace un contratto di presentazione e forniscono un mezzo per offrire la compatibilità tra le classi a un livello molto astratto. Quando si utilizza un'interfaccia, si sta effettivamente dicendo "questa classe è definita in un modo, ma può essere utilizzata in un altro modo per essere compatibile con un'altra classe" .

Fondamentalmente stai definendo un caso d'uso. Di solito non stai chiedendo un oggetto per le sue proprietà tramite un'interfaccia se hai accesso all'oggetto stesso. Normalmente chiederai comunque che l'oggetto si comporti in un modo che potrebbe essere coerente con il comportamento di altri tipi di classe in un sistema, in modo che ognuno possa essere chiamato e si prevede che si comporti in modo simile e coerente. Questo è Polymorphism 101.

Ora, mi contraddirei un po '. Ho detto prima che normalmente non chiedi alla classe le sue proprietà tramite un'interfaccia. L'intenzione con le interfacce come definite è sicuramente quella di comportarsi in questo modo. Tuttavia puoi richiedere che una classe ti fornisca le sue proprietà tramite un'interfaccia, ma tu usi il metodo invece della sintassi delle proprietà. In questo caso, si richiede alla classe (tramite un'interfaccia) di comportarsi in un modo che consenta di recuperare i valori tramite un metodo getter. È il classico comportamento richiesta / risposta, che è totalmente in linea con la natura comportamentale fondamentale delle interfacce, pur non escludendo la capacità di trattare una classe come se fosse semplicemente una struttura dati più semplice o un tipo compatibile con altre classi tramite un'interfaccia comune astrazione.

Anche il comportamento Getter / Setter è in linea con l'incapsulamento di tutte le variabili interne. Linguaggi come Delphi e ora C # con le sue proprietà automatiche tendono a sfocare le linee e fanno sembrare le proprietà come se fossero semplici variabili, ma la realtà è che per ogni proprietà c'è un metodo getter e setter sotto il cappuccio per ogni proprietà . E se no, dovrebbe esserci per preservare l'incapsulamento.

Da questa prospettiva, le interfacce non sono limitate al solo comportamento. Essi sono migliorati in modo efficace e, a loro volta, migliorano le classi che li implementano.

    
risposta data 04.02.2012 - 12:13
fonte
0

OOP non si limita ai comportamenti, piuttosto contiene caratteri, così fanno le interfacce. per esempio. IPerson può avere sia Characterstics {a.k.a proprietà} sia comportamenti {metodi a.k.a}. La programmazione basata sull'interfaccia tende ad astrarre i problemi del mondo reale nel mondo della programmazione mentre dall'altra parte l'ereditarietà / realizzazione / composizioni attua il mondo reale. In breve, le interfacce definiscono contratti / tipi {che potranno mai soddisfare, diventeranno quel tipo.} Mentre le classi (eredità / composizione) definiscono le implementazioni di quei contratti. per esempio. Diciamo che ho un'interfaccia ICandian che ha un carattere booleano BornInCanada , definendo che l'interfaccia non fa altro che definire un contratto che per essere canadese devi fornire un valore booleano, quindi qualsiasi persona chi dà un'implementazione di BornInCanada diventa quel tipo cioè ICanadico. Spero che tu abbia capito il mio punto.

    
risposta data 27.02.2011 - 12:45
fonte

Leggi altre domande sui tag