Sto cercando di ridefinire un codice brutto e renderlo facilmente estensibile in futuro.
L'applicazione non dovrebbe essere altro che una serie di componenti che hanno input (s) e output (s). I componenti sono concatenati in modo tale che l'input del componente corrente sia l'output di uno (o più) componenti precedenti.
Ecco una rapida panoramica di ciò che ho finora:
-
Reader
- Indica un'origine dati
- Può essere un file su HDD, risorsa online, database, ecc.
-
Splitter
- L'input è
Reader(s)
- Divide il contenuto di ciò che il lettore consegna in parti
- Le uscite sono contenuti divisi di
Reader(s)
- L'input è
-
Model
- L'input è
Splitter(s)
- Crea un modello di qualcosa basato su
Splitter(s)
output - L'output è silenzioso, ma puoi dire che l'output è uno stato interno che può essere interrogato per i singoli input
- L'input è
-
Tester
- Input è un modello
- Può interrogare un modello per un risultato su alcuni dati
- L'output è facoltativo, ma nel caso venga utilizzato, è un flusso di dati (queryInput, queryOutput)
-
Writer
- L'input è praticamente tutto ciò che produce una collezione di oggetti
- Scrive quella raccolta ovunque
- Non so come dovrebbe essere l'output adesso
Quindi, voglio avere la possibilità di collegarli nel seguente modo:
-->Reader-->Splitter-->Model-->Tester-->Writer-->
Tuttavia, questa sarebbe anche una combinazione valida (ovviamente non fa altro che un semplice trasferimento di dati)
-->Reader-->Writer-->
Ora, dato che mi piacerebbe essere in grado di collegare (quasi) tutto a tutto e (possibilmente) creare catene piuttosto lunghe, suppongo che dovrei avere una sorta di interfaccia Pluggable
.
Inoltre, quando creo una tale catena di grandi dimensioni, probabilmente vorremmo racchiuderla dietro un Facade
. E poiché vorrei che ogni componente (classe) a innesto fosse sostituito da qualche altro, mi viene in mente il modello Strategy
.
Ora, poiché ho già menzionato il termine catena qui, mi viene in mente il pattern Chain of Responsibility
, nel modo seguente (o simile):
public interface Pluggable<InputType, OutputType> {
public void consume(Pluggable<?, InputType> previous);
public Collection<OutputType> produce();
}
Ad esempio, se volessi avere il mio Splitter
per dividere un elenco di File
s fornito da Reader
, potrebbe essere qualcosa del genere:
public class Splitter<InputType, OutputType> implements Pluggable<?, InputType> {
public void consume(Pluggable<?, InputType> previous) {
// retrieves for example a list of InputType objects
}
public Collection<OutputType> produce() {
// filters the collection it got and returns a sublist for example
}
}
Alla fine, i componenti potrebbero apparire in questo modo:
Reader<File, Foo> --> Splitter<Foo, Foo> --> Model<Foo, Void> --> Test<Model, Bar> --> Writer<Bar, DAO>
Non so in quale altro modo descrivere il problema che sto avendo, ma sono sicuro che qualcosa del genere è abbastanza realizzabile. Per un esempio visivo, ecco l'immagine del processo di RapidMiner
Nota che non sto cercando di replicare o copiare Rapid Miner, è solo che il progetto che mi è stato assegnato sembra che possa essere implementato in modo similare.
Apprezzerei qualsiasi aiuto su come progettare un'applicazione di questo tipo.