by Moridin8
3. February 2008 20:14
[For a ##csharp bod]
The basic idea to factories is that they create objects for you.
The simplest example is given here:
namespace ooppatterns
{
using System;
using System.Collections.Generic;
internal class Program
{
private static void Main( string[] args )
{
List<IDoSomething> aList = new List<IDoSomething>();
SimpleMethodFactory factory = new SimpleMethodFactory();
for ( int i = 0; i < 32; i++ )
aList.Add( factory.Create( i ) );
foreach ( IDoSomething ID in aList )
Console.WriteLine( ID.DoSomething );
Console.ReadLine();
}
}
// product
interface IDoSomething
{
string DoSomething { get; }
}
// Concrete Creator
class SimpleMethodFactory
{
/// <summary>
/// Manufactures and object based on criteria.
/// </summary>
/// <param name="manufactureCriteria">The manufacture criteria.</param>
/// <returns>An IDoSomething derived object</returns>
public IDoSomething Create( int manufactureCriteria )
{
if ( manufactureCriteria % 15 == 0 )
return new Example01( "This is created using MOD 15 FIZZBANG" );
if ( manufactureCriteria % 5 == 0 )
return new Example02( "This is created using MOD 5 FIZZ" );
if ( manufactureCriteria % 3 == 0 )
return new Example03( "This is created using MOD 3 BANG" );
return new Example00( manufactureCriteria.ToString() );
}
}
// Concrete Product 00
class Example00 : IDoSomething
{
private string _value;
public Example00( string value )
{
this._value = value;
}
public string DoSomething
{
get { return string.Format( "Example00 : {0}", this._value ); }
}
}
// Concrete Product 01
class Example01 : IDoSomething
{
private string _value;
public Example01( string value )
{
this._value = value;
}
public string DoSomething
{
get { return string.Format( "Example01 : {0}", this._value ); }
}
}
// Concrete Product 02
class Example02 : IDoSomething
{
private string _value;
public Example02( string value )
{
this._value = value;
}
public string DoSomething
{
get { return string.Format( "Example02 : {0}", this._value ); }
}
}
// Concrete Product 03
class Example03 : IDoSomething
{
private string _value;
public Example03( string value )
{
this._value = value;
}
public string DoSomething
{
get { return string.Format( "Example03 : {0}", this._value ); }
}
}
}
Another take for GoF purists:
namespace ooppatterns
{
using System;
using System.Collections.Generic;
internal class Program
{
private static void Main( string[] args )
{
SimpleMethodFactoryBase[] factories =
{
new SimpleMethodFactoryA(),
new SimpleMethodFactoryB()
};
List<IDoSomething> aList = new List<IDoSomething>();
for ( int i = 0; i < 32; i++ )
aList.Add( factories[1-(i % 2)].Create( i ) );
foreach ( IDoSomething ID in aList )
Console.WriteLine( ID.DoSomething );
Console.ReadLine();
}
}
// Product
interface IDoSomething
{
string DoSomething { get; }
}
// Creator
abstract class SimpleMethodFactoryBase
{
/// <summary>
/// Manufactures and object based on criteria.
/// </summary>
/// <param name="manufactureCriteria">The manufacture criteria.</param>
/// <returns>An IDoSomething derived object</returns>
public abstract IDoSomething Create( int manufactureCriteria );
}
// Concrete Creator A
class SimpleMethodFactoryA : SimpleMethodFactoryBase
{
public override IDoSomething Create( int manufactureCriteria )
{
if ( manufactureCriteria % 15 == 0 )
return new Example01( "This is created using MOD 15 FIZZBANG" );
if ( manufactureCriteria % 5 == 0 )
return new Example02( "This is created using MOD 5 FIZZ" );
if ( manufactureCriteria % 3 == 0 )
return new Example03( "This is created using MOD 3 BANG" );
return new Example00( manufactureCriteria.ToString() );
}
}
// Concrete Creator B
class SimpleMethodFactoryB : SimpleMethodFactoryBase
{
public override IDoSomething Create( int manufactureCriteria )
{
if ( manufactureCriteria % 13 == 0 )
return new Example03( "This is created using MOD 13 Wibble" );
if ( manufactureCriteria % 10 == 0 )
return new Example01( "This is created using MOD 10 Wobble" );
if ( manufactureCriteria % 7 == 0 )
return new Example02( "This is created using MOD 7 Wubble" );
return new Example00( manufactureCriteria.ToString() );
}
}
// Concrete Product 00
class Example00 : IDoSomething
{
private string _value;
public Example00( string value )
{
this._value = value;
}
public string DoSomething
{
get { return string.Format( "Example00 : {0}", this._value ); }
}
}
// Concrete Product 01
class Example01 : IDoSomething
{
private string _value;
public Example01( string value )
{
this._value = value;
}
public string DoSomething
{
get { return string.Format( "Example01 : {0}", this._value ); }
}
}
// Concrete Product 02
class Example02 : IDoSomething
{
private string _value;
public Example02( string value )
{
this._value = value;
}
public string DoSomething
{
get { return string.Format( "Example02 : {0}", this._value ); }
}
}
// Concrete Product 03
class Example03 : IDoSomething
{
private string _value;
public Example03( string value )
{
this._value = value;
}
public string DoSomething
{
get { return string.Format( "Example03 : {0}", this._value ); }
}
}
}
by Moridin8
1. February 2008 20:12
You could consider this singleton to be the web application friendly version of the ThreadSingleton (Well... almost). It lives inside the HttpContext Session dictionary as a standard session serialized object instead of staying in state against a specific thread and ss usual for session data it is (de)serialized against which ever session serialisation source you are using
In more complicated incarnations this form of class can allow all sorts of extensions to your web session model. Using the various facilities available in .NET for instance you can engineer and associate all forms of models directly against the session data in a much more OOP friendly manner.
This is my prefered way of working with session stated data. I sometimes wonder why so many other people don't themselves...
[Serializable]
public sealed class SessionSingleton
{
private const string SESSION_KEY
= "MySession_3BC433AB-3925-4bee-9EDD-7F874D241AD0";
/// <summary>
/// Some basic instance data.
/// </summary>
private string _SomeInstanceData;
/// <summary>
/// Gets or sets some instance data.
/// </summary>
/// <value>Some instance data.</value>
public string SomeInstanceData
{
get { return this._SomeInstanceData; }
set { this._SomeInstanceData = value; }
}
/// <summary>
/// Initializes a new instance of the <see cref="SessionSingleton"/> class.
/// This is privately invoked
/// </summary>
private SessionSingleton()
{
this._SomeInstanceData = "Hi!";
}
/// <summary>
/// Gets the singleton.
/// </summary>
/// <value>The singleton.</value>
public static SessionSingleton Session
{
get
{
// double check locking...
if( HttpContext.Current.Session[SESSION_KEY] == null )
lock( HttpContext.Current.Session.SyncRoot )
if( HttpContext.Current.Session[SESSION_KEY] == null )
HttpContext.Current.Session[SESSION_KEY] =
new SessionSingleton();
return HttpContext.Current.Session[SESSION_KEY] as SessionSingleton;
}
}
}