Is there a name for this aggregative design pattern? - c#

I frequently find myself using the following pattern when I want to avoid using large switch statements (please excuse the hackneyed 'animal' theme):
public enum AnimalType { Dog, Cat, Hamster }
public interface IAnimal
{
AnimalType AnimalType { get; }
}
public class Cat : IAnimal
{
public AnimalType AnimalType { get { return AnimalType.Cat; } }
}
public class AnimalAggregator
{
private readonly IDictionary<AnimalType, IAnimal> _animals;
public AnimalAggregator(IEnumerable<IAnimal> animals)
{
_animals = animals.ToDictionary(a => a.AnimalType);
}
public IAnimal Get(AnimalType animalType)
{
IAnimal animal;
return _animals.TryGetValue(animalType, out animal) ? animal : null;
}
}
In the above example I would take a dependency on AnimalAggregator and allow an IoC container to wire up the injection of all IAnimals. Then instead of writing out a large switch statement for retrieving the IAnimal associated with AnimalType.Cat, I just call animalAggregator.Get(AnimalType.Cat).
I have used this pattern (and variations thereof) many times in my projects but never known what to call it - I tend to go with "aggregator" but I'm not sure that's accurate. I have never seen it outside of my own code though.
Does it have a name?

This feels to me like it should be an abstract factory pattern:
Provide an interface for creating families of related or dependent
objects without specifying their concrete classes.
You will then have an AnimalFactory with different GetMethods for each animal type.
I guess you could have a generic get method but this defeats the purpose of the abstract factory. Since you are in any way limited by the enum why not have a method per type.
For more info see http://www.dofactory.com/Patterns/PatternAbstract.aspx

I think this is just a variation of the abstract factory pattern. The only thing left to do is make AnimalAggregator extend an IAnimalFactory interface and change client code to take a dependency on IAnimalFactory instead of AnimalAggregator.
public inteface IAnimalFactory
{
IAnimal Get(AnimalType t);
}

Related

IAnimal Interface implemnted by Dog and Cat and DogViewmodel and catViewModel takes IAnimal dependency. How to inject correct obj cat to CatViewmodel

I was asked the below problem in interview of injecting the correct type in dependency injection. I told i will use factory pattern and check the type before injecting the object. Then interviewer asked me if there are 100 classes will you do for all the classes. then he gave hint to use Ienumerable. But I did not get the solution. Below explained the problem statements. Please help me to understand the solution for the below problem.
in WPF MVVM pattern
Model : Has an Interface called IAnimal and two classes are implementing it.
public class Dog : IAnimal
{
}
public class Cat : IAnimal
{
}
in viewmodel having two classes CatViewModel and DogViewModel
public class CatViewModel
{
public CatViewModel(IAnimal animalObj)
{
}
}
public class DogViewModel
{
public DogViewModel(IAnimal animalObj)
{
}
}
here DogViewModel should take only DogModel object and CatViewModel should take only CatModel Object. Here constructor is having IAnimal type so there can be posibility of injecting wrong object. How to protect and inject correct type.

Instantiate a dynamic Type in C#

I have an Animal class, and two derived classes: Lion and Ant.
I have a method that takes in an Animal type and I want to return a new instance of the derived type of the animal passed to the function (i.e. a new instance of Lion).
public Animal Reproduce(Animal p_animal)
{
Type animalType = p_animal.GetType();
if (SameSpecies(p_animal))
return new animalType(RandomName());
}
There are several ways to achieve this, but what I would suggest is that you create an abstract Reproduce method on your Animal class and implement it in the derived types. For instance:
public abstract class Animal
{
/* .. other stuff .. */
public abstract Animal Reproduce();
public string RandomName() { /* ... */ }
}
public class Lion : Animal
{
/*... other stuff .. */
public override Animal Reproduce() => new Lion(RandomName());
}
That way you can add any future logic in the Reproduce method specific to a certain Animal
Since you don't know the type at compile time, you will have to use Reflection. What you are trying to achieve can be done with:
return (Animal)Activator.CreateInstance(animalType, RandomName());
That line is executed at runtime, meaning that, if the type "animalType" is actually not an extension of the class "Animal", this line will fail at runtime. Also, one of the constructors of your type "animalType" needs to receive exactly one argument of whatever type "RandomName()" function returns, otherwise you will also have a runtime error.
EDIT: Reflection has a performance cost and should be avoided when possible. KMoussa suggested a good approach you can follow that avoids reflection and thus is much better than the reflection approach.
You could use reflection OR you could keep some type safety and use something called the 'Curiously recurring template pattern'. It uses generics, if you aren't familiar with that concept, I would do some reading up as they are very powerful, useful and prevalent in the .Net Eco system. Any way, here is what I would do
public abstract class Animal<T>
where T : Animal<T>
{
public string Name {get; private set;}
public Animal(string name)
{
Name = name;
}
public abstract T Reproduce();
public static T Reproduce(T animalToReproduce)
{
return animalToReproduce.Reproduce();
}
}
public class Lion : Animal<Lion>
{
public Lion(string name)
: base (name)
{
}
public override Lion Reproduce()
{
return new Lion(RandomName());
}
}
Then you can just call Animal.Reproduce(yourAnimalInstance)
this will return an object of the correct type. For example
Lion myLion = GetALionFromSomewhere();
Lion babyLion = Animal.Reproduce(myLion);
That will compile and you've got all the goodness of type safety

Generic interface implementing multiple generic types - how to share a method implementation?

Let's say I have the following interface
public interface IFilter<T>
{
IEnumerable<T> ApplyFilter(IEnumerable<T> list);
}
And a specific implementation like this:
public class PetFilter: IFilter<Dog>, IFilter<Cat>
{
public IEnumerable<Dog> ApplyFilter(IEnumerable<Dog> list)
{
return ApplyFilter<Dog>(list);
}
public IEnumerable<Cat> ApplyFilter(IEnumerable<Cat> list)
{
return ApplyFilter<Cat>(list);
}
private IEnumerable<T> ApplyFilter<T>(IEnumerable<T> list)
{
// do the work here
}
}
Is there any way to avoid having to implement separate methods for both Dog and Cat, given that they share the same implementation?
Yes and no. When you're using generics without any constraints the compiler would have no way of knowing of how to operate on the different classes (even if they were somehow related). Think for example how would the compiler know that ApplyFilter would work on both the Cat and the Dog classes? To it Dog and Cat are completely separate things.
However considering that both of your classes inherit from the same base class you can then operate on them through their common base class (or interface), but your PetFilter class would need to be generic as well.
public abstract class Pet
{
}
public class Dog : Pet
{
}
public class Cat : Pet
{
}
Below is a generic PetFilter class, it inherits IFilter, and even though IFilter doesn't have a generic constraint, you can add one to the PetFilter class.
public class PetFilter<T> : IFilter<T> where T : Pet
{
public IEnumerable<T> ApplyFilter(IEnumerable<T> list)
{
throw new NotImplementedException();
}
}
Yes, given that Dog and Cat both inherit from a common base class or implement a common interface like e.g. IAnimal. Then for instance:
private IEnumerable<T> ApplyFilter(IEnumerable<T> list)
where T:IAnimal
{
// do the work here
}
In other words, if Cat and Dog share the filtering logic, it surely refers to a common base.

Why we do create object instance from Interface instead of Class?

I have seen an Interface instance being generated from a class many times. Why do we use interface this way? An interface instance is created only itself with the help of the derived class and we can access only these interface members through this instance. How does this give an advantage? I'm so confused.
interface IPrint
{
void Print();
}
class Sample : IPrint
{
public void Print()
{
Console.WriteLine("Print...");
}
public void Sample()
{
Console.WriteLine("Sample...");
}
}
class Program
{
static void Main(string[] args)
{
IPrint print = new Sample();
print.Print();
}
}
Interfaces define that a class MUST be able to do something. This means that you know the object being worked on will do what you want to be able to do. It allows you greater freedom and is one of the advantages of OOP. This is a deep topic but a very basic example would be this:
public interface IAnimal
{
string Speak();
}
public class Dog : IAnimal
{
public string Speak()
{
return "Woof, woof";
}
}
public class Cat : IAnimal
{
public string Speak()
{
return "Meow";
}
}
public class Parrot : IAnimal
{
public string Speak()
{
return "Sqwark!";
}
}
Then you could use any animal you like!
class Program
{
static void Main(string[] args)
{
// Writes Woof, Woof
IAnimal animal = new Dog();
Console.WriteLine(animal.Speak());
// Now writes Meow
animal = new Cat();
Console.WriteLine(animal.Speak());
// Now writes Sqwark etc
animal = new Parrot();
Console.WriteLine(animal.Speak());
}
}
This also allows you to then get into things like Inversion Of Control where you would take an item in like this and you could pass a dog, cat or parrot and the method would always work, not knowing or caring which animal it was:
public void ShoutLoud(IAnimal animal)
{
MessageBox.Show("Shout " + animal.Speak());
}
This then makes ShoutLoud unit testable because you could use a mock object rather than a real animal. It basically makes your code flexible and dynamic rather than rigid and tightly coupled.
Also, expanding on Matthew's question. In C# you can only inherit from one base class but you can have multiple interfaces. So, you could have:
public class Dog : IAnimal, IMammal, ICarnivor
This allows you to have small interfaces (recommended) that then allow you to build up so giving maximum control over what an item can / must do.
Using an interface this way gives you the ability to create methods that use standard template of the interface. So here you might have many classes of printer that all inherit from IPrinter
class SamsungPrinter : IPrinter
{
// Stuff and interface members.
}
class SonyPrinter : IPrinter
{
// Stuff and interface members.
}
interface IPrinter
{
void Print();
}
So for each type SamsungPrinter, SonyPrinter, etc. you can pre-process using something like
public static void PreProcessAndPrint(IPrinter printer)
{
// Do pre-processing or something.
printer.Print();
}
You know from inheriting from IPrinter and using that type in the method parameters that you can always safely use the Print method on what ever object is passed.
Of course there are many other uses for using interfaces. One example of their use is in design patterns, in particular the Factory and Strategy patterns. The description of which and examples can be found here.
I hope this helps.
But how does this differ from, for example, using a base class with virtual methods?
You are all in the assumption that one programmer or one program writes the interface and the classes, but this doesn't always have to be this way.
Maybe you have a complete finished program that works with animals and you have this worked out using:
public abstract class Animal { public abstract string Speak(); }
And then some day you download some awesome DLL from nuget that shows pictures for animals. The class library contains a contract - interface - 'IAnimal':
namespace AwesomeAnimalLibrary
{
public interface IAnimal
{
string AnimalName;
}
}
The class library also maybe contains :
namespace AwesomeAnimalLibrary
{
public class AnimalPhotos
{
[Byte] GetPhotos(IAnimal animal);
}
}
What could you do now ? Your bas class Animal can implement the AwesomeAnimalLibrary IAnimal interface and that's it.
Don't assume that other people will use you abstract base classes but work together using interface contracts.
Interface can not have instance because interface implements only signatures of properties or methods. Interface is just a pointer to an instance of some class:
interface IExample
{
// method signature
void MyMethod();
}
public class MyClass : IExample
{
// method implementation
public void MyMethod()
{
ConsoleWriteline("This is my method");
}
}
// interface pointing to instance of class
IExample ie = new MyClass();
ie.MyMethod();

Inherit from a base class and provide the inheritance type to overridden method

I have a base class with a method that can be overridden. If I inherit a class from this base class how can I make the method return the inherited type?
Like:
public class ClassA : BaseClass
{
public override ClassA TestMethod(...)
{
// ...
}
}
Do I need to provide a type manually to the base class ? Or can I make it provide that type automatically?
You could use a generic type to do it.
public class BaseClass<T> where T : BaseClass<T> {
public abstract T TestMethod(...);
}
public class ClassA : BaseClass<ClassA>
{
public override ClassA TestMethod(...)
{
// ...
}
}
Why do you need it? Might lead to better suiting answers...
The feature you want has a name; this is return type covariance.
The reasons it is not supported in C# are here:
Why C# doesn't allow inheritance of return type when implementing an Interface
The other answers are all suggesting that you use the C# version of the curiously recurring template pattern to solve your problem. My opinion is that the pattern makes more problems than it solves. See my article on that subject for more details:
http://blogs.msdn.com/b/ericlippert/archive/2011/02/03/curiouser-and-curiouser.aspx
A better way to solve this problem is to use this pattern:
abstract class Animal
{
protected abstract Animal ProtectedGetMother();
public Animal GetMother()
{
return this.ProtectedGetMother();
}
}
class Cat : Animal
{
protected override Animal ProtectedGetMother()
{
do the work particular to cats here
make sure you return a Cat
}
public new Cat GetMother()
{
return (Cat)this.ProtectedGetMother();
}
}
The problem is that you cannot override a virtual method with a different return type. So don't. Make a brand new method with a different return type and make the virtual method an implementation detail of the class hierarchy.
This technique is approximately one billion times easier to understand than this Cat : Animal<Cat> "a cat is an animal of cat" nonsense.
You can do this in a generic way:
public abstract class Base
{
public abstract T AbstractTestMethod<T>() where T : Base;
public virtual T VirtualTestMethod<T>() where T : Base, new()
{
return new T();
}
}
public class ClassA : Base
{
public override ClassA AbstractTestMethod<ClassA>()
{
return new ClassA();
}
public override ClassA VirtualTestMethod<ClassA>()
{
return new ClassA();
}
}
Using virtual methods behaves not as strict as using abstract methods. Using the abstract way you can force developers to implement the method on their own. Using the virtual way you can tell them something like "meet my constraints and feel free to use the default behaviour".

Categories