1

I have a current situation where I have to design calls to multiple webservices, coming from different companies, let's say EnrollFacebook, EnrollGoogle, EnrollYelp, EnrollBing.

I need to build different options that bundle this enrolls, for instance:

  • PlanA: EnrollFacebook, EnrollGoogle, EnrollBing
  • PlanB: EnrollGoogle
  • PlanC: EnrollYelp, EnrollBing
  • PlanD: EnrollFacebook, EnrollGoogle, EnrollYelp, EnrollBing

Later on, if I need to build a PlanE, I want to be able to build using the different units (aka enrolls, and plug google with yelp or whatever).

I'm investigating about a design pattern that helps me covering this, since every enroll is an independent unit, not knowing others enrolls. However if any of the unit fails, I have to call all the deenroll related to all success enrolls.

Do you know a pattern that suit my needs? I was reading about Pipeline or Mediator but not sure if this actually cover what I describe.

Update: I've read this post Choosing the right Design Pattern, but however this does not help since I know what my problem is and I just trying to find an existing solution for this problem since this seems a very common problem, I don't want to reinvent the wheel if there are good designs out there.

2 Answers2

1

The chain of responsibity seems to be a good candidate for this at first sight:

  • a handler could have an optional successor, thus creating the kind of variable chain that you describe
  • the concrete handler class would implement an enrollX client
Christophe
  • 81,699
-1

I would suggest you to use dependency injection. Have an XML file define various Enroll elements and Plan elements.

<config>
    <plan name="PlanC">
        <enroll refId="EnrollYelp" order="0" attr1="val1" attr2="val2"/> 
        <enroll refId="EnrollBing" order="1" attr1="val1" attr2="val2"/> 
    </plan>
    <plan name="PlanA">
        <!-- more child enroll elements -->
    </plan>
    <enroll name ="EnrollGoogle" attr="val">
    </enroll>
    <enroll name ="EnrollYelp" attr="val">
    </enroll>
</config>

(You need to create a schema defining above structure)

Now the code part. (I am going to use Java for describing things)

In the code, you can have an Enroll class and Plan class. The plan class has two queues: enrollQueue and deenrollQueue

class Plan{
    Queue<Enroll> enrollQueue;
    Queue<Enroll> deEnrollQueue;
    // Other variables and methods follow
}

Have enroll and deenroll methods defined in Enroll class:

class Enroll{
    String name;
    //other variables
    private boolean enroll(){
         // enroll logic might be based on attributes present in XML --
         // -- which were read by factory class and assigned into variables of this class.
         // return boolean indicating success of failure
    }
    private boolean deEnroll(){
         // enroll logic might depend on variables of this class which depend on attributes in XML element
         // return boolean indicating success of failure
    }
}

Also have a Factory class which reads the xml file defined above and creates the Plan elements. In your entrypoint/main/controller class, create the plans based on xml

List<Plan> planList = PlanFactory.readPlansFromXML();

Now for each plan in the planList, perform the core task

for(Plan plan:planList){
    // get enroll queue for the plan
    // for each element in enroll queue
        // remove element from enroll queue and add it to deEnroll queue
        // execute enroll() for the element
        // if enroll() fails, execute deEnroll() for each element in deEnroll queue and break to next plan
        // if enroll() is successful, continue the loop with next element in enrollQueue
}   

Since all the plans and all the enrolls are defined in XML, you can easily define new Enrolls and new Plans just by editing the XML without any changes to the code.

RajatJ
  • 1