另一种方法是采用推送模型而不是拉动模型。通常,您需要不同的格式化程序,因为您正在破坏封装,并且具有如下内容:
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();
...
其中,将数据从特定类型提取到格式化程序中。
相反,请创建与格式无关的数据接收器并反转流,以便特定类型将数据推送到接收器
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;
}
...
这意味着你仍然封装了数据,并且只是将标记的数据馈送到接收器。然后,XML 接收器可能会忽略数据的某些部分,可能会对其中的某些部分进行重新排序,然后编写 XML。它甚至可以在内部委托给不同的汇策略。但接收器并不一定需要关心车辆的类型,只需要关心如何以某种格式表示数据。使用内部全局 ID 而不是内联字符串有助于降低计算成本(只有在编写 ASN.1 或其他紧密格式时才重要)。