3
\$\begingroup\$
public interface ICacheable<TK,TV>
{
   TV Get(TK key);
   void Add(TK key, TV val);
}

public abstract class BaseCache<TK, TV>
{
    protected static Dictionary<Guid, Dictionary<TK, TV>> data = new Dictionary<Guid, Dictionary<TK, TV>>();
    private Guid StorageNameSpage;

    protected BaseCache(Guid storageNameSpage)
    {
        StorageNameSpage = storageNameSpage;
    }

    protected BaseCache()
    {
        StorageNameSpage = Guid.NewGuid();
    } 



    public TV Get(TK key)
    {
        return data[StorageNameSpage][key];
    }

    public void Add(TK key, TV val)
    {
        data.Add(....);
     }
}

2 different ways to implement it:

"mulityTon" or what ever you want to call it.

public class KeyValCacheStorage<TK, TV> : BaseCache<TK, TV>, ICacheable<TK, TV>
{

}

SingleTome

public class KeyValCacheStorageSingleTon<TK, TV> : BaseCache<TK, TV>, ICacheable<TK, TV>
{
    private static Guid storageNameSpage = Guid.NewGuid();
    public KeyValCacheStorageSingleTon():base(storageNameSpage)
    {

    }
}

usage:

KeyValCacheStorageSingleTon<string, string> storageSingleTon1 = new KeyValCacheStorageSingleTon<string, string>();
storageSingleTon1.Add("storageSingleTon1", "KeyValCacheStorageSingleTon");
storageSingleTon1.Add("bla", "yada");

KeyValCacheStorageSingleTon<string, string> storageSingleTon2 = new KeyValCacheStorageSingleTon<string, string>();
storageSingleTon2.Add("storageSingleTon2", "KeyValCacheStorageSingleTon2");
\$\endgroup\$
1
  • 1
    \$\begingroup\$ How is this better than having a private static dictionary elsewhere? The dictionary gives you a lot of functionality, such as it can tell you whether a key exists, it can participate in a LINQ query, etc. etc. I would rather write an algorithm against an IDictionary than ICacheable interface. \$\endgroup\$
    – Leonid
    Mar 19, 2012 at 15:30

2 Answers 2

4
\$\begingroup\$

So I've made a few modifications; here are the explanations:

  • Used interfaces a bit more liberally (IDictionary)
  • Made BaseClass implement ICacheable so the subclasses don't explicitly have to
  • Made fields readonly as appropriate to declare intent
  • Made field data private and exposed as protected by way of a property
  • Chained the BaseCache constructors
  • Created the storage dictionary in the constructor (could do this in Add if you were looking for lazy creation)
  • sealed subclasses (if they're intended to be non-inheritable, of course)

The code:

public interface ICacheable<TK, TV>
{
    TV Get(TK key);

    void Add(TK key, TV val);
}

public abstract class BaseCache<TK, TV> : ICacheable<TK, TV>
{
    private static readonly IDictionary<Guid, IDictionary<TK, TV>> data = new Dictionary<Guid, IDictionary<TK, TV>>();

    private readonly Guid storageNameSpace;

    protected BaseCache(Guid storageNameSpace)
    {
        this.storageNameSpace = storageNameSpace;
        data[this.storageNameSpace] = new Dictionary<TK, TV>();
    }

    protected BaseCache() : this (Guid.NewGuid())
    {
    }

    protected static IDictionary<Guid, IDictionary<TK, TV>> Data
    {
        get
        {
            return data;
        }
    }

    public TV Get(TK key)
    {
        return data[this.storageNameSpace][key];
    }

    public void Add(TK key, TV val)
    {
        data[this.storageNameSpace].Add(key, val);
    }
}

public sealed class KeyValCacheStorage<TK, TV> : BaseCache<TK, TV>
{
}

public sealed class KeyValCacheStorageSingleton<TK, TV> : BaseCache<TK, TV>
{
    private static readonly Guid storageNameSpace = Guid.NewGuid();

    public KeyValCacheStorageSingleton() : base(storageNameSpace)
    {
    }
}
\$\endgroup\$
3
\$\begingroup\$

One comment on the code: you will find your constructors easier to maintain if you use constructor chaining

protected BaseCache() : this(Guid.NewGuid() ) { }

Now my possibly ignorant comments on other things.

  • The usage is almost identical to Dictionary<K,V> why would I not just use a static instance of a dictionary?
  • Are you sure that a single multidimensional dictionary actually preforms better than different instances of a regular dictionary? Have you done profiling on this? It seems to me unlikely (I use that in a snark-free sense, it seems unlikely but I don't know)
  • There's like a 192732981923 different cache implementations already out there. Why not use one of those?
  • When is this cache cleared? I don't see any options about that. That is the more interesting part of any caching API.
  • The interface is similar to IDictionary<K,V> but not quite the same. This might subtly break expectations. I don't think you'd loose anything in just implementing that interface.
\$\endgroup\$
2
  • \$\begingroup\$ Thanks, 1. Because you have a singleTon mechanism "for free" 2. no, but from what I read its the same. 3. yea I know, each of everyone who wrote them has the right to start a new one, like myself. 4. yes, I added that. 5. more complex. thank you \$\endgroup\$
    – sexyMF
    Mar 19, 2012 at 14:05
  • \$\begingroup\$ @sexyMF Yes you can of course implement your own, I was more wondering what requirement drove you to that and if there's another way to address it. I don't know what you mean by getting a static mechanism for free. The only difference seems to be that you don't have to write the word 'static'? \$\endgroup\$ Mar 19, 2012 at 14:48

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.