I believe Factory Pattern is one of the most known pattern in development community. Simply Factory Pattern states that we have a factory object which is used to create other objects. But GoF specification for the Factory Pattern is a little bit different. GoF book says that "We should define an interface for creating an object, but let subclasses decide which class to instantiate."
How you implement the Factory Pattern depends on your custom needs. 1) If you want to control object instantiation behaviour of your factory
provide a static class with static methods or sealed factory class to
your clients, else 2) if you want to keep your code closed for modification but open for extension follow the GoF way by providing an interface or abstract factory class.
Method 1
Download GoF_Patterns_Factory1.rar (18,45 kb)
Now lets implement Factory Pattern for our Vehicle instantiation process so that we do not want our clients to have alternative factory implementation at all.
001 //Abstract Vehicle class
002
003 public abstract class Vehicle
004
005 {
006
007 public abstract string Description { get; }
008
009 }
010
011
012
013 //Concrete implementation
014
015 public sealed class Car : Vehicle
016
017 {
018
019 internal Car() { }
020
021 public override string Description
022
023 {
024
025 get { return "Car";}
026
027 }
028
029 }
030
031
032
033 //Concrete implementation
034
035 public sealed class Helicopter : Vehicle
036
037 {
038
039 internal Helicopter() { }
040
041 public override string Description
042
043 {
044
045 get { return "Helicopter"; }
046
047 }
048
049 }
050
051
052
053 //Concrete implementation
054
055 public sealed class Jet : Vehicle
056
057 {
058
059 internal Jet() { }
060
061 public override string Description
062
063 {
064
065 get { return "Jet"; }
066
067 }
068
069 }
I've chosen to implement my factory as a static class with CreateVehicle static method. Here is the code
001 public static class VehicleFactory
002
003 {
004
005 public static Vehicle CreateVehicle(string vehicleType)
006
007 {
008
009 string type = vehicleType.ToLower().Trim();
010
011 switch (type)
012
013 {
014
015 case "car":
016
017 return new Car();
018
019 case "helicopter":
020
021 return new Helicopter();
022
023 case "jet":
024
025 return new Jet();
026
027 default:
028
029 throw new Exception("Unsupported vehicle type!");
030
031 }
032
033 }
034
035 }
As you can see our clients will not be able to change the Vehicle instantiation behaviour of our static factory class.
001 static void Main(string[] args)
002
003 {
004
005 Vehicle vehicle = VehicleFactory.CreateVehicle("car");
006
007 Console.WriteLine(vehicle.Description);
008
009
010
011 vehicle = VehicleFactory.CreateVehicle("jet");
012
013 Console.WriteLine(vehicle.Description);
014
015
016
017 vehicle = VehicleFactory.CreateVehicle("helicopter");
018
019 Console.WriteLine(vehicle.Description);
020
021
022
023 Console.ReadLine();
024
025 }
Method 2
Download GoF_Patterns_Factory2.rar (18,90 kb)
If you want to enable your clients to modify object instantiation behaviour of the factory you must implement your factory the GoF way. Our abstract Vehicle class and different concerete implementations remain as the ones provided in Method 1. Here is our factory interface
001 public interface IVehicleFactory
002
003 {
004
005 Vehicle CreateVehicle(string vehicleType);
006
007 }
Here a sample implementation of IVehicleFactory interface. Our clients may implement CreateVehicle method of our factory interface how they wish.
001 public class VehicleFactory:IVehicleFactory
002
003 {
004
005 #region IVehicleFactory Members
006
007
008
009 public Vehicle CreateVehicle(string vehicleType)
010
011 {
012
013 string type = vehicleType.ToLower().Trim();
014
015 switch (type)
016
017 {
018
019 case "car":
020
021 return new Car();
022
023 case "helicopter":
024
025 return new Helicopter();
026
027 case "jet":
028
029 return new Jet();
030
031 default:
032
033 throw new Exception("Unsupported vehicle type!");
034
035 }
036
037 }
038
039
040
041 #endregion
042
043 }
001 static void Main(string[] args)
002
003 {
004
005 VehicleFactory factory = new VehicleFactory();
006
007 Vehicle vehicle = factory.CreateVehicle("car");
008
009 Console.WriteLine(vehicle.Description);
010
011
012
013 vehicle = factory.CreateVehicle("jet");
014
015 Console.WriteLine(vehicle.Description);
016
017
018
019 vehicle = factory.CreateVehicle("helicopter");
020
021 Console.WriteLine(vehicle.Description);
022
023
024
025 Console.ReadLine();
026
027 }
d345997c-5b9d-421a-9ca4-89256a9ba51b|0|.0