Java Design Patterns – Is This a Good Case for Proxy Pattern or Overdone?

designdesign-patternsjava

Working on a major enhancement for legacy code, I have been wrestling with myself over whether this is a good case to use the Proxy pattern, and more specifically whether a good case to use the Java Dynamic Proxy API.

BACKGROUND
We have a "FIXConnection" class used to send orders to a destination. The application maintains 1 to n FIXConnections for sending (a specific object is selected based on what the user specified on the order).

Normally, the order would be sent straight out to the market. The enhancement is to see whether order could be filled by other orders already sent to market before sending, and if it can be filled, execute totally different logic (i.e. not send). If not, it delegates to current logic.

This feature will only be used by one client, so it is turned on/off dynamically (or by configuration setting).

It feels like this is a good use for the Proxy pattern/Dynamic Proxy, because it would allow designing a block of code to intercept requests to the existing FIXConnection.send method (and also its processResponse method), only in the case whether the feature is enabled. The Proxy could either execute the new logic (if warranted), or dispatch to existing logic.

PROS AND CONS
PRO

  • Using Proxy avoids any issues with Class hierarchy (we occasionally subclass this FIXConnection class). If we handled this by subclass, then other children might need to be moved to this under this as a parent.

  • We don't need to update the existing top level class with any flag to check if this feature is enabled, and to conditionally execute code. (i.e. not create code for one special case, which would now be hit by all cases).

  • Single point of control

CON

  • Existing class exposes public variables, all would need to be refactored into getter/setter methods, and need to extract an interface (so that Dynamic Proxy could be used). i.e. a ripple throughout other classes.

  • Binding between the proxy and legacy method could be a little cheesy (e.g. method.getName().equals("send"). There are ways of more tightly binding, but … (yuck?)

  • Is this making things unnecessarily complicated? In general I try to subscribe to doing "the simplest thing that could work". This doesn't quite feel like it.

Would love to hear anyone's thoughts about how they might handle this design question.

Best Answer

The big thing here is what are the chances you'll need to do this for other clients? If the odds of any other client using this are low to nil, refactoring may be a lot of time and effort for something with very minor impact. However, if you think this could be an enhancement you'll be making for more clients, I would go ahead and make the change to the code.

If you do refactor, I think the Strategy pattern is a better fit for this particular situation. It sounds like you're not so much looking for an object to operate in place of another object so much as you're looking to alter the server's behavior based on the specific situation. Clients (I'm assuming at this point that ultimately this will be used by more than 1 client) that would use this enhancement would use a strategy that checks existing orders before sending out a new order, other clients would use a strategy that always sends orders to market. As clients start to use this feature, they use the appropriate strategy with minimal changes on your part.

Related Topic