The Decorator Pattern is very useful pattern to extend your application more flexible.
Usually, a factory pattern, only one class will be invoked, but by using decorator pattern, you can invoice more than one classes in one call.
public interface RtrnAdjustService { List<Map<String, Object>> getRmaLineToBeAdjustd(); List<Map<String, Object>> getRmaLineToBeAdjustd(RCV_RPT_LINETMsg rrLnTMsg); void adjustRma(List<Map<String, Object>> rmaLineToBeAdjustd, RCV_RPT_LINETMsg rrLnTMsg) throws RRException; }
Above: Interface
public class AWBL1050AdjustStaticFactory { private AWBL1050AdjustStaticFactory() { // Prevent non-static instantiation } public static RtrnAdjustService getObj(AWBL1050CMsg bizMsg, List<Map<String, Object>> rmaLineToBeAdjustd, RCV_RPT_LINETMsg rrLnTMsg) throws RRException { RtrnAdjustServiceModel model = creteModel(bizMsg); // 1st invoike model.setRmaLineStsCd(RMA_LINE_STS.CANCELLED); RtrnAdjustService svc = new RtrnAdjustServiceImplByRmaBase(model); /** RMA qty need to be added for Non-Crushed line */ svc.adjustRma(rmaLineToBeAdjustd, rrLnTMsg); /** Decolator Pattern (After first ajust) */ // 2nd invoice return new RtrnAdjustServiceImplRmaQty(svc, model); } }
Above: Factory call:
public class RtrnAdjustServiceImplByRmaBase implements RtrnAdjustService, AWBL1050Constant { protected RtrnAdjustServiceImplByRmaBase(RtrnAdjustServiceModel model) { this.model = model; } public List<Map<String, Object>> getRmaLineToBeAdjustd() { // Since RR line is not specified, the entire RR is a target return new List<Map<String, Object>>(); } public void adjustRma(List<Map<String, Object>> rmaLineToBeAdjustd, RCV_RPT_LINETMsg rrLnTMsg) throws RRException { // do something } }
Above: 1st class to be invoked
public class RtrnAdjustServiceImplRmaQty extends RtrnAdjustServiceDecolator implements AWBL1050Constant { protected RtrnAdjustServiceImplRmaQty(RtrnAdjustService svc, RtrnAdjustServiceModel model) { super(svc); this.model = model; } public List<Map<String, Object>> getRmaLineToBeAdjustd() { return new ArrayList<Map<String, Object>>(); // Return empty list } public List<Map<String, Object>> getRmaLineToBeAdjustd(RCV_RPT_LINETMsg rrLnTMsg) { return new ArrayList<Map<String, Object>>(); // Return empty list } @Override public void adjustRma(List<Map<String, Object>> rmaLineToBeAdjustd, RCV_RPT_LINETMsg rrLnTMsg) throws RRException { // do something } }
Above: 2nd class to be invoked
The factory class call two class by one call, so you don’t need to change any code from main class that call the method.
public abstract class RtrnAdjustServiceDecolator implements RtrnAdjustService { protected RtrnAdjustService svc; protected RtrnAdjustServiceDecolator(RtrnAdjustService svc) { this.svc = svc; } public abstract void adjustRma(List<Map<String, Object>> rmaLineToBeAdjustd, RCV_RPT_LINETMsg rrLnTMsg) throws RRException; }
Above: Abstract class for 2nd class
RtrnAdjustService svc = AWBL1050AdjustStaticFactory.getObj(bizMsg); List<Map<String, Object>> rmaLineToBeAdjustd = svc.getRmaLineToBeAdjustd(); . . /** Calling by factory */ svc = AWBL1050AdjustStaticFactory.getObj(bizMsg, rmaLineToBeAdjustd, rrLnTMsg); /** Method call */ svc.adjustRma(rmaLineToBeAdjustd, rrLnTMsg); .
Above: class and method call from such as main method