Please bear with me, if this type of question has been asked before. I am having a dilemma with object design and seeking experts' help here to come up with the correct/better design for a webservice client. I am attaching a crude UML diagram below:I have been writing/fixing Java code, but just getting into object design/architecture. I am writing a webservice client in Java to integrate a commercial Address Validation Geocoding Webservice into our application. Ours is a Tax software written in PowerBuilder running inside EAServer. I am writing the web service client in Java, so it can be integrated with the PB client through CORBA.I have done a similar service earlier to get some GIS information and this was slightly simpler design handling only XML for both Request and Response. I handled getting/sending request and response in the controller itself.I started using the same design and hit a road block: current web service handles both XML and REST (through HTTP GET URL); actually, there are 2 webservice urls, the one for Address Validation/Geocoding supports XML or REST, and the other for searching addresses uses REST only. I want to design a generic request abstract class/interface and the controller that can be used for both the services. While trying to come up with the classes, I ran into a classic design issue. Now with Request itself can be a XML string or a URI object (for REST Request), my approach of getting the request and sending it in Controller seems flawed.Should I make the Request object itself build and send XML/REST itself to the external Service or should I somehow manage to get different types of Requests into the Controller and send it from there (using getRequest, sendRequest)?Also, I am learning to use Design Patterns in Java. What type of design pattern would be applicable here? I saw command pattern suggested for a similar client. Also, can MVC pattern be applied here?I just want to get it right, before I started coding.UPDATE:My Address Record to send as part of request is,public class AddressRecord {  protected String AddressLine1;  protected String AddressLine2;  protected String City;  protected String State;  protected String PostalCode;  protected String Country;...}And my request object is,public class Request {  protected AddressRecord  records[];  protected ArrayList      actions;  protected ArrayList      columns;  protected Properties     options;  protected String         transmissionReference;  protected String         customerId;....}It can have one or addresses (I am planning to send only one for now). It also allows to specify the exact columns needed, actions to be done, Options etc.And my XMLRequest extends,public class RequestXml extends Request {..public String buildRequest(){...}And my problem came when I try to do REST Request similarly,public class RequestREST extends Request {..public URI buildRequest(){...}Depending on the columns chosen, the address will be validated and the service will optionally pass back the Lat/Long for the address, if found. A typical Address Request and Response may contain one or more of the following record (in XML format):Request record<Request>  <Actions>Check</Actions>  <Columns />  <CustomerID>1234567890</CustomerID>  <Options />  <Records>    <RequestRecord>      <AddressLine1>200 Main St</AddressLine1>      <AddressLine2 />      <City>Los Angeles</City>      <PostalCode>90012</PostalCode>      <State>CA</State>      <Country>USA</Country>      <CompanyName></CompanyName>      <EmailAddress />      <FirstName />      <FreeForm />      <FullName></FullName>      <LastLine />      <LastName />      <PhoneNumber></PhoneNumber>      <RecordID>1</RecordID>    </RequestRecord>    <TransmissionReference />  </Records></Request>Response record:Will contain validated and standard formatted address record.<ResponseRecord>  <AddressLine1>200 Main St</AddressLine1>  <AddressLine2></AddressLine2>  <City>Los Angeles</City>  <State>CA</State>  <CompanyName></CompanyName>  <EmailAddress></EmailAddress>  <NameFull></NameFull>  <PhoneNumber></PhoneNumber>  <PostalCode>90012</PostalCode>  <RecordExtras></RecordExtras>  <RecordID>1</RecordID>  <Reserved></Reserved>  <Results>AS01</Results>  <AddressExtras></AddressExtras>  <AddressKey>92688211282</AddressKey></ResponseRecord>I am probably stretching it too much. Like @Vladislav suggested, I could probably make buildRequest in URI request also return a String, and that might solve this issue; that can get this job done, but I am trying to learn to do it the proper way of identifying objects and design.UPDATE2:@Vladislav, This is what I had for an earlier Webservice client. They called their service GeoQuery, so I named it BoeQueryManager. Does this qualify to be the transport class you are referring to? I think this qualifies to be the Controller. The GeoQuery_MyLAService, generated by WSDL2Java may be the Transport object you referred to? I have redone the diagram, for the new program, to reflect the changes I see per my new understanding of your comments. Can you please validate that?FYI, our address validation is done in 3-parts - Address  Validation/Search, Geocode and once we get the Lat/Long, do the  internal GIS function to get city layers. I already did the 3rd part,  now working on replacing the 1st and 2nd services.public class BoeGeoQueryManager {  private void init(String aUrlStr) {    try {      URL endPoint = new URL(aUrlStr);      GeoQuery_MyLAService service = new GeoQuery_MyLAServiceLocator();      geoq = service.getGeoQuery_MyLAcfc(endPoint);    } catch (MalformedURLException me) {      logger.error(BOEGIS, , this.toString() +  -  +  init, Error initializing.  + me.getMessage());      me.printStackTrace();    } catch (ServiceException se) {      logger.error(BOEGIS, , this.toString() +  -  +  init, Error initializing Service.  + se.getMessage());      se.printStackTrace();    }  }  // Search by Address  public String queryBoeGis(String aAddress) throws Exception {    BoeXMLRequest lRequest = new BoeXMLRequest(aAddress, 0, 0, GISRequest.SEARCH_MODE_ADDRESS);    return queryBoeGis(lRequest);  }  // Search by Lat/Long  public String queryBoeGis(double aLatitude, double aLongitude) throws Exception {    BoeXMLRequest lRequest =        new BoeXMLRequest(GISRequest.REQUEST_BLANK_ADDRESS, aLatitude, aLongitude,            GISRequest.SEARCH_MODE_LATLONG);    return queryBoeGis(lRequest);  }  // 3. The controller is doing the Webservice call here. I just pass in   // the Request object into this. Controller is fully aware it's a XML  // Request/Response.  public String queryBoeGis(BoeXMLRequest aRequest) throws Exception {    String respXML = ;    String reqXML = ;    requestCount++;    try {      reqXML = aRequest.getXml();      if (aRequest.isModeLatLong()) {        respXML = geoq.qByCoords(reqXML);      } else if (aRequest.isModeAddress()) {        // search by address (or both)        respXML = geoq.addressValidationService(reqXML);      }      respXML = XMLDocument.cleanup(respXML);      BoeXMLResponse boeResponse = new BoeXMLResponse(respXML);      // To be able to get a flattened XML to be sent to the Legacy application      if (adjustXML)        respXML = XMLExtractor.getAdjXml(aRequest, boeResponse);    } catch (Exception e) {      e.printStackTrace();      respXML = ;    }    // Otherwise, return the original XML    return respXML;  }}
Java code design for a Geocoder Webservice client
java;object oriented;web services
You created two parallel class hierarchies: Request with concretes (XmlRequest, JsonRequest etc) and Response with concretes (XmlResponse, JsonResponse etc). But what I think you have to deal with is a Request / Response as a business entities (Request can be as simple as a string, containing address to geocode for our example, and a Response - an array of two floats - geographic coordinates) and a number of transports (Json, Xml etc.). Each transport has it's Request and Response encoder / decoder of the original Request object to represent request and response from appropriate web services.This way you will decouple your business logic from concrete implementations.Your controller will create a Request object and then, depending on some conditions, choose appropriate transport for it to send / receive data. Transports serialize Request, communicate with external web services, receive and deserialize Response and return it to the controller.UPDATE:After seeing your updates above I would like you to check if you need Request class descendants at all. Your request /  response scheme is highly customised depending on the transport. Why not to have a single Transport class hierarchy, which will receive your Request object and return Response?Transport will handle all URIs or whatever internal protocol details are.UPDATE 2:just curious: while learning OO, I keep hearing about making objects  self contained. This is why I made XMLRequest etc, thinking that's the  only one that knows about the request.Well, that's right. It's about SRP actually. If an implementation is very simple, you can assign 'transport' responsibility to a Transport class. If implementation becomes or is planning to become complex, you transform Transport into a module, make facade for it and then assign 'request handler' and 'response handler' responsibilities to classes, inside this module.When I'm doing OO design, I'm actually trying to keep system understandable and separable at all zoom levels: layer -> module -> class -> class member.I guess your second diagram is much better, but still blurs responsibilities between classes. Controller should create Request object and use some kind of factory to instantiate Transport. In this way, transport details are hidden from controller. It should know about abstract Transport class / module without going into details about its implementation.