Una cosa che mi ha sempre infastidito (in C #) è che c'è una dura dipendenza tra un'interfaccia / classe astratta e la classe e l'assembly di implementazione. Ciò significa che se due diversi assembly implementano la stessa interfaccia, uno di essi deve fare riferimento all'altro (dove si trova l'interfaccia) oppure entrambi devono fare riferimento a un terzo assieme con l'interfaccia.
Rende più difficile testare separatamente le diverse parti di un'applicazione e rende il codice molto meno flessibile dal momento che devi implementare quella specifica interfaccia. Inoltre, rende meno ordinate le librerie di distribuzione a terze parti, in quanto se si desidera distribuire solo parte delle proprie funzionalità, è necessario rielaborare la classe per terze parti per includere l'interfaccia oppure disporre in alcuni casi di qualche assemblaggio sciocco che contiene un'interfaccia tranne una.
Non dovrebbe esserci un modo per avere interfacce impalpabili? Quindi, ad esempio se hai due oggetti con un metodo che prende un'interfaccia come parametro, e ogni assembly ha interfacce separate ma identiche, allora potresti scambiare i due.
Sono sicuro che ci sono casi in cui vogliamo che le buone e rigorose dipendenze dell'interfaccia che abbiamo adesso, ma anche avere la possibilità di "interfacce morbide", possano essere una buona idea? Oppure il concetto è troppo contorto e applicabile in troppe poche situazioni (come ad esempio l'ereditarietà multipla). Ci sono linguaggi che non sono completamente anonimi che hanno risolto questo problema e c'è forse qualche design pattern da usare per evitare la dipendenza?
Esempio:
Assembly A:
public interface ISomeInterface
{
ReadBooks();
WriteLetters();
}
Public ClassA : SomeInterface
{
}
Assembly B:
public interface ISomeOtherInterface
{
ReadBooks();
WriteLetters();
}
public class ClassB
{
public DoStuff (ISomeOtherInterface someOtherInterface)
{
....
}
}
Qui mi piacerebbe avere un assembly C che faccia riferimento a A e B e facciate:
ClassA classA = new ClassA();
ClassB classB = new ClassB()
classB.DoStuff(classA as ISomeOtherInterface);
Non esiste una dipendenza diretta tra A e B, ma possono ancora essere usati insieme. Immagino che in questa istanza potrei fare una classe dell'adattatore, ma sembra goffo e in alcuni casi non appropriato.
Il casting specifico è un modo per andare, un altro sarebbe dichiarare un'interfaccia come dinamica (o qualsiasi altra cosa) e quindi controllerebbe solo che le interfacce siano identiche (ma non che siano la stessa interfaccia). Un terzo modo sarebbe di essere in grado di specificare "dinamici" sui parametri in modo che l'oggetto possa consentire o impedire quel tipo di interfacce.
Forse dovrebbe essere il contrario, a meno che tu dichiari un'interfaccia come "esplicita", puoi sempre fare quel tipo di digitazione.