I have a generic factory which caches an instance before return it (simplified code):
static class Factory<T>
where T : class
{
private static T instance;
public static T GetInstance()
{
if (instance == null) instance = new T();
return instance;
}
}
I want to replace such approach with non-caching one to show that caching makes no sense in matters of instantiation performance (I believe new object creation is very cheap).
So I want to write a load test which will create a deal, say 1000, of dynamic, runtime-only types and load it to my factories. One will cache, and another - will not.
Here's my two cents although I agree with jgauffin's and Daniel Hilgarth's answers. Using generic type caching using a static member in this way would intuitively create additional parallel types per type that is cached but it is important to understand how this works differently for reference and value types. For reference types as T the additional generic types produced should use less resources than would an equivalent usage of a value type.
So when should you use the generic type technique for producing a cache? Below are a few important criteria that I use.
1. You want to allow caching single instances of each class of interest.
2. You would like to use compile time generic type constraints to enforce rules on the types used in the cache. With type constraints you can enforce the need for an instance to implement several interfaces without having to define a base type for those classes.
3. You don't need to remove items from the cache for the lifetime of the AppDomain.
By the way one term that may be useful to search on is "Code Explosion" which is a general term used to define cases where a considerable amount of code is needed to perform some regularly occurring task and that generally grows linearly or worse with the growth of project requirements. In terms of generic types, I've heard and will generally use the term "type explosion" to describe the proliferation of types as you begin to combine and compose several generic types.
Another important point is that in these cases a factory and the cache can always be separated and in most cases they can be given an identical interface which would allow you to substitute the factory (new instance per call) or the cache which essentially wraps the factory and delegates through the same interface in cases where you want to use one or the other depending on things such as type explosion concerns. Your cache could also take on more responsibility such as a more sophisticated caching strategy where perhaps particular types are cached differently (ex. reference types vs. value types). If your curious about this the trick is to define your generic class that does the caching as a private class within the actual concrete type that implements the interface for your factory. I can give an example if you would like.
Update with example code as requested:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
namespace CacheAndFactory
{
class Program
{
private static int _iterations = 1000;
static void Main(string[] args)
{
var factory = new ServiceFactory();
// Exercise the factory which implements IServiceSource
AccessAbcTwoTimesEach(factory);
// Exercise the generics cache which also implements IServiceSource
var cache1 = new GenericTypeServiceCache(factory);
AccessAbcTwoTimesEach(cache1);
// Exercise the collection based cache which also implements IServiceSource
var cache2 = new CollectionBasedServiceCache(factory);
AccessAbcTwoTimesEach(cache2);
Console.WriteLine("Press any key to continue");
Console.ReadKey();
}
public static void AccessAbcTwoTimesEach(IServiceSource source)
{
Console.WriteLine("Excercise " + source.GetType().Name);
Console.WriteLine("1st pass - Get an instance of A, B, and C through the source and access the DoSomething for each.");
source.GetService<A>().DoSomething();
source.GetService<B>().DoSomething();
source.GetService<C>().DoSomething();
Console.WriteLine();
Console.WriteLine("2nd pass - Get an instance of A, B, and C through the source and access the DoSomething for each.");
source.GetService<A>().DoSomething();
source.GetService<B>().DoSomething();
source.GetService<C>().DoSomething();
Console.WriteLine();
var clock = Stopwatch.StartNew();
for (int i = 0; i < _iterations; i++)
{
source.GetService<A>();
source.GetService<B>();
source.GetService<C>();
}
clock.Stop();
Console.WriteLine("Accessed A, B, and C " + _iterations + " times each in " + clock.ElapsedMilliseconds + "ms through " + source.GetType().Name + ".");
Console.WriteLine();
Console.WriteLine();
}
}
public interface IService
{
}
class A : IService
{
public void DoSomething() { Console.WriteLine("A.DoSomething(), HashCode: " + this.GetHashCode()); }
}
class B : IService
{
public void DoSomething() { Console.WriteLine("B.DoSomething(), HashCode: " + this.GetHashCode()); }
}
class C : IService
{
public void DoSomething() { Console.WriteLine("C.DoSomething(), HashCode: " + this.GetHashCode()); }
}
public interface IServiceSource
{
T GetService<T>()
where T : IService, new();
}
public class ServiceFactory : IServiceSource
{
public T GetService<T>()
where T : IService, new()
{
// I'm using Activator here just as an example
return Activator.CreateInstance<T>();
}
}
public class GenericTypeServiceCache : IServiceSource
{
IServiceSource _source;
public GenericTypeServiceCache(IServiceSource source)
{
_source = source;
}
public T GetService<T>()
where T : IService, new()
{
var serviceInstance = GenericCache<T>.Instance;
if (serviceInstance == null)
{
serviceInstance = _source.GetService<T>();
GenericCache<T>.Instance = serviceInstance;
}
return serviceInstance;
}
// NOTE: This technique will cause all service instances cached here
// to be shared amongst all instances of GenericTypeServiceCache which
// may not be desireable in all applications while in others it may
// be a performance enhancement.
private class GenericCache<T>
{
public static T Instance;
}
}
public class CollectionBasedServiceCache : IServiceSource
{
private Dictionary<Type, IService> _serviceDictionary;
IServiceSource _source;
public CollectionBasedServiceCache(IServiceSource source)
{
_serviceDictionary = new Dictionary<Type, IService>();
_source = source;
}
public T GetService<T>()
where T : IService, new()
{
IService serviceInstance;
if (!_serviceDictionary.TryGetValue(typeof(T), out serviceInstance))
{
serviceInstance = _source.GetService<T>();
_serviceDictionary.Add(typeof(T), serviceInstance);
}
return (T)serviceInstance;
}
private class GenericCache<T>
{
public static T Instance;
}
}
}
Basically to summarize, the code above is a console app that has the concept of an interface to provide for an abstraction of a service source. I used an IService generic constraint just to show an example of how it could matter. I don't want to type or post 1000 separate type definitions so I did the next best thing and created three classes - A, B, and C - and accessed them each 1000 times using each technique - repetitive instantiation, generic type cache, and collection based cache.
With a small set of accesses the difference is negligible but of course my service constructor is simplistic (default parameterless constructor) so it does not calculate anything, access a database, access configuration or any of the things that typical service classes do when they are constructed. If this were not the case then the benefits of some caching strategy is obviously going to be beneficial for performance. Also when accessing even the default constructor in the caes where there are 1,000,000 accesses there is still a dramatic difference between not caching and caching (3s : 120ms) so the lesson is that if you are doing high volume accesses or complex calculations that require frequent access through the factory then caching will be not only beneficial but verging on a necessity depending on whether it impacts user perception or time sensitive business processes otherwise the benefits are negligible. The important thing to remember is that it's not just instantiation time that you have to worry about but also the load on the Garbage collector.
Sounds to me that your colleague want's to do premature optimizations. Caching objects are seldom a good idea. Instantiation is cheap and I would only cache objects where it's proven that it will be faster. A high performance socket server would be such case.
But to answer your question: Caching objects will always be faster. Keeping them in a LinkedList or something like that will keep the overhead small and performance should not decrease as the number of objects grow.
So if you are willing to accept larger memory consumption and increased complexity, go for a cache.
Related
I am doing a refactor over certain code.
We have a list of investors with amounts assigned to each. The total of amounts should be equal to another total, but sometimes there are a couple of cents of difference, so we use different algorithms to assign these differences to each investor.
The current code is something like this:
public void Round(IList<Investors> investors, Enum algorithm, [here goes a list of many parameters]) {
// some checks and logic here - OMMITED FOR BREVITY
// pick method given algorithm Enum
if (algoritm == Enum.Algorithm1) {
SomeStaticClass.Algorithm1(investors, remainders, someParameter1, someParameter2, someParameter3, someParameter4)
} else if (algoritm == Enum.Algorithm2) {
SomeStaticClass.Algorithm2(investors, remainders, someParameter3)
}
}
so far we only have two algorithms. I have to implement the third one. I was given the possibility to refactor both existing implementations as well as do some generic code to make this function for future algorithms, maybe custom to each client.
My first thought was "ok, this is a strategy pattern". But the problem I see is that both algorithms receive a different parameter list (except for the first two). And future algorithms can receive a different list of parameters as well. The only thing in "common" is the investor list and the remainders.
How can I design this so I have a cleaner interface?
I thought of
Establishing an interface with ALL possible parameters, and share it
among all implementations.
Using an object with all possible parameters as properties, and use that generic object as part of the interface. I
would have 3 parameters: The list of investors, the remainders object, and a "parameters" object. But in this case, I have a similar problem. To instantiate each object and fill the required properties depends on the algorithm (unless I set all of them). I
would have to use a factory (or something) to instantiate it, using all parameters in the interface, am I right? I would be moving the problem of too many parameters to that "factory" or whatever.
Using a dynamic object instead of a statically typed object. Still
presents the same problems as before, the instantiation
I also thought of using the Visitor Pattern, but as I understand, that would be the case if I had different algorithms for different entities to use, like, another class of investors. So I don't think it is the right approach.
So far the one that convinces me the most is the second, although I am still a bit reticent about it.
Any ideas?
Thanks
Strategy has different implementations. Its straightforward when all alternate Concrete Strategies require same type signature. But when concrete implementations start asking for different data from Context, we have to gracefully take a step back by relaxing encapsulation ("breaking encapsulation" is known drawback of strategy), either we can pass Context to strategies in method signature or constructor depending upon how much is needed.
By using interfaces and breaking big object trees in to smaller containments we can restrict the access to most of the Context state.
following code demonstrates passing through method parameter.
public class Context {
private String name;
private int id;
private double salary;
Strategy strategy;
void contextInterface(){
strategy.algorithmInterface(this);
}
public String getName() {
return name;
}
public int getId() {
return id;
}
public double getSalary() {
return salary;
}
}
public interface Strategy {
// WE CAN NOT DECIDE COMMON SIGNATURE HERE
// AS ALL IMPLEMENTATIONS REQUIRE DIFF PARAMS
void algorithmInterface(Context context);
}
public class StrategyA implements Strategy{
#Override
public void algorithmInterface(Context context) {
// OBSERVE HERE BREAKING OF ENCAPSULATION
// BY OPERATING ON SOMEBODY ELSE'S DATA
context.getName();
context.getId();
}
}
public class StrategyB implements Strategy{
#Override
public void algorithmInterface(Context context) {
// OBSERVE HERE BREAKING OF ENCAPSULATION
// BY OPERATING ON SOMEBODY ELSE'S DATA
context.getSalary();
context.getId();
}
}
Okay, I might be going in the wrong direction... but it seems kinda weird that you're passing in arguments to all the algorithms, and the identifier to which algorithm to actually use. Shouldn't the Round() function ideally just get what it needs to operate?
I'm imagining the function that invokes Round() to look something like:
if (something)
algToUse = Enum.Algorithm1;
else
if (otherthing)
algToUse = Enum.Algorithm2;
else
algToUse = Enum.Algorithm3;
Round(investors, remainder, algToUse, dayOfMonth, lunarCycle, numberOfGoblinsFound, etc);
... what if, instead, you did something like this:
public abstract class RoundingAlgorithm
{
public abstract void PerformRounding(IList<Investors> investors, int remainders);
}
public class RoundingRandomly : RoundingAlgorithm
{
private int someNum;
private DateTime anotherParam;
public RoundingRandomly(int someNum, DateTime anotherParam)
{
this.someNum = someNum;
this.anotherParam = anotherParam;
}
public override void PerformRounding(IList<Investors> investors, int remainder)
{
// ... code ...
}
}
// ... and other subclasses of RoundingAlgorithm
// ... later on:
public void Round(IList<Investors> investors, RoundingAlgorithm roundingMethodToUse)
{
// ...your other code (checks, etc)...
roundingMethodToUse.Round(investors, remainders);
}
... and then your earlier function simply looks like:
RoundingAlgorithm roundingMethod;
if (something)
roundingMethod = new RoundingByStreetNum(1, "asdf", DateTime.Now);
else
if (otherthing)
roundingMethod = new RoundingWithPrejudice(null);
else
roundingMethod = new RoundingDefault(1000);
Round(investors, roundingMethod);
... basically, instead of populating that Enum value, just create a RoundingAlgorithm object and pass that in to Round() instead.
I am in the process of refactoring a rather large portion of spaghetti code. In a nutshell it is a big "God-like" class that branches into two different processes depending in some condition. Both processes are lengthy and have lots of duplicated code.
So my first effort has been to extract those two processes into their own classes and putting the common code in a parent they both inherit from.
It looks something like this:
public class ExportProcess
{
public ExportClass(IExportDataProvider dataProvider, IExporterFactory exporterFactory)
{
_dataProvider = dataProvider;
_exporterFactory = exporterFactory;
}
public void DoExport(SomeDataStructure someDataStructure)
{
_dataProvider.Load(someDataStructure.Id);
var exporter = _exporterFactory.Create(_dataProvider, someDataStructure);
exporter.Export();
}
}
I am an avid reader of Mark Seemann's blog and in this entry he explains that this code has a temporal coupling smell since it is necessary to call the Load method on the data provider before it is in a usable state.
Based on that, and since the object is being injected to the ones returned by the factory anyway, I am thinking of changing the factory to do this:
public IExporter Create(IExportDataProvider dataProvider, SomeDataStructure someDataStructure)
{
dataProvider.Load(someDataStructure.Id);
if(dataProvider.IsNewExport)
{
return new NewExportExporter(dataProvider, someDataStructure);
}
return new UpdateExportExporter(dataProvider, someDataStructure);
}
Because of the name "DataProvider" you probably guessed that the Load method is actually doing a database access.
Something tells me an object doing a database access inside the create method of an abstract factory is not a good design.
Are there any guidelines, best practices or something that say this is effectively a bad idea?
Thanks for your help.
Typically, a factory is used to resolve concrete types of a requested interface or abstract type, so you can decouple consumers from implementation. So usually a factory is just going to discover or specify the concrete type, help resolve dependencies, and instantiate the concrete type and return it. However, there's no hard or fast rule as to what it can or can't do, but it is sensible to give it enough access to only to resources that it needs to resolve and instantiate concrete types.
Another good use of a factory is to hide from consumers types dependencies that are not relevant to the consumer. For example, it seems IExportDataProvider is only relevant internally, and can be abstracted away from consumers (such as ExportProcess).
One code smell in your example, however, is how IExportDataProvider is used. The way it currently seems to work, you get an instance of it once, but it's possible to change its state in subsequent usages (by calling Load). This can lead to issues with concurrency and corrupted state. Since I don't know what that type does or how it's actually used by your IExporter, it's hard to make a recommendation. In my example below, I make an adjustment so that we can assume that the provider is stateless, and instead Load returns some sort of state object that the factory can use to resolve the concrete type of exporter, and then provide data to it. You can adjust that as you see fit. On the other hand, if the provider has to be stateful, you'll want to create an IExportDataProviderFactory, use it in your exporter factory, and create a new instance of the provider from the factory for each call to exporter factory's Create.
public interface IExporterFactory
{
IExporter Create(SomeDataStructure someData);
}
public class MyConcreteExporterFactory : IExporterFactory
{
public MyConcreteExporterFactory(IExportDataProvider provider)
{
if (provider == null) throw new ArgumentNullException();
Provider = provider;
}
public IExportDataProvider Provider { get; private set; }
public IExporter Create(SomeDataStructure someData)
{
var providerData = Provider.Load(someData.Id);
// do whatever. for example...
return providerData.IsNewExport ? new NewExportExporter(providerData, someData) : new UpdateExportExporter(providerData, someData);
}
}
And then consume:
public class ExportProcess
{
public ExportProcess(IExporterFactory exporterFactory)
{
if (exporterFactory == null) throw new ArgumentNullException();
_exporterFactory = factory;
}
private IExporterFactory _exporterFactory;
public void DoExport(SomeDataStructure someData)
{
var exporter = _exporterFactory.Create(someData);
// etc.
}
}
I'll begin this question with apologizing for the length of the post. So that I save you some time, my problem is that the class pattern I've got stuck in my head is obviously flawed, and I can't see a good solution.
In a project I'm working on, I need to use operate algorithms on a chunks of data, let's call them DataCache. Sometimes these algorithms return results that themselves need to be cached, and so I devised a scheme.
I have an Algorithm base class that looks like so
abstract class Algorithm<T>
{
protected abstract T ExecuteAlgorithmLogic(DataCache dataCache);
private readonly Dictionary<DataCache, WeakReference> _resultsWeak = new Dictionary<DataCache, WeakReference>();
private readonly Dictionary<DataCache, T> _resultsStrong = new Dictionary<DataCache, T>();
public T ComputeResult(DataCache dataCache, bool save = false)
{
if (_resultsStrong.ContainsKey(dataCache))
return _resultsStrong[dataCache];
if (_resultsWeak.ContainsKey(dataCache))
{
var temp = _resultsWeak[dataCache].Target;
if (temp != null) return (T) temp;
}
var result = ExecuteAlgorithmLogic(dataCache);
_resultsWeak[dataCache] = new WeakReference(result, true);
if (save) _resultsStrong[dataCache] = result;
return result;
}
}
If you call ComputeResult() and provide a DataCache you can optionally select to cache the result. Also, if you are lucky result still might be there if the GC hasn't collected it yet. The size of each DataCache is in hundreds of megabytes, and before you ask there are about 10 arrays in each, which hold basic types such as int and float.
My idea here was that an actual algorithm would look something like this:
class ActualAgorithm : Algorithm<SomeType>
{
protected override SomeType ExecuteAlgorithmLogic(DataCache dataCache)
{
//Elves be here
}
}
And I would define tens of .cs files, each for one algorithm. There are two problems with this approach. Firstly, in order for this to work, I need to instantiate my algorithms and keep that instance (or the results are not cached and the entire point is mute). But then I end up with an unsightly singleton pattern implementation in each derived class. It would look something like so:
class ActualAgorithm : Algorithm<SomeType>
{
protected override SomeType ExecuteAlgorithmLogic(DataCache dataCache)
{
//Elves and dragons be here
}
protected ActualAgorithm(){ }
private static ActualAgorithm _instance;
public static ActualAgorithm Instance
{
get
{
_instance = _instance ?? new ActualAgorithm();
return _instance;
}
}
}
So in each implementation I would have to duplicate code for the singleton pattern. And secondly tens of CS files also sounds a bit overkill, since what I'm really after is just a single function returning some results that can be cached for various DataCache objects. Surely there must be a smarter way of doing this, and I would greatly appreciate a nudge in the right direction.
What I meant with my comment was something like this:
abstract class BaseClass<K,T> where T : BaseClass<K,T>, new()
{
private static T _instance;
public static T Instance
{
get
{
_instance = _instance ?? new T();
return _instance;
}
}
}
class ActualClass : BaseClass<int, ActualClass>
{
public ActualClass() {}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine(ActualClass.Instance.GetType().ToString());
Console.ReadLine();
}
}
The only problem here is that you'll have a public constructor.
I refined my previous answer but as it is rather different than the other approach I proposed, I thought I might just make another answer. First, we'll need to declare some interfaces:
// Where to find cached data
interface DataRepository {
void cacheData(Key k, Data d);
Data retrieveData(Key k, Data d);
};
// If by any chance we need an algorithm somewhere
interface AlgorithmRepository {
Algorithm getAlgorithm(Key k);
}
// The algorithm that process data
interface Algorithm {
void processData(Data in, Data out);
}
Given these interfaces, we can define some basic implementation for the algorithm repository:
class BaseAlgorithmRepository {
// The algorithm dictionnary
Map<Key, Algorithm> algorithms;
// On init, we'll build our repository using this function
void setAlgorithmForKey(Key k, Algorithm a) {
algorithms.put(k, a);
}
// ... implement the other function of the interface
}
Then we can also implement something for the DataRepository
class DataRepository {
AlgorithmRepository algorithmRepository;
Map<Key, Data> cache;
void cacheData(Key k, Data d) {
cache.put(k, d);
}
Data retrieveData(Key k, Data in) {
Data d = cache.get(k);
if (d==null) {
// Data not found in the cache, then we try to produce it ourself
Data d = new Data();
Algorithm a = algorithmRepository.getAlgorithm(k);
a.processData(in, d);
// This is optional, you could simply throw an exception to say that the
// data has not been cached and thus, the algorithm succession did not
// produce the necessary data. So instead of the above, you could simply:
// throw new DataNotCached(k);
// and thus halt the whole processing
}
return d;
}
}
Finally, we get to implement algorithms:
abstract class BaseAlgorithm {
DataRepository repository;
}
class SampleNoCacheAlgorithm extends BaseAlgorithm {
void processData(Data in, Data out) {
// do something with in to compute out
}
}
class SampleCacheProducerAlgorithm extends BaseAlgorithm {
static Key KEY = "SampleCacheProducerAlgorithm.myKey";
void processData(Data in, Data out) {
// do something with in to compute out
// then call repository.cacheData(KEY, out);
}
}
class SampleCacheConsumerAlgorithm extends BaseAlgorithm {
void processData(Data in, Data out) {
// Data tmp = repository.retrieveData(SampleCacheProducerAlgorithm.KEY, in);
// do something with in and tmp to compute out
}
}
To build on this, I think you could also define some special kinds of algorithms that are just in fact composites of other algorithms but also implement the Algorithm interface. An example could be:
class AlgorithmChain extends BaseAlgorithm {
List<Algorithms> chain;
void processData(Data in, Data out) {
Data currentIn = in;
foreach (Algorithm a : chain) {
Data currentOut = new Data();
a.processData(currentIn, currentOut);
currentIn = currentOut;
}
out = currentOut;
}
}
One addition I would make to this is a DataPool, that would allow you to reuse exisiting but unused Data objects in order to avoid allocating lots of memory each time you make a new Data().
I think this set of classes could give a good basis to your whole architecture, with the additional benefit that it does not employ any Singleton (always passing references to the concerned objects). Which means also that implementing dummy classes for unit tests would be rather easy.
You could have your algorithms independant of their results:
class Engine<T> {
Map<AlgorithmKey, Algorithm<T>> algorithms;
Map<AlgorithmKey, Data> algorithmsResultCache;
T processData(Data in);
}
interface Algorithm<T> {
boolean doesResultNeedsToBeCached();
T processData(Data in);
}
Then you Engine is responsible for instanciating the algorithms which are only pieces of code where the input is data and the output is either null or some data. Each algorithm can say whether his result needs to be cached or not.
In order to refine my answer, I think you should give some precisions about how the algorithms are to be run (is there an order, is it user adjustable, do we know in advance the algorithms that will be run, ...).
Can you register your algorithm instances with a combined repository/factory of algorithms that'll keep references to them? The repository could be a singleton, and, if you give the repository control of algorithm instantiation, you could use it to ensure that only one instance of each existed.
public class AlgorithmRepository
{
//... use boilerplate singleton code
public void CreateAlgorithm(Algorithms algorithm)
{
//... add to some internal hash or map, checking that it hasn't been created already
//... Algorithms is just an enum telling it which to create (clunky factory
// implementation)
}
public void ComputeResult(Algorithms algorithm, DataCache datacache)
{
// Can lazy load algoirthms here and make CreateAlgorithm private ..
CreateAlgorithm(algorithm);
//... compute and return.
}
}
This said, having a separate class (and cs file) for each algorithm makes sense to me. You could break with convention and have multiple algo classes in a single cs file if they're lightweight and it makes it easier to manage if you're worried about the number of files -- there are worse things to do. FWIW I'd just put up with the number of files ...
Typically when you create a Singleton class you don't want to inherit from it. When you do this you lose some of the goodness of the Singleton pattern (and what I hear from the pattern zealots is that an angel loses its wings every time you do something like this). But lets be pragmatic...sometimes you do what you have to do.
Regardless I do not think combining generics and inheritance will work in this instance anyway.
You indicated the number of algorithms will be in the tens (not hundreds). As long is this is the case I would create a dictionary keyed off of System.Type and store references to your methods as the values of the dictionary. In this case I used
Func<DataCache, object> as the dictionary value signature.
When the class instantiates for the first time register all your available algorithms in the dictionary. At runtime when the class needs to execute an algorithm for type T it will get the Type of T and look up the alogorithm in the dictionary.
If the code for the algorithms will be relatively involved I would suggest splitting them off into partial classes just to keep your code readable.
public sealed partial class Algorithm<T>
{
private static object ExecuteForSomeType(DataCache dataCache)
{
return new SomeType();
}
}
public sealed partial class Algorithm<T>
{
private static object ExecuteForSomeOtherType(DataCache dataCache)
{
return new SomeOtherType();
}
}
public sealed partial class Algorithm<T>
{
private readonly Dictionary<System.Type, Func<DataCache, object>> _algorithms = new Dictionary<System.Type, Func<DataCache, object>>();
private readonly Dictionary<DataCache, WeakReference> _resultsWeak = new Dictionary<DataCache, WeakReference>();
private readonly Dictionary<DataCache, T> _resultsStrong = new Dictionary<DataCache, T>();
private Algorithm() { }
private static Algorithm<T> _instance;
public static Algorithm<T> Instance
{
get
{
if (_instance == null)
{
_instance = new Algorithm<T>();
_instance._algorithms.Add(typeof(SomeType), ExecuteForSomeType);
_instance._algorithms.Add(typeof(SomeOtherType), ExecuteForSomeOtherType);
}
return _instance;
}
}
public T ComputeResult(DataCache dataCache, bool save = false)
{
T returnValue = (T)(new object());
if (_resultsStrong.ContainsKey(dataCache))
{
returnValue = _resultsStrong[dataCache];
return returnValue;
}
if (_resultsWeak.ContainsKey(dataCache))
{
returnValue = (T)_resultsWeak[dataCache].Target;
if (returnValue != null) return returnValue;
}
returnValue = (T)_algorithms[returnValue.GetType()](dataCache);
_resultsWeak[dataCache] = new WeakReference(returnValue, true);
if (save) _resultsStrong[dataCache] = returnValue;
return returnValue;
}
}
First off, I'd suggest you rename DataCache to something like DataInput for more clarity, because it's easy to confuse it with objects that really act as caches (_resultsWeak and _resultsStrong) to store the results.
Concerning the need for these caches to remain in memory for future use, maybe you should consider placing them in one of the wider scopes that exist in a .NET application than the object scope, Application or Session for example.
You could also use an AlgorithmLocator (see ServiceLocator pattern) as a single point of access to all Algorithms to get rid of the singleton logic duplication in each Algorithm.
Other than that, I find your solution to be a nice one globally. Whether or not it is overkill will basically depend on the homogeneity of your algorithms. If they all have the same way of caching data, of returning their results... it will be a great benefit to have all that logic factored out in a single place. But we lack context here to judge.
Encapsulating the caching logic in a specific object held by the Algorithm (CachingStrategy ?) would also be an alternative to inheriting it, but maybe a bit awkward since the caching object would have to access the cache before and after calculation and would need to be able to trigger algorithm calculation itself and have a hand on the results.
[Edit] if you're concerned with having one .cs file per algorithm, you can always group all Algorithm classes pertaining to a particular T in the same file.
Is this a good pattern? It has a code smell to me with having a factory class aware of the IUnityContainer...
My basic need was to resolve an ICalculationRuleProcess at runtime depending on an Id of a class. It could be based on something other than the Id, I am aware of that... basically I have a known set of Ids that I need to deal with because I bootstrapped the records into the database manually and there is no way to edit the records. With each Id I have a related class. I also have a varying number of constructor parameters within each class that implements the ICalculationRuleProcess, so using an IoC container is extremely helpful versus some crazy switch statement and variable constructor aguments using Activator.CreateInstance
Here is what I did:
Registered the IUnityContainer instance within the container itself. I wasnt sure if this was even possible, but it worked.
Registered all of the ICalculationRuleProcess classes with a unique identifier within the registration (basically just the Id.ToString() of each possible DistributionRule)
Created a factory to determine the correct ICalculationRuleProcess, and had it use the IoC container to figure out the correct class to load.
Registered the factory class (ICalculationRuleProcessFactory) to the IoC container
Wherever the ICalculationRuleProcess needed to be used, I had the class take an ICalculationRuleProcessFactory in its constructor and have it call the Create method to figure out which ICalculationRuleProcess to use.
The code for the factory is here:
public interface ICalculationRuleProcessFactory
{
ICalculationRuleProcess Create( DistributionRule distributionRule );
}
public class CalculationRuleProcessFactory : ICalculationRuleProcessFactory
{
private readonly IBatchStatusWriter _batchStatusWriter;
private readonly IUnityContainer _iocContainer;
public CalculationRuleProcessFactory(
IUnityContainer iocContainer,
IBatchStatusWriter batchStatusWriter )
{
_batchStatusWriter = batchStatusWriter;
_iocContainer = iocContainer;
}
public ICalculationRuleProcess Create( DistributionRule distributionRule )
{
_batchStatusWriter.WriteBatchStatusMessage(
string.Format( "Applying {0} Rule", distributionRule.Descr ) );
return _iocContainer.Resolve<ICalculationRuleProcess>(
distributionRule.Id.ToString() );
}
}
This seems okay to me, given the constraints you described. The most important thing is that all of your rules implement ICalculationRuleProcess and that all consumers of those rules only know about that interface.
It isn't inherently bad that your factory takes the container dependency, especially as an interface. Consider that if you ever had to change container implementations, you could create an IUnityContainer implementation that doesn't use Unity at all (just forward all the members of the interface to their corresponding methods in the replacement container).
If it really bothers you, you can add yet another layer of indirection by creating an agnostic IoC interface with the requisite Register, Resolve, etc. methods and create an implementation that forwards these to Unity.
There is another way you can achieve this without factory taking dependency on IUnityContainer, which is not inherently bad in and of itself. This is just a different way to think about the problem.
The flow is as follows:
Register all different instances of ICalculationRuleProcess.
Get all registered ICalculationRuleProcess and create a creation lambda for each one.
Register ICalculationRuleProcessFactory with a list of ICalculationRuleProcess creation lambdas.
In ICalculationRuleProcessFactory.Create return the right process.
Now the tricky part of this is to preserve the Ids that the registrations were made under. Once solution is to simply keep the Id on the ICalculationProcess interface, but it might not semantically belong there. This is where this solution slips into ugly (which is more of a case of missing functionality in Unity). But, with an extension method and a small extra type, it looks nice when it's run.
So what we do here is create an extension method that returns all registrations with their names.
public class Registration<T> where T : class {
public string Name { get; set; }
public Func<T> CreateLambda { get; set; }
public override bool Equals(object obj) {
var other = obj as Registration<T>;
if(other == null) {
return false;
}
return this.Name == other.Name && this.CreateLambda == other.CreateLambda;
}
public override int GetHashCode() {
int hash = 17;
hash = hash * 23 + (Name != null ? Name.GetHashCode() : string.Empty.GetHashCode());
hash = hash * 23 + (CreateLambda != null ? CreateLambda.GetHashCode() : 0);
return hash;
}
}
public static class UnityExtensions {
public static IEnumerable<Registration<T>> ResolveWithName<T>(this UnityContainer container) where T : class {
return container.Registrations
.Where(r => r.RegisteredType == typeof(T))
.Select(r => new Registration<T> { Name = r.Name, CreateLambda = ()=>container.Resolve<T>(r.Name) });
}
}
public class CalculationRuleProcessFactory : ICalculationRuleProcessFactory
{
private readonly IBatchStatusWriter _batchStatusWriter;
private readonly IEnumerable<Registration<ICalculationRuleProcess>> _Registrations;
public CalculationRuleProcessFactory(
IEnumerable<Registration<ICalculationRuleProcess>> registrations,
IBatchStatusWriter batchStatusWriter )
{
_batchStatusWriter = batchStatusWriter;
_Registrations= registrations;
}
public ICalculationRuleProcess Create( DistributionRule distributionRule )
{
_batchStatusWriter.WriteBatchStatusMessage(
string.Format( "Applying {0} Rule", distributionRule.Descr ) );
//will crash if registration is not present
return _Registrations
.FirstOrDefault(r=>r.Name == distributionRule.Id.ToString())
.CreateLambda();
}
}
//Registrations
var registrations = container.ResolveWithName<ICalculationRuleProcess>(container);
container.RegisterInstance<IEnumerable<Registration<ICalculationRuleProcess>>>(registrations);
After I wrote this I realised that this is more creative lambda douchebaggery than a architecturally pretty solution. But in any case, feel free to get ideas out of it.
Hey Rob, I'm intending to use essentially the same pattern. I've got multiple types of shopping cart item that need to be associated with their own specific set of validator instances of varying class.
I think there is a smell about this pattern and its not that the factory has a reference to the IoC container, its that typically, an IoC container is configured in the application root which is typically the UI layer. If a crazy custom factory was created just to handle these associations then possibly it should be in the domain.
In short, these associations are possibly not part of the overall program structure that's set up before the application runs and so shouldn't be defined in the application root.
What would be the most efficient way to instanciate an object according to a generic type passed to a Factory class, for instance:
public class LoggerFactory
{
public static ILogger<T> Create<T>()
{
// Switch Statement?
// Generic Dictionary?
// EX.: if "T" is of type "string": return (ILogger<T>)new StringLogger();
}
}
How would you do it? Which branching statement? etc...
I think it's best to keep it simple, perhaps something like this:
public static class LoggerFactory
{
static readonly Dictionary<Type, Type> loggers = new Dictionary<Type, Type>();
public static void AddLoggerProvider<T, TLogger>() where TLogger : ILogger<T>, new()
{
loggers.Add(typeof(T), typeof(TLogger));
}
public static ILogger<T> CreateLogger<T>()
{
//implement some error checking here
Type tLogger = loggers[typeof(T)];
ILogger<T> logger = (ILogger<T>) Activator.CreateInstance(tLogger);
return logger;
}
}
You just call the AddLoggerProvider for each type you want to support, can be extended at runtime, it ensures you definetly add an implementation of the interface to the library and not some object, isn't very fast because of the Activator, but creating a logger wont likely be a bottleneck anyway. Hope it looks okay.
Usage:
// initialize somewhere
LoggerFactory.AddLoggerProvider<String, StringLogger>();
LoggerFactory.AddLoggerProvider<Exception, ExceptionLogger>();
// etc..
ILogger<string> stringLogger = LoggerFactory.CreateLogger<string>();
Note: each ILogger<T> requires a parameterless constructor for the Activator, but that too is ensured with the new() generic constraint in the add method.
I think I'd do it like this:
public class LoggerFactory<T>
{
private static Dictionary<Type, Func<ILogger<T>>> LoggerMap =
new Dictionary<Type, Func<ILogger<T>>>
{
{ typeof(string),
() => new StringILogger() as ILogger<T> },
{ typeof(StringWriter),
() => new StringWriterILogger() as ILogger<T> }
};
public static ILogger<T> CreateLogger()
{
return LoggerMap[typeof(T)]();
}
}
You pay something of a readability price (all those angle brackets, sheesh), but as you can see it makes for very little program logic.
Although I typically would recommend using a dependency injection framework, you could implement something with reflection that would search the available types for one that implements the appropriate ILogger interface.
I would suggest that you carefully consider which assemblies will contain these logger implementations and how extensible and bullet-proof you want the solution to be. Performing runtime searches across the available assemblies and types is not inexpensive. It is, however, an easy way to allow extensibility in this type of design. It also avoid the issue of up-front configuration - however it requires that only a single concrete type implement a particular version of the ILogger<> interface - otherwise there's an ambiguous situation you have to resolve.
You may want to perform some internal caching to avoid the expense of performing reflection on each call to Create().
Here is some sample code you could start with.
using System;
using System.Linq;
using System.Reflection;
public interface ILogger<T> { /*... */}
public class IntLogger : ILogger<int> { }
public class StringLogger : ILogger<string> { }
public class DateTimeLogger : ILogger<DateTime> { }
public class LoggerFactory
{
public static ILogger<T> Create<T>()
{
// look within the current assembly for matching implementation
// this could be extended to search across all loaded assemblies
// relatively easily - at the expense of performance
// also, you probably want to cache these results...
var loggerType = Assembly.GetExecutingAssembly()
.GetTypes()
// find implementations of ILogger<T> that match on T
.Where(t => typeof(ILogger<T>).IsAssignableFrom(t))
// throw an exception if more than one handler found,
// could be revised to be more friendly, or make a choice
// amongst multiple available options...
.Single();
/* if you don't have LINQ, and need C# 2.0 compatibility, you can use this:
Type loggerType;
Type[] allTypes = Assembly.GetExecutingAssembly().GetTypes();
foreach( var type in allTypes )
{
if( typeof(ILogger<T>).IsAssignableFrom(type) && loggerType == null )
loggerType = type;
else
throw new ApplicationException( "Multiple types handle ILogger<" + typeof(T).Name + ">" );
}
*/
MethodInfo ctor = loggerType.GetConstructor( Type.EmptyTypes );
if (ctor != null)
return ctor.Invoke( null ) as ILogger<T>;
// couldn't find an implementation
throw new ArgumentException(
"No mplementation of ILogger<{0}>" + typeof( T ) );
}
}
// some very basic tests to validate the approach...
public static class TypeDispatch
{
public static void Main( string[] args )
{
var intLogger = LoggerFactory.Create<int>();
var stringLogger = LoggerFactory.Create<string>();
var dateTimeLogger = LoggerFactory.Create<DateTime>();
// no logger for this type; throws exception...
var notFoundLogger = LoggerFactory.Create<double>();
}
}
Depends on how many types you intend to handle. If it's small (less than 10) I'd suggest a switch statement, as it'll be fast and cleaner to read. If you want more you would want a lookup table (Hash Map, Dictionary, etc), or some reflection based system.
switch statement vs dictionary - doesn't matter for perfomance, as a switch is compiled into a dictionary. So really it's a matter of readabilty and flexibility. The switch is easier to read, on the other hand a dictionary can be extended at runtime.
You might consider using a dependency injection framework here like Unity. You can configure it with the generic types that your factor will return and do the mapping in configuration. Here's an example of that.
1) I'm always amazed at the complexity people put into logging. Always seems like overkill to me. If log4net is opensource, I'd recommend you go look at that, infact, you might just as well use it ...
2) Personally, I try to avoid type checking whenever possible - it defeats the point of generics. Just use the .ToString() method and be done with it.
Hrm... you could actually try to be a little more clever about this, depending on what the given runtime system supported. I actually try to avoid any conditional statements in my code if I can, especially in polymorphic and dynamically bound code. You've got a generic class there, so why not use it?
For example, in Java, you can especially make use of the static method you've got there to do something like this:
public class LoggerFactory<T>
{
public static ILogger<T> CreateLogger(Class<? extends SomeUsefulClass> aClass);
{
// where getLogger() is a class method SomeUsefulClass and its subclasses
// and has a return value of Logger<aClass>.
return aClass.getLogger();
// Or perhaps you meant something like the below, which is also valid.
// it passes the generic type to the specific class' getLogger() method
// for correct instantiation. However, be careful; you don't want to get
// in the habit of using generics as variables. There's a reason they're
// two different things.
// return aClass.getLogger(T);
}
}
You'd call it like this:
public static void main(String[] args)
{
Logger = LoggerFactory.createLogger(subclassOfUsefulClass.class);
// And off you go!
}
This avoids having to have any conditionals and is more flexible besides: any class that's a subclass (or implements the logger interface, perhaps) of SomeUsefulClass can return the correctly typed logger instance.