Miglioramento progressivo come caratteristica del linguaggio

1

Il miglioramento progressivo di solito si riferisce ai contenuti web e l'idea di avere una pagina leggibile prima che sia completamente funzionante.

Sono improvvisamente preoccupato dell'idea che non posso migliorare progressivamente il mio codice. Voglio essere in grado di aggiungere metodi ai miei valori. Potrei avere una proprietà stringa. Se voglio migliorarlo con un metodo IsValid (), non ho modo di farlo senza cambiare il chiamante.

Da un lato, questo sembra inevitabile. Avevo una stringa. Ora ho un oggetto con una stringa "value" e alcuni metodi. È un tipo completamente diverso, e devo chiamarlo in modo diverso.

Ma la realtà che sto modellando non è cambiata. Sono appena arrivato ad aggiungere IsValid (). Perché i chiamanti esistenti che vogliono solo il valore (e non si preoccupano della validità) devono adattarsi? C # ha la nozione di proprietà predefinite, dove, è possibile indirizzare una proprietà di raccolta solo fornendo la classe contenente e l'indice. Quindi è possibile modificare una lista in SomeClassWithAListInside senza la cura del chiamante. Perché non ci può essere equivalente per altri tipi di proprietà? Altre lingue trattano in modo diverso?

    
posta bbsimonbb 03.02.2017 - 11:10
fonte

3 risposte

2

Puoi aggiungere nuovi metodi a tutte le classi che controlli e, se non controlli una classe, puoi fornire una sottoclasse che supporta i nuovi metodi e che sarà trasparente per qualsiasi chiamante.

Quindi il problema che descrivi è solo un problema se vuoi estendere una classe che non controlla e che è sigillata in modo da non poter essere sottoclassi - come String in alcune lingue. String e primitive sono sigillati come compromesso per le prestazioni in questi linguaggi, quindi è necessario passare a un linguaggio più flessibile oppure evitare di esporre gli oggetti di dominio sotto forma di primitive in primo luogo.

Alcuni linguaggi dinamici come Python e JavaScript ti permettono di estendere oggetti arbitrari con nuovi metodi, che si chiama "patching scimmia". Questo tipo di soluzione risolve il problema, ma in genere è una cattiva idea perché rischi di interferire e, quando si attiva una stringa in un oggetto dominio, si trasformerà la stringa ogni nel programma in questo oggetto dominio che è ovviamente pazzo. I metodi di estensione in C # sono un approccio diverso che evita gli scontri, ma hanno ancora il problema fondamentale che si applicherà a tutte le istanze del tipo esteso.

    
risposta data 03.02.2017 - 14:46
fonte
2

I linguaggi procedurali si occupano di questo molto semplicemente. Quando vuoi più funzionalità, devi semplicemente aggiungere una funzione isValid(String) . I chiamanti che non conoscono questa funzione non lo usano. La funzione isValid non deve essere fisicamente posizionata insieme ad altre funzioni String .

Nei linguaggi funzionali, puoi sfruttare l'immutabilità per creare tutte le copie che vuoi dei dati. Alcune di queste copie possono avere trasformazioni applicate o altri dati associati ad essa in una struttura dati e sai che rimane sincronizzata a causa dell'immutabilità. Ciò significa che puoi avere un codice funzionante con String e alcuni che lavorano con EnhancedString , ma stanno entrambi lavorando sullo stesso valore sottostante.

Incapsulare tutta la tua mutabilità dietro i confini degli oggetti ha dei vantaggi, ma ha anche dei limiti, e ti sei imbattuto in uno di quelli grandi.

    
risposta data 03.02.2017 - 21:49
fonte
0

Molte lingue dinamicamente tipizzate ti permetteranno di fare questo genere di cose abbastanza facilmente. Ad esempio, in Javascript, potresti avere qualcosa di simile a questo:

var myString = new String("hello, world");
var myOtherString = new String("goodbye everything");
function stringValidator ()
{
    return this.indexOf(',') >= 0;
}
myString.isValid = stringValidator;
myOtherString.isValid = stringValidator;

alert (myString.isValid () + ", " + myOtherString.isValid()); // result: "true, false"

Più in generale, il tuo problema riguarda solo la tipizzazione statica. Se disponi di due tipi diversi che potresti aspettarti da un elemento, in un linguaggio con caratteri dinamici è sempre possibile per te restituire un oggetto che ha entrambi i tipi allo stesso tempo. Un linguaggio statico può o meno consentire questo (alcuni possono farlo tramite eredità multiple, ad esempio in C ++ si potrebbe implementare una classe che estende la classe di stringhe standard e aggiunge anche funzionalità aggiuntive, ma in C # o Java non si può perché le classi di stringhe in quelle lingue sono sigillate e non possono essere estese).

    
risposta data 05.02.2017 - 00:53
fonte

Leggi altre domande sui tag