7

I have a system I've been working on this week where I'm having a hard time balancing separation of concerns with easy extensibility. I'm adding new types to the system, and it feels like shotgun surgery.

The basic idea is that data is collected (polled) from a remote system and then made available to a number of different kinds of clients. To support their interface type (protocol), I'm doing a lot of translation.

I'm going to try to simplify this so I can fit it in a question box.

There's a FruitService out in the world with an SNMP interface. My publisher's job is to collect that data and then publish it.

  1. So for each kind of new Fruit we decide to publish, I create a class that knows how to pull the attributes for that fruit via SNMP.
  2. Internally Fruit is translated to DTOs (the same objects used to talk to client #1 (RMI)).
  3. A cache is updated and checked for changes to trigger async notifications.
  4. A class to translate the fruit into the xml schema used by another client (#2).
  5. A class to translate the fruit into simple attribute/value pairs used by another client (#3).

In the end I create 5 classes and edit 8 more to plug in a new type. It's not a lot of work; couple hours to write code, test, and check-in for a simple type. Note that there isn't a lot of commonality in the fruit types (e.g.: pear and coconut), so most of the common abstractions are based around the process of updating the data and not the data itself.

My design concerns are:

  1. The SNMP interface changes 2-3 times a year
  2. The xml schema (client 2) changes 10 times a year.
  3. Adding new types happens less frequently, generally when someone gets around to it. But maybe if it was easier...

So the notional goal with the design was to handle those external changes easily. This lead to all the separation in the translation layers. But adding types feels harder than I'd like.

Is there a technique or example I might look into? An idea I'm missing? Am I applying SRP wrong and there should be an Apple type that speaks SNNP, xml schema, DTO, etc?

alt text

EDIT:

Client #1, the RMI client, is custom written when a new fruit is added, to take advantage of all the fruit's capabilities. So if we decide to pull banana information from the FruitService we will also write a client that allows you to peel the banana, get a notification when it's ripe, and tell you which bunch it belongs to - along with the basic fruit attributes like size, weight, color, time till rotten, etc.

3
  • One thing that isn't clear to me from the question - how much of creating these new classes is entirely mechanically algorithmic and how much do you have to actually write original stuff for? Because code generation might be a solution, or perhaps even something more dynamic but it does sound like you want strong types and might not be able to do that dynamically. This isn't an answer because I can't tell from the question if this makes sense for you.
    – psr
    Commented Feb 10, 2012 at 17:33
  • @psr - I do want strong types. Does my edit help? The mechanical parts (and code reuse) is all surrounding how the data is updated and handled, not in the fruit-specific concerns. Commented Feb 10, 2012 at 17:44
  • So it sounds like it would be possible to write code that generates all the strongly typed classes automatically - except for client #1, and that this would cut down the effort of using a new service? If so I'll move that from comments to an answer, though unfortunately I doubt I'll come with anything more useful to say in the process.
    – psr
    Commented Feb 10, 2012 at 18:21

1 Answer 1

1

My first impression is that your design needs some refactoring to be more object oriented. You have different types for different structures, however the behaviour is important. If it is possible rather than creating new Fruit type, describe generic Fruit structure and create objects for concrete Fruit. This way you can include behaviour which will describe the structure in Fruit and create generic translation classes, which will just use the information about the structure to create the 8 objects you need when you add new fruit type. This could be done also using metaprogramming, but depends on your language and skills and effort needed to create something like that.

So the idea is to translate Coconut.getMilk() and Pear.getSeeds() into Fruit.getAttributes() and so on. Does this help a bit?

1
  • It really depends on the client. Two of them are interested in just displaying some information about generic fruit. One is interested in only Pears and wants to see every possible detail about that pear without any information about coconuts. What I think you're describing is essentially what's done in my translation layers for client #2 and #3, but client #1 benefits from a pear-specific object with pear-specific domain concerns. Commented Sep 10, 2010 at 11:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.