需按固定順序執行多個命令、命令間共享上下文數據、支援動態配置流程步驟時,Commons Chain 提供標準化實現。
execute(Context) 返回 boolean (true 終止鏈)public class GetCustomerInfo implements Command {
public boolean execute(Context ctx) {
System.out.println("Get customer info");
ctx.put("customerName", "George Burdell");
return false; // 繼續
}
}
// TestDriveVehicle, NegotiateSale, ArrangeFinancing 結構類似,僅輸出日誌
public class CloseSale implements Command {
public boolean execute(Context ctx) {
System.out.println("Congratulations " + ctx.get("customerName") + ", you bought a new car!");
return false;
}
}
public class SellVehicleChain extends ChainBase {
public SellVehicleChain() {
addCommand(new GetCustomerInfo());
addCommand(new TestDriveVehicle());
addCommand(new NegotiateSale());
addCommand(new ArrangeFinancing());
addCommand(new CloseSale());
}
public static void main(String[] args) throws Exception {
Command chain = new SellVehicleChain();
Context ctx = new ContextBase();
chain.execute(ctx);
}
}
<catalog>
<chain name="sell-vehicle">
<command id="GetCustomerInfo" className="demo.chain.GetCustomerInfo"/>
<command id="TestDriveVehicle" className="demo.chain.TestDriveVehicle"/>
<command id="NegotiateSale" className="demo.chain.NegotiateSale"/>
<command id="ArrangeFinancing" className="demo.chain.ArrangeFinancing"/>
<command id="CloseSale" className="demo.chain.CloseSale"/>
</chain>
</catalog>
public class SellVehicleContext extends ContextBase {
private String customerName;
public String getCustomerName() { return customerName; }
public void setCustomerName(String name) { this.customerName = name; }
}
public class CatalogLoader {
private static final String CONFIG_FILE = "/demo/chain-config.xml";
private ConfigParser parser = new ConfigParser();
private Catalog catalog;
public Catalog getCatalog() throws Exception {
if (catalog == null) {
parser.parse(getClass().getResource(CONFIG_FILE));
catalog = CatalogFactoryBase.getInstance().getCatalog();
}
return catalog;
}
public static void main(String[] args) throws Exception {
CatalogLoader loader = new CatalogLoader();
Command chain = loader.getCatalog().getCommand("sell-vehicle");
Context ctx = new SellVehicleContext();
chain.execute(ctx);
}
}
true 可提前終止鏈Context 傳遞數據,SellVehicleContext 提供類型安全存取