I am trying to learn the factory design pattern. I have created a code for creating two animals (for now only dogs and a cats).
I have got an Animal (as a product)
public abstract class Animal
{
public abstract void CreateBody();
public abstract void CreateLeg();
}
Dog and Cat Implements Animal class:
public class Dog: Animal
{
public override void CreateBody()
{
Console.WriteLine("Dog body created");
}
public override void CreateLeg()
{
Console.WriteLine("Dog body created");
}
}
Cat Implements Animal:
public class Cat: Animal
{
public override void CreateBody()
{
Console.WriteLine("Cat body created");
}
public override void CreateLeg()
{
Console.WriteLine("Cat Leg created");
}
}
Created a factory class that makes different animal according to the input given in the parameter:
public class AnimalFactory
{
public static Animal CreateAnimal(string animal)
{
Animal animalDetails = null;
if (animal == "cat")
{
animalDetails = new Cat();
}
else if (animal == "dog")
{
animalDetails = new Dog();
}
animalDetails.CreateBody();
animalDetails.CreateLeg();
return animalDetails;
}
}
In the main it is used as:
static void Main(string[] args)
{
Animal animalDetails = AnimalFactory.CreateAnimal("cat");
if (animalDetails != null)
{
}
else
{
Console.Write("Invalid Card Type");
}
Console.ReadLine();
}
Here in this code, I know exactly what methods I need to call to create an animal, so I called those methods in the factory class.
As I read in the various tutorials and books, most of the implementation of the factory method uses another concrete factory method to create the concrete product?
In what case it is appropriate to create the concrete factory method? Is that concrete factory relevant in this demo too?
My implementation :
Animal interface :
public interface IAnimal
{
void CreateBody();
void CreateLeg();
}
Cat & Dog classes:
public class Dog : IAnimal
{
public void CreateBody()
{
Console.WriteLine("Dog body created");
}
public void CreateLeg()
{
Console.WriteLine("Dog leg created");
}
}
public class Cat : IAnimal
{
public void CreateBody()
{
Console.WriteLine("Cat body created");
}
public void CreateLeg()
{
Console.WriteLine("Cat leg created");
}
}
Animal factory
public static class AnimalFactory
{
public static IAnimal? GetInstance(Type type)
{
if(type.GetInterfaces().Contains(typeof(IAnimal))) // check if type implement IAnimal
{
return Activator.CreateInstance(type) as IAnimal;
}
return null;
}
}
Use case
IAnimal? cat = AnimalFactory.GetInstance(typeof(Cat));
IAnimal? dog = AnimalFactory.GetInstance(typeof(Dog));
cat?.CreateBody();
cat?.CreateLeg();
dog?.CreateBody();
dog?.CreateLeg();
this structure can be expanded into an abstractory factory provider. it currently demonstrate a simple factory provider model. The provider accepts the derived class of animal which is either cat or dog and sets a private label called type
public abstract class Animal
{
public string _Type;
public abstract void CreateBody();
public abstract void CreateLeg();
public abstract void SetType(string type);
}
public class Dog : Animal
{
public Dog() {
SetType("Dog");
}
public override void SetType(string type)
{
_Type = type;
}
public override void CreateBody()
{
Console.WriteLine("Dog body created");
}
public override void CreateLeg()
{
Console.WriteLine("Dog body created");
}
}
public class Cat : Animal
{
public Cat()
{
SetType("Cat");
}
public override void SetType(string type)
{
_Type = type;
}
public override void CreateBody()
{
Console.WriteLine("Cat body created");
}
public override void CreateLeg()
{
Console.WriteLine("Cat Leg created");
}
}
public class AnimalProviderFactory {
public AnimalProvider GetAnimalProvider()
{
return new AnimalProvider();
}
}
public class AnimalProvider{
public string GenerateShippingLabelFor(Animal catOrDog)
{
return catOrDog._Type;
}
}
public class AnimalType
{
private readonly Animal catOrDog;
private readonly AnimalProviderFactory animalProviderFactory;
public AnimalType(Animal catOrDog, AnimalProviderFactory animalProviderFactory)
{
this.catOrDog = catOrDog;
this.animalProviderFactory = animalProviderFactory;
}
public string Finalize()
{
var provider = animalProviderFactory.GetAnimalProvider();
return provider.GenerateShippingLabelFor(catOrDog);
}
}
public void TestAbstractFactory()
{
Cat cat = new Cat();
AnimalType animalType= new AnimalType(cat, new AnimalProviderFactory());
var type = animalType.Finalize();
_output.WriteLine(type);
Assert.True(true);
}
Related
I try to simulate the decorator pattern in C#.
So I have these classes:
public abstract class Car
{
// private string description;
public abstract string Descripton
{
get;
}
public abstract int Cost();
}
public abstract class CarDecorator : Car
{
protected Car _decorated;
//private string description;
public CarDecorator(Car decoratied)
{
this._decorated = decoratied;
}
public override string Descripton
{
get
{
return _decorated.Descripton;
}
}
public override int Cost()
{
return _decorated.Cost();
}
public class EnhancedAutoPilot : CarDecorator
{
public EnhancedAutoPilot(Car car):base(car)
{
this._decorated = car;
}
public override string Descripton
{
get
{
return _decorated.Descripton + ", Enhanced autopilot";
}
}
public override int Cost()
{
return _decorated.Cost() + 5000;
}
}
public class ModelXS:Car
{
protected Car _decorated;
public string Description = "Model XS";
public override string Descripton
{
get
{
return _decorated.Descripton;
}
}
public override int Cost()
{
return 5500;
}
}
public class ModelXXX : Car
{
protected Car _decorated;
public string Description = "ModelXXX";
public override string Descripton
{
get
{
return _decorated.Descripton;
}
}
public override int Cost()
{
return 73000;
}
}
public class RearFacingSeats:CarDecorator
{
public RearFacingSeats(Car car):base(car)
{
this._decorated = car;
}
public override string Descripton
{
get
{
return _decorated.Descripton + ", Rear Facing Seats ";
}
}
public override int Cost()
{
return _decorated.Cost() + 4000;
}
}
public class SmartAirSuspension: CarDecorator
{
public SmartAirSuspension(Car car):base(car)
{
this._decorated = car;
}
public override string Descripton
{
get
{
return _decorated.Descripton + ", Smart Air Suspension ";
}
}
public override int Cost()
{
return _decorated.Cost() + 2500;
}
}
class Program
{
static void Main(string[] args)
{
Car car = new RearFacingSeats(new SmartAirSuspension(new EnhancedAutoPilot()));
}
}
But then I get this error:
There is no argument given that corresponds to the required formal parameter 'car' of 'EnhancedAutoPilot.EnhancedAutoPilot(Car)'
Your Cars are wrong, they look like decorators but are not, in fact they are supposed to be just implementations of Cars. Like this one:
public class ModelXS : Car
{
public override string Descripton
{
get
{
return "Model XS";
}
}
public override int Cost()
{
return 5500;
}
}
After that you can call the constructors like in #Richard 's answer and you are golden.
and you can ditch
public EnhancedAutoPilot(Car car):base(car)
{
this._decorated = car; // <<-- this lines
}
because you do that assignment in the base constructor of the CarDecorator class already.
You're using new EnhancedAutoPilot() constructor without parameters and it requires a Car parameter in your contructor signature.
public EnhancedAutoPilot(Car car):base(car)
Another issue i see is that you have _decorated in your Car class. The decorated object should only be in the Decorator classes.
So i would modify your car classes this way :
public class ModelXXX : Car
{
public override string Descripton => "ModelXXX";
public override int Cost()
{
return 73000;
}
}
public class ModelXS : Car
{
public override string Descripton => "Model XS";
public override int Cost()
{
return 5500;
}
}
And main would look like this :
static void Main(string[] args)
{
Car car = new ModelXXX();
car = new EnhancedAutoPilot(car);
car = new SmartAirSuspension(car);
car = new RearFacingSeats(car);
Console.Writeline(car.Descripton);
}
The error is telling you that you are not passing a value to the EnhancedAutoPilot() contstructor. All of your decorators require a Car instance be passed, thus you must instantiate a car first, before calling your decorators.
It looks like ModelXS and ModelXXX are types of cars, so the Program class should be:
class Program
{
static void Main(string[] args)
{
Car decoratedCar =
new RearFacingSeats(
new SmartAirSuspension(
new EnhancedAutoPilot(
new ModelXS())));
}
}
For all the entities in my project I have a base entity and from that interface another interface and then a class ( this is how it is and I cannot change it ).
Given any 2 objects, I want to call a method.
I have created a dictionary with a tuple key to be able to retrieve the right method.
This is the code:
public interface IAnimal
{
string Name { get; set; }
}
public interface IDog : IAnimal
{
}
public interface ICat : IAnimal
{
}
public interface IMouse : IAnimal
{
}
public class Cat : ICat
{
public string Name { get; set; }
}
public class Dog : IDog
{
public string Name { get; set; }
}
public class Mouse : IMouse
{
public string Name { get; set; }
}
public class Linker
{
private static Dictionary<Tuple<Type, Type>, object> _linkMethodsDictionary = new Dictionary<Tuple<Type, Type>, object>();
private static bool _linkDictionaryWasInitialized = false;
public void InitializeLinkMethods()
{
if (_linkDictionaryWasInitialized) return;
_linkMethodsDictionary.Add(Tuple.Create(typeof(IDog), typeof(ICat)), (Action<IDog, ICat>)LinkDogToCat);
_linkMethodsDictionary.Add(Tuple.Create(typeof(ICat), typeof(Mouse)), (Action<ICat, IMouse>)LinkCatToMouse);
_linkDictionaryWasInitialized = true;
}
public void Link<T, TU>(T entity1, TU entity2) where T : class, IAnimal
where TU : class, IAnimal
{
Action<T, TU> linkMethod = _linkMethodsDictionary[Tuple.Create(typeof(T), typeof(TU))] as Action<T, TU>;
if (linkMethod == null)
throw new NotImplementedException($"Could not find link method for {entity1.Name} and {entity2.Name}");
linkMethod(entity1, entity2);
}
public void LinkDogToCat(IDog dog, ICat cat)
{
Console.WriteLine($"Dog: {dog.Name} - Cat:{cat.Name}");
}
public void LinkCatToMouse(ICat cat, IMouse mouse)
{
Console.WriteLine($"Cat: {cat.Name} - Mouse:{mouse.Name}");
}
Not sure how to declare the key of the dictionary, because the call fails: "The given key was not present in the dictionary."
Linker linker = new Linker();
linker.InitializeLinkMethods();
ICat cat = new Cat() {Name = "The CAT"};
IDog dog = new Dog() {Name = "the DOG"};
IMouse mouse = new Mouse() {Name = "The MOUSE"};
linker.Link<ICat, IMouse>(cat, mouse);
linker.Link(dog, cat);
I have used a struct as a key for the Dictionary
internal struct EntityLinkKey
{
private readonly Type _first;
private readonly Type _second;
public EntityLinkKey(Type first, Type second)
{
this._first = first;
this._second = second;
}
public override int GetHashCode()
{
return this._first.GetHashCode() * 17 + this._second.GetHashCode();
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (GetType() != obj.GetType()) return false;
EntityLinkKey p = (EntityLinkKey)obj;
return p._first == this._first && p._second == this._second;
}
}
Please see this structure (from here):
public abstract class AbstractPage<T> where T : AbstractPageEmenetsMap, new()
{
protected readonly string url;
protected VendorInfo vendorInfo;
public AbstractPage(VendorInfo vendorInfo)
{
this.vendorInfo = vendorInfo;
this.url = this.vendorInfo.Url;
}
public void Navigate()
{
WebDriver.Driver.Navigate().GoToUrl(this.url);
}
protected T Map
{
get { return new T(); }
}
}
public abstract class AbstractPage<M, V> : AbstractPage<M>, ITest
where M : AbstractPageEmenetsMap, new()
where V : AbstractPageValidator<M>, new()
{
public AbstractPage(VendorInfo vendorInfo)
: base(vendorInfo) { }
public V Validate()
{
return new V();
}
public void Login();
{
throw new System.NotImplementedException();
}
public void Logout();
{
throw new System.NotImplementedException();
}
}
And i want to add interface with some operations
public interface ITest
{
void Login();
void Logout();
}
Now this is Son class:
public class GmailPage : AbstractPage<GmailPageElementsMap, GmailPageValidator>, ITest
{
public GmailPage() : base("http:...") { }
}
Class that holds all the elements:
public IWebElement EmailAddressTextBox
{
get
{
return WebDriver.WebDriverWait.Until(ExpectedConditions.ElementIsVisible(By.Id("identifierId")));
}
}
And validator:
public class GmailPageValidator : AbstractPageValidator<GmailPageElementsMap>
{
}
As you can see i implement ITest from my Gmail class but i don't received any compile error although i do not add this 2 interface methods (Login and Logout).
This is because those methods are implemented in the parent AbstractPage. If you want to force GmailPage (and all other derived classes) to implement Login() and Logout() declare them as abstract in the parent AbstractPage class
public abstract class AbstractPage<M, V> : AbstractPage<M>, ITest
where M : AbstractPageEmenetsMap, new()
where V : AbstractPageValidator<M>, new()
{
public AbstractPage(VendorInfo vendorInfo) : base(vendorInfo) { }
public V Validate()
{
return new V();
}
public abstract void Login();
public abstract void Logout();
}
And override in GmailPage
public class GmailPage : AbstractPage<GmailPageElementsMap, GmailPageValidator>
{
public GmailPage() : base("http:...") { }
public override void Login()
{
throw new System.NotImplementedException();
}
public override void Logout()
{
throw new System.NotImplementedException();
}
}
I'd like to implement abstract factory design pattern. I add this snippet :
public class Class1
{
static Ete _ete;
static Hiver _hiver;
public static void Main(Clothes cl)
{
_ete = cl.CreateEteClothes();
_hiver = cl.CreateHiverClothes();
Console.WriteLine(_ete.GetMarque());
Console.ReadKey();
Console.WriteLine(_hiver.GetMarque());
Console.ReadKey();
}
}
public abstract class Clothes
{
public abstract Ete CreateEteClothes();
public abstract Hiver CreateHiverClothes();
}
public abstract class ItalianFactory: Clothes
{
public override Ete CreateEteClothes()
{
return new TShirtJuve();
}
public override Hiver CreateHiverClothes()
{
return new PullJuve();
}
}
public abstract class FrenchFactory : Clothes
{
public override Ete CreateEteClothes()
{
return new TShirtPsg();
}
public override Hiver CreateHiverClothes()
{
return new PullPsg();
}
}
public abstract class TunisianFactory : Clothes
{
public override Ete CreateEteClothes()
{
return new TShirtCa();
}
public override Hiver CreateHiverClothes()
{
return new PullCa();
}
}
public abstract class Ete
{
public abstract string GetMarque();
}
public abstract class Hiver
{
public abstract string GetMarque();
}
public class TShirtJuve: Ete
{
public override string GetMarque()
{
return "Juventus T shirt";
}
}
public class TShirtPsg : Ete
{
public override string GetMarque()
{
return "PSG T shirt";
}
}
public class TShirtCa : Ete
{
public override string GetMarque()
{
return "club africain T shirt";
}
}
public class PullJuve : Hiver
{
public override string GetMarque()
{
return "Juventus Pull";
}
}
public class PullPsg : Hiver
{
public override string GetMarque()
{
return "PSg Pull";
}
}
public class PullCa : Hiver
{
public override string GetMarque()
{
return "Club africain Pull";
}
}
I'd like to test this implementation, but I get an exception indicates that the signature of main method is not acceptable.
So How can I fix my code to test this design pattern implementation?
You have public static void Main(Clothes cl)
This should be static void Main(string[] args) as this is the entry point for the application and there can be only one entry point. See the .NET documentation for more info.
A method's signature usually consists of the methods name, return type, and parameters. Your application is expecting the correct signature for the Main method, hence it's giving you this exception.
I need the following inheritance:
public class Persistent
{
public virtual Persistent Clone() { ... }
}
public class Animal : Persistent
{
public override Animal Clone() { ... }
}
This can be implemented using a generic class:
public class Persistent<T>
{
public virtual T Clone() { ... }
}
public class Animal : Persistent<Animal>
{
public override Animal Clone() { ... }
}
However inheriting further from Animal does not work:
public class Pet : Animal
{
public override Pet Clone() // return type is Animal
}
Obviously Pet should derive from Persistent<Pet> for this to work but I need classic inheritance. Unfortunately C# supports neither multiple inheritance nor mixins. Is there any workaround?
This works the way you want it to, although I'd ask why Persistent needs to be a class and not an interface.
public class Persistent
{
public virtual Persistent Clone() { return null; }
}
public class Animal : Persistent<Animal>
{
public override Animal Clone() { return null; }
}
public class Persistent<T>
{
public virtual T Clone() { return default(T); }
}
public class Animal : Persistent<Animal>
{
public override Animal Clone() { return null; }
}
public class Pet : Animal
{
public new Pet Clone()
{
return null;
}
}
Here is a simple solution with generics:
public abstract class Persistent<T>
{
protected abstract T CloneOverride();
public T Clone()
{
return CloneOverride();
}
}
public class Animal : Persistent<Animal>
{
protected override Animal CloneOverride()
{
return new Animal();
}
public new Animal Clone()
{
return CloneOverride();
}
}
public class Pet : Persistent<Pet>
{
protected override Pet CloneOverride()
{
return new Pet();
}
public new Pet Clone()
{
return CloneOverride();
}
}
(see also my other answer without generics)
Here is a simple solution without generics:
public class Persistent
{
protected virtual object CloneOverride()
{
return new Persistent();
}
public Persistent Clone()
{
return (Persistent)CloneOverride();
}
}
public class Animal : Persistent
{
protected override object CloneOverride()
{
return new Animal();
}
public new Animal Clone()
{
return (Animal)CloneOverride();
}
}
public class Pet : Animal
{
protected override object CloneOverride()
{
return new Pet();
}
public new Pet Clone()
{
return (Pet)CloneOverride();
}
}
The good point is that you hide ancestors Clone() methods as expected, and the pattern is always the same.
The drawback is that it's easy to make a mistake because CloneOverride() is not type safe.
(see also my other answer with generics)
With method hiding
public class Persistent
{
public Persistent Clone() { ... }
}
public class Animal : Persistent
{
public new Animal Clone() { ... }
}
From your code I am assuming you are doing it for cloning. So you can create a cloner,
public class Persistent
{
public virtual Dictionary<string, object> GetCloneDictionary()
{
return //dictionary containning clonning values.
}
public void SetValues( Dictionary<string, object> objects)
{
//set values from dictionary
}
}
public class Animal : Persistent
{
public override Dictionary<string, object> GetCloneDictionary()
{
return //dictionary containning clonning values.
}
public override void SetValues( Dictionary<string, object> objects)
{
}
}
public class Animal2 : Animal
{
public override Dictionary<string, object> GetCloneDictionary()
{
return //dictionary containning clonning values.
}
public override void SetValues( Dictionary<string, object> objects)
{
}
}
public class PersistentClonner<T> where T : Persistent
{
public virtual T Clone(T obj)
{
obj.GetCloneDictionary();
//create new and set values
return //new clone
}
}
public class AnimalClonner : PersistentClonner<Animal>
{
public override Animal Clone(Animal obj)
{
obj.GetCloneDictionary();
//create new and set values
return //new clone
}
}
Will this help?
public class Persistent
{
public virtual Persistent Clone()
{
return new Persistent();
}
}
public class Animal : Persistent
{
public new Animal Clone()
{
return new Animal();
}
}
public class Pet : Animal
{
}
public class Wild : Animal
{
public new Wild Clone()
{
return new Wild();
}
}
private static void Test()
{
var p = new Persistent().Clone();
Console.WriteLine("Type of p: {0}", p);
var a = new Animal().Clone();
Console.WriteLine("Type of a: {0}", a);
var t = new Pet().Clone();
Console.WriteLine("Type of t: {0}", t);
var w = new Wild().Clone();
Console.WriteLine("Type of w: {0}", w);
}