Sto incontrando un problema di progettazione. Il mio codice è in C # ma i concetti potrebbero applicarsi a qualsiasi linguaggio OO.
Sto progettando un framework per eseguire esperimenti, e questi esperimenti hanno diverse variabili che manipoleremo, e diverse variabili che calcoleremo dopo la manipolazione (come le colonne in un foglio Excel). Ogni variabile può avere un certo numero di valori possibili. Ho bisogno di memorizzare queste variabili in qualche modo in un ordine particolare. Quindi, avrò bisogno di creare una riga di dati (una riga dell'ipotetico foglio excel) usando l'ordine definito, dove scelgo un singolo valore di ogni variabile e calcola alcuni dei valori delle variabili.
EDIT: Sulla base dei commenti sembra che ho bisogno di spiegare lo scopo. Gli utenti dovrebbero essere in grado di inserire il loro design sperimentale, cioè quali variabili vogliono e quali sono i livelli di ciascuna variabile. Quindi il mio programma effettua ogni permutazione di quelle (prove), randomizza le prove e poi le itera attraverso l'esperimento. L'output è tutto solo una stringa .csv. Quindi, dopo ogni prova, emette il valore di ogni variabile di input, quindi calcola e restituisce le variabili di output.
Ho tutto funzionante al momento. Ma al momento, ho bisogno di definire le variabili manualmente per gli utenti, e quindi possono mettere un elenco di valori in ciascuno per conto proprio. Devo anche scrivere manualmente le conversioni alle stringhe per ogni variabile e quindi inserirle manualmente nell'ordine e allineamento corretti per il file csv. Il mio obiettivo finale è di consentire loro di creare le proprie variabili e aggiungerle all'esperimento senza il mio intervento, e imporre un'attribuzione dell'output della stringa.
cosa ho:
List<float> levels = new List<float>();
levels.add(1f);
levels.add(2f);
levels.add(3f);
Experiment.variable1.levels = levels;
cosa voglio:
Experiment.AddVariable(new Variable<float>(levels);
// note that Variable should conceivably be any type
// and all variables types should have a method to output its value as a
// string depending on what type it is.
Quindi avrò qualcosa come:
inputvariable1 denominato "distance" ha valori int
:
1, 2
inputvariable2 denominato "time given" ha valori float
:
1.1, 1.2, 1.3
inputvariable3 denominato "some unknown class" ha alcuni valori definiti dall'utente:
CustomClass.OnOffEnum.ON, CustomClass.OnOffEnum.OFF
ouputvariable1 denominato "tempo di risposta" ha valori float:
Quindi ho una variabile di classe
public class Variable<T> {
string name
T value
}
Ora, ho bisogno di memorizzare in qualche modo queste variabili, così ho creato una classe Row:
public class Row {
List<Variable> variables;
public Row(List<Variable> variables) {
this.variables = variables
}
}
Ora ho un paio di problemi:
1. Come posso definire una struttura per le righe per ogni esperimento, in modo che tutte le righe di un particolare esperimento abbiano le stesse variabili nello stesso ordine? (stessi nomi, valori diversi).
Per affrontare questo problema ho preso in considerazione la modifica di Row
per richiedere un oggetto RowSchema
immesso per forzarlo a definire un determinato schema per le sue variabili. Ma ora ho indovinato quale dovrebbe essere la classe RowShema
.
2. Come posso garantire che ciascuna variabile implementa un metodo StringOutput()
che posso utilizzare per scrivere in un file di testo?
Ho preso in considerazione di forzare il tipo generico T di Variable
per implementare un'interfaccia con questo metodo, ma voglio Variable
per poter essere anche un tipo primitivo.
qualcosa come
public class Variable<T> where T : StringOutputter {
Ho preso in considerazione anche solo l'utilizzo di ToString()
, ma poi per i tipi personalizzati, non posso garantire che sarà un formato definito.
3. Sarebbe bello in altre parti del mio programma essere in grado di riferirsi al valore di una particolare variabile (per nome) di una particolare riga. Qualcosa di simile:
row2.<<variablename>>.value
Ho riflettuto su questo per diversi giorni, ma non riesco a capire l'architettura corretta.
La mia attuale implementazione consiste nel definire manualmente ogni Row
con i campi che rappresentano ciascuna variabile che voglio. Ma questo non è estendibile dal momento che ho bisogno di ridefinire la classe Row
per ogni esperimento.