Now I also have the buildXml object which just builds xml and then another communicator class which posts it to another consumer. BUT if I make a utility class I actually have two ways that I will pass xml back and forth. One being through an HttpUrlConnection object and one just as a response on the OutputStream so I am lost on whether or not to put this utility class in the base class or a handler class or... just cant' see it yet. Sorry for my ignorance.
You're not ignorant, it's just part of learning and refactoring. I end up refactoring my designs several times until I am comftable with a design that is extensible. Thats the key here, Extensibility.
Never short change your designs, think of ways to write code to be modular and capable of adapting as requirements change. Let me ask you a question, what if a new technology or java API came along that allowed you to post your xml to a server via an FTPConnection? VoIPConnection? HTTPConnection? URLConnection? PacketConnection?
See?, Your design should be capable of interchanging behaviors (connection strategies) as needed without haveing to mess with any existing logic.
This is called the Strategy Design pattern. It's a basic principal that says "take the behavior that varies and encapsulate it into it's own class". So you end up with several classes, each one representing just a single behavior, also know as an algorithm. Then, the client that needs a behavior can use anyone of the algorithms at runtime and be able to interchange them as needed,.
Think of how Microsof Word saves documents. Word is capable of saving a document in different formats. Each format is a special encoding algorithm. A user selects the saving behavior to use when he saves. Example algorithms:
RTFAlgorithm, DOCAlgorithm, HtmlAlgorithm, WPSAlgorithm
Each one of those classes represent a single encoding algorithm. And since each algorithm operates differently, there is no inheritance for code reuse here. Instead, I bet each class implements a common Interface for polymorphic behavior. They each may implement an interface: "ISavable"
the Isavable interface says that all algorithms that want to be interchangable must implement the method called "Save()" and provide custom algorithm for saving a stream of chars.
Now, when a user selects to save as .doc, Microsoft Word simply saves the current document by calling .save() on the algorithm. Word does not care what algorithm it is, nor does it care how saving is done. It just knows to call .Save();
That approach allows vendors to write their own custom saving algorithms and plug them into word. Imagine Adobe writing a PDFAlgorithm to allows saving a document to .pdf format. The algorithm implements .Save() and accepts a stream of characters and does it's own thing for encoding to pdf.
Let's take your Communicator object for example. I am not sure what is the responsiblity of Communicator, so I will assume in this example that it is responsible for posting xml to a destination via some algorithm. So far you listed 2 possible ways to post:
1. HttpUrlConnection
2. OutPutStream
Make those 2 their own classes and let them implement a common interface like "ITransferable" or something liek that. Let them provide implementation for a common method like "Post()". That way, each algorithm can accept a stream of xml as a param and post it using its own uniqu algorithm.
You can then say to your friends that you employed a Strategy Pattern for posting xml. Now you can let your client objects reuse any one of these algorithms as needed. Example:
Utility.SetPostingAlgorithm(new HttpUrlConnection());
Utility.Post("xml file string here");
The Post method in Utility will delegate (fancy for redirect) the Posting responsibility to HttpUrlConnection class.
I am not sure if Utility should be the host for Posting xml. Maybe that part looks strage and needs further thought. Maybe your class1,class2,class3 etc needs this postable behavior?