• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Programming to interface but need access to implementation for persistence

 
Ranch Hand
Posts: 65
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello,

My program has domain objects which are persisted through a corresponding DAO object. I'm also trying to "program to interface" rather than implementation as much as possible but getting a little stuck so I'd like some advice please!

I have something like the following interface (lots of methods removed to create example):


I have an implementation of this interface called AgentImpl. The internal data has other attributes that aren't part of the business interface, such as the current optimistic locking version number. I'd prefer not to contaminate the business interface with these details.

My AgentDAO interface looks like the following:



The DAO interface works with the Agent interface, and not the implementation of the Agent.

My issue is, when implementing the AgentDAO.saveAgent(Agent agent) method, I need access to the optimistic locking version number, and it would be advantageous to have access to the implementation so the persistence code can access the containers more directly for efficiency, rather than the more stable (and potentially slower) business methods. This means that I have to do casting in saveAgent() method, or introduce a special method on Agent interface to get the implementation.

In essence, my problem can be boiled down to:
1) Implementation object is created.
2) Interface returned so the implementation is hidden.
3) Later on the implementation is required again. The dilemma appears to be either:
  • casting or providing access to implementation via interface.
  • extending (and dirtying) the the business interface.


  • Hopefully someone can come to my rescue with some advice on this!

    Thanks,

    Ed
     
    Ranch Hand
    Posts: 132
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Hi Edward,

    I've read your description twice and perhaps I've an idea how you can still use your interface (and not your implementation) in the class AgentDAO. My idea is based on the decorator pattern which provides additional behavior for a class. If you don't know the pattern you can think of an wrapper object.

    I'm not sure if this will work for you, but I would think about the following required steps:
    1) Create a new class AgentWrapper which tooks an Agent in its constructor and provides the same methods as the interface do. A lot of this wrapper does is delegating to the Agent interface/instance. The new thing/behavior which this Wrapper provide is the threading/locking stuff.
    2) Remove the existing threading/locking stuff from your class AgentImpl. You don't need it there, because you 've now the wrapper class AgentWrapper for this stuff.
    3) In your DAO class you work still with the Agent interface. If there are methods which need locking-functionality then you put your Agent instance in the AgentWrapper class which will provide the new behavior.

    Best regards,
    Christian
     
    Christian Nicoll
    Ranch Hand
    Posts: 132
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    I just get another idea, which doesn't not 've to be better, but which is perhaps more pragmatically.

    What happens if you just create another interface for example AgentExtended which is extended from your existing interface Agent and would add the specific methods like locking stuff? In your class AgentImpl you would implement the interface AgentExtended and not Agent. In your DAO you can still work with the Agent interface because AgentExtended would extend all the methods from agent. At the specific methods were you need extended stuff you are casting your Agent interface into a AgentExtended interface.
     
    Saloon Keeper
    Posts: 27763
    196
    Android Eclipse IDE Tomcat Server Redhat Java Linux
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    I'm having a hard time following this. All I do is go ahead and try and save and catch the OptimisticLockingException if if comes up. No need for specialized overhead. If I've been well-behaved, the operation succeeds. Otherwise, it's Management By Exception, and it's reasonable that exceptional cases require more work than the common ones.

    On the other hand, if multiple concurrent modifications are going to be the rule rather than the exception, I'd recommend designing specifically for that problem. The traditional approach is to obtain a (pessimistic) lock, and work with a single copy of that record. You could cache that copy and present it to local app users so they don't end up making conflicting mods (and note that EJB in particular was designed to synchronize access to bean properties). If you have a mutiple-server situtation, you're better off coughing up cash for a coherent cache such as Tangesol.

    In all of the above situations there's no real reason to acquire the underlying object implementation, and some good reasons not to. However, in a pinch, casting is the best solution.

    Do realize that there's probably 40 years of real-world experience been laid up by some big names working on some really high-performance systems, and it's better to look at Best Practices than to cook up some one-off solution if you can. Custom solutions are expensive to develop, debug and maintain, with their "real" cost often exceeding what the commercial solutions cost. You have fewer support options as well. If it fails, the person the boss calls up and yells at is probably going to be you. Not meaning that a purchased solution is necessarily the way to go, but at least follow proven paths. I have a very good book in my possession that's entirely dedicated to transaction management in Java, including in an XA environment.
     
    Ranch Hand
    Posts: 2187
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator



     
    Edward Winchester
    Ranch Hand
    Posts: 65
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Thanks for everyone who tried to understand my ramblings and responded!

    I think I'm a little clearer on this now and will include the optimistic locking version number (and whatever other details are necessary for the DAO to save the entity) in the interface as Frank suggested.

    Another way forward is to make the DAOs work with the concrete implementation of the things it's persisting. I can still have interfaces which are used elsewhere - i.e. the concrete object is passed to a business method to do some work, and that method accepts an interface. When the method completes, I still have the concrete object to be saved via the DAO.

    Regards,

    Ed
     
    reply
      Bookmark Topic Watch Topic
    • New Topic