Un altro approccio consiste nell'adottare un modello push anziché un modello pull. In genere è necessario diverse formattatori perché si sta rompendo l'incapsulamento, e avere qualcosa di simile:
class TruckXMLFormatter implements VehicleXMLFormatter {
public void format (XMLStream xml, Vehicle vehicle) {
Truck truck = (Truck)vehicle;
xml.beginElement("truck", NS).
attribute("name", truck.getName()).
attribute("cost", truck.getCost()).
endElement();
...
dove si sta tirando i dati dal tipo specifico nel formattatore.
Invece, creare un lavandino di dati in formato-agnostico e invertire il flusso in modo che il tipo specifico di dati spinge al lavandino
class Truck implements Vehicle {
public DataSink inspect (DataSink out) {
if (out.begin("truck", this)) {
// begin returns boolean to let the sink ignore this object
// allowing for cyclic graphs.
out.property("name", name).
property("cost", cost).
end(this);
}
return out;
}
...
Ciò significa che hai ancora i dati incapsulati, e si sta solo alimentando dati taggati al lavandino. Un sink XML potrebbe quindi ignorare determinate parti dei dati, magari riordinarne alcune e scrivere l'XML. Potrebbe persino delegare a diverse strategie di sink internamente. Ma il dissipatore non ha necessariamente bisogno di preoccuparsi del tipo di veicolo, solo come rappresentare i dati in qualche formato. L'utilizzo di ID globali internati anziché di stringhe inline consente di ridurre i costi di calcolo (solo se si scrive ASN.1 o altri formati stretti).
fonte
2009-03-30 09:28:08
Potrebbe essere meglio rinominare IVehicleFormatterVisitor solo su IVehicleVisitor, in quanto è un meccanismo più generico rispetto alla semplice formattazione. – Richard
hai assolutamente ragione. –
Una soluzione apt. +1 –