views:

79

answers:

4

In class library I am currently working on, I need to implement a mechanism in which class users will get hold of an item by operating on an Issuer class:

class Issuer {
    public Item GetItem () {
        return queue.Pop ();
    }
}

//at some other place
var item = issuer.GetItem ();
//work on item and submit back to Issuer

How can I implement this pattern which minimizes the risk that user of the class doesn't even bother to submit it back?

My order of preference would be:

  • Class user doesn't have to explicitly submit it back
  • Class user has to explicitly submit it back but it is not possible to get away without submitting (exceptions???)
  • It is possible to even get away without submitting it back but the design encourage user not to do it

I know it is not a crystal clear question but any suggestions/design-pattern to implement above would be helpful!

+2  A: 

Maintain a collection of issued Items, perhaps storing when they were issued and the class they were issued to. That way you don't have to explicitly resubmit the item. Resubmitting removes from the issued collection obviously. You then have the option of throwing exceptions based on 'dirty' data in a number of ways if the issued collection still has items in. You could:

  • handle events from the requesting class if you stored that for example form closing events
  • periodically throw an excpetion for all items older than x
  • if the number of outstanding items goes above a certain threshold

One thing I would say is perhaps look into a static issuer rather than have it as an instance method.

Chris
Actually, that's pretty elegant. If he wants to enforce all items getting returned, then at the process end throw a custom exception if the issued count is greater than zero.
emptyset
+2  A: 

One way of doing this would be using the IDisposable interface. This way, users could possibly take advantage of the using statement during usage:

using (var item = issuer.GetItem())
{
    // Work on item
} // Item is released on Dispose()

The issuer could simply listen to an event to get the item back. However, if the item gets passed around, it might not be your best bet. In this case, a simple Close() or Release() method (again with the issuer listening on an event) might just do the trick.

In most cases, it's best that users explicitly - in some way - release the acquired item.

If some inconsiderate user omits to release an item, you could always fall back on the Finalizer along with the standard Dispose pattern. However, you must be very careful not to resurrect the item (keeping a reference once it's finalized).

Bryan Menard
Thanks. I like the tip of using Dispose pattern but unfortunately the usage of item is likely to spread across multiple methods. Your suggestion to listen to event might be useful. Should I force the users to implement an interface which has an event I can listen to?
Hemant
Declaring an event such as `Closed` or `Released` on Item (invoked when `Close()` or `Release()`) is called by the user will suffice. The user won't be constrained to implement anything. Issuer would listen to those event and *regain control* on the item.
Bryan Menard
I really don't know why I insisted on Close and Release; It could have easily been Sumbit!
Bryan Menard
+2  A: 
Jeremy McGee
Thanks for answer (it is interesting really) but there will be only one instance of Issuer in application. A single source of items. Any more suggestions....
Hemant
As I mentioned in my answer considering making it static then if there can only be one Issuer - it prevents issues with accidental occurances of multiple issuers
Chris
Yes, a singleton here would be a good idea.
Jeremy McGee
A: 

Hey,

Use an event to let the Issuer know that an item was gotten and pass it back to the Issuer using an event.

Tony

Tony