\$\begingroup\$
\$\endgroup\$
1
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");
-
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– Leonid2012年03月19日 15:30:02 +00:00Commented Mar 19, 2012 at 15:30
2 Answers 2
\$\begingroup\$
\$\endgroup\$
So I've made a few modifications; here are the explanations:
- Used interfaces a bit more liberally (
IDictionary
) - Made
BaseClass
implementICacheable
so the subclasses don't explicitly have to - Made fields
readonly
as appropriate to declare intent - Made field
data
private
and exposed asprotected
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)
{
}
}
answered Mar 19, 2012 at 16:11
\$\begingroup\$
\$\endgroup\$
2
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.
answered Mar 19, 2012 at 13:37
-
\$\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– sexyMF2012年03月19日 14:05:04 +00:00Commented 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\$George Mauer– George Mauer2012年03月19日 14:48:12 +00:00Commented Mar 19, 2012 at 14:48
lang-cs