I'm using a series of Template Pattern classes that represent different types of events.
internal abstract class DayEndingEvent : Event
{
internal void OnDayEnding(object? sender, DayEndingEventArgs e)
{
if (IsHooked) OnDayEndingImpl(sender, e);
}
protected abstract void OnDayEndingImpl(object? sender, DayEndingEventArgs e);
}
This pattern ensures that the implementation only runs if the event is "hooked", which allows other parts of the application to activate/deactivate the event by calling Hook and Unhook methods from the base Event class.
internal abstract class Event
{
public bool IsHooked {get; private set;}
public bool Hook() => !IsHooked && (IsHooked = true);
public bool Unhook() => IsHooked && !(IsHooked = false);
}
(Event is obviously more complex than this, but this is enough to get the picture).
My EventManager can instantiate one of every implementation of this pattern and hook their OnDayEnding to the appropriate handler in an external API.
This has worked fine for a while, but now I have a new requirement to add prioritization to these classes. The only way to do so (and this is a limitation of the external API) is by adding attribute [EventPriority] to the event callback. But obviously I can't annotate OnDayEnding with a priority since that would set the priority of all implementations, which defeats the whole purpose.
The attribute will have no effect anywhere else but on the callback. The only other solution I can see is to remove the Impl and just make the callback itself abstract. But that means I'd have to manually check the IsHooked flag on every implementation, which is what I want to avoid.
So question is, can anybody sugest an alternative to this pattern that would both 1) allow me to have different implementations of the callback, to which I can add priority attributes, and 2) enforce the check for IsHooked?
There are two possibilities I have come across recently when I encountered a similar problem:
Option one, have an entry method that has the required attributes:
public class SpecificImplementationClass1 : BaseClass, IInitializer
{
[SomeAttribute]
public void CallMeToInitiate(SomeType input)
{
ExecuteCommonCode(input);
}
protected override void ExecuteSpecificCode(object input)
{
var typedInput = (SomeType) input;
// ...execute whatever implementation-specific code here
}
}
public class BaseClass
{
protected void ExecuteCommonCode(object input)
{
// DoSomethingBefore(input);
ExecuteSpecificCode(input);
// DoSomethingAfter(input);
}
protected abstract void ExecuteSpecificCode(object input);
}
public interface IInitializer
{
void CallMeToInitialize(SomeType input);
}
// Get all IInitializers through dependency injection and call "CallMeToInitialize(new SomeType())" on each
Option two, use the template delegate pattern
I have two classes that I would like to share code between. These classes represent screens in my app, and both inherit from a base screen class. The first class (MyList) already exists, and encapsulates most of the behavior that I want to perform. The second class (MyNewList) needs only to slightly tweak the behavior in the first class.
Normally, I would have MyNewList inherit from MyList and be done with it. But, in this case, both classes have common code which is auto-generated into those classes. This code causes loads of warnings because MyNewList is hiding MyList members without using new or override.
To make things even stickier, some of that code could be shared 100% (exact same fields), and the rest needs to be unique to each class.
To make matters more difficult, the code generator cannot be modified to change the output. I also cannot trigger the code generation into a separate abstract base class, which would allow both classes to inherit from the common base.
The two classes represent different custom implementations. It is possible to simply use the first class and add some branching logic to perform the behavior that MyNewList wants (and eliminate MyNewList). However, my lead developer would like it to be a separate class. I understand that desire - it's cleaner if we can use inheritance, but I don't see a solution here.
Below is my code, attempting to use inheritance:
public class MyList : ScreenBase
{
protected override void PageLoad()
{
base.PageLoad();
//Do page loading type stuff
}
protected override void PageRefresh()
{
base.PageRefresh();
//Do page refreshing type stuff
}
protected override void PageClose()
{
base.PageClose();
CloseThePage(RESULT_CLOSE);
}
#region Auto-generated code
public const string RESULT_LOAD = "Load";
public const string RESULT_BACK = "Back";
public const string RESULT_CLOSE = "Close";
public string Property_Date
{
get { /*get date from somewhere*/ }
set { /*assign date to somewhere*/ }
}
public void CloseThePage(string result)
{
//Route to next location based on result
}
#endregion
}
Second screen:
public class MyNewList : MyList
{
protected override void PageLoad()
{
base.PageLoad();
//Do additonal page loading behavior
}
//allow the rest of the base behavior to take over
#region Auto-generated code
public const string RESULT_LOAD = "Load";
public const string RESULT_BACK = "Back";
public const string RESULT_CLOSE = "Close";
public string Property_Date
{
get { /*get date from somewhere*/ }
set { /*assign date to somewhere*/ }
}
public void CloseThePage(string result)
{
//Completely different routing behavior here
}
#endregion
}
Everything inside of the #region Auto-generated code region shows hiding warnings with this approach.
How can I reuse MyList's event code from inside of MyNewList?
I'm working on a legacy application wich has some flaws due to inheritance, but I'm struggling to solve it properly.
At the moment the structure of the WinForms looks like this:
BaseForm
ListViewForm : BaseForm
ListViewFormReadOnly : ListViewForm
ListViewFormWithDetailForm : ListViewForm
DetailForm : BaseForm
ConcreteForm : ListViewFormWithDetailForm
There is a method inside the BaseForm which is called sth like protected virtual void InitializeMyStuff() which is overwritten in the inherited instances.
e.g.
public class BaseForm {
public BaseForm() {
//.. do stuff
//.. do other stuff like initialize DB connection or read app.config values and initialize properties..
}
public virtual void InitializeMyStuff() {
throw new NotImplementedException();
}
}
public class ListViewForm : BaseForm {
protected BindingSource GridBindingSource { get; set; }
public ListViewForm {
//do special stuff like adding the grid and some buttons
}
}
public class ConcreteForm : ListViewForm {
public override void InitializeMyStuff() {
GridBindingSource = my_bindingSource;
SomeOtherUsefulProperty = myValue;
Foo = new Bar();
// etc.
}
}
//Usage:
var myForm = new ConcreteForm();
myForm.InitializeMyStuff();
As you can imagine this creates some problems like:
- "What things do I have to set at this point for the form to work"
- "What things may not be initialized yet?"
- "Which properties and method calls are at my disposal yet"
and some other interesting thoughts about what may be going on in that magic blackbox.
How can I refactor this so that it gets more clear what is happening? Remember that this is a project with about 150 or more concrete forms.
My initial thought was to encapsulate those magic properties like the GridBindingSource for example into an object (e.g. FormConfiguration) and make it private in the BaseForm.
e.g. something like that
public class BaseForm {
private FormConfigObject _formConfig = new FormConfigObject();
protected override void OnLoad()
{
InitializeMyStuff(_formConfig);
}
protected virtual void InitializeMyStuff(FormConfigObject config)
{}
}
The problem I have here is: the FormConfig object of the ListForm would have to have other properties for example, like GridBindingSource but I can't just change the signature in the derived classes to an ListFormConfigObject isntead of the FormConfigObject..
Can anybody suggest possible solutions to get out of this dilemma?
// Edit: straightnened out the code to what actually happens and getting rid of the virtual call in the constructor violation.
The main question is this: are there any objects inside BaseForm that:
are required to be initialized in BaseForm's constructor
depend on the concrete implementation of the subclasses
If such objects exist then probably they should be made polymorphic, and passed into BaseForm's constructor from subclasses.
A simple example, on of many possible scenarios:
abstract class RandomPicture
{
public RandomPicture()
{
shapes = new List<Shape>();
InitializeRandomShapes();
// do some initial drawing calculations
}
protected abstract void InitializeRandomShapes();
protected List<Shape> shapes;
}
//... subclasses initialize the shapes
This can be changed to:
abstract class RandomPicture
{
public RandomPicture(AbstractShapeCollection shapeCollection)
{
shapes = shapeCollection;
// do some initial drawing calculations
}
private AbstractShapeCollection shapes;
}
And now subclasses provide the required information through the abstract object, so the base class can proceed with it's task.
Splitting information into various objects like this is a good refactoring start, as you create more smaller objects, that are easier to test and manage and reveal the underlying structure of a mess that you've encountered. It helps also to reduce the number of violations of Single Responsibility Principle.
We're working with XML and want a common interface amongst the main XML class and all of its components. However, sub-components of the XML class need additional methods, but they also need the main component's methods. Seems like a great use for inheritance.
Here is some code I wrote to accomplish this task. Hopefully, you can get a good idea of what we're going for based on usage:
using System;
namespace SampleNamespace
{
public class SampleClass
{
public static void Main()
{
var xmlDocumentFiles = new XmlDocumentFiles();
xmlDocumentFiles.Files.RootFile.SetFileName("Example.xml");
System.Console.WriteLine(
xmlDocumentFiles.Files.RootFile.GetFileName()
);
}
}
public class XmlDocumentFilesRoot
{
protected string _rootFileName;
public FilesClass Files { get { return (FilesClass) this; } }
}
public class FilesClass : XmlDocumentFilesRoot
{
public RootFileClass RootFile { get { return (RootFileClass) this; } }
}
public class RootFileClass : FilesClass
{
public void SetFileName( string newTitle )
{
_rootFileName = newTitle;
}
public string GetFileName()
{
return _rootFileName;
}
}
public class XmlDocumentFiles : RootFileClass
{
}
}
I was able to cast to child classes and to my surprise it runs just fine. Assuming nothing is put inside of the sub-classes other than methods which wouldn't make sense in the parent, will there ever be any problems (weird compilation errors, runtime crashes) with this class structure?
Are there any alternatives? I had initially tried nested classes + extension methods located outside of the main class, but there was a lot of code needed to set that up. See: https://stackoverflow.com/questions/19415717/using-c-sharp-extension-methods-on-not-in-nested-classes-to-establish-a-common
Extending functionality of a class, sounds like a decorator pattern.
Here's a head-first pdf on this subject:
http://oreilly.com/catalog/hfdesignpat/chapter/ch03.pdf
Also; I would like to discourage the triple '.' :
xmlDocumentFiles.Files.RootFile.SetFileName("Example.xml");
2 is evil, if you need 3: you will definitely lose maintainability.
Hope it helps.
I kinda know what polymorphism is but failed to understand it clearly. Also my code is following:
class Human
{
public virtual void CleanTheRoom()
{
}
}
class Woman:Human
{
public override void CleanTheRoom()
{
//women clean faster
}
}
class Man:Human
{
public override void CleanTheRoom()
{
//men clean slower, different code here
}
}
class Child:Human
{
public override void CleanTheRoom()
{
//empty ... children are lazy :)
}
}
Should I explain this is polymorhism because all derived classes from base class Human contain method CleanTheRoom but each of them it implements differently?
The benefit of polymorphism comes when you want to invoke the method on some type of Human, but you don't care which one specifically.
By having CleanTheRoom() defined at the base class level, Human, you can write shorter, cleaner code elsewhere in your application whenever you are working with an instance of Human, whether it be a Child or otherwise.
Polymorphism, for example, lets you avoid lengthy conditional statements where you explicitly check for each type of Human and call a different method:
Good:
private void SomeMethod(Human h)
{
//some logic
h.CleanTheRoom();
//more logic
}
Bad:
private void SomeMethod(Human h)
{
//some logic
if (h is Adult)
CleanTheRoom();
else if (h is Child)
GoofOff();
//some logic
}
What you have is a good example of inheritance. Polymorphism refers specifically to being able to refer to objects of different types by using a single type (the parent class or interface), something this type of inheritance makes possible. Like so:
List<Human> humans = new ArrayList<Human>();
humans.add(new Woman());
humans.add(new Woman());
humans.add(new Man());
humans.add(new Child());
humans.add(new Child());
foreach(Human hum in humans) {
hum.CleanTheRoom(); //I don't know the type of hum, but I don't care
}
Say I've been collecting instances of Human from various locations -- I don't know what type each one is. But I can still iterate over them and call CleanTheRoom(), because they share a parent class.
I'll add a real-world example. Say I have an Invoice class with various subclasses for different types of Invoices -- maybe there are different kinds of Invoices for service clients versus customers who make one-time purchases. Sometimes I care deeply about the differences, and I only deal with one type. But sometimes I want to loop through all of the invoices for this month and print them out. If the parent class has a print() method (which may well be implemented differently by different types) then I can do that.
Yes, that is correct. And you can call the method CleanTheRoom() without knowing which "kind" of human is it.
Here you have some basic examples.
I think you fail to see the benefit, that's the key you're missing to fully understand polymorphism. I will try to make an example:
Let's say you have a simple CRUD form. This is the code of the save button:
var Client = PopulateDTO(); //put all the values in the controls, to an object
if(Action==Actions.Create){
_repository.Create(Client);
}
else if(Action==Actions.Update){
_repository.Update(Client);
}
else if(Action==Actions.Delete){
_repository.Delete(Client);
}
this.Close();
This code works, but it's bad code, and difficult to read. Let's use polymorphism (and the strategy pattern):
public abstract class BaseStrategy{
abstract void Do(ClientDto Client);
}
public class CreateStrategy:BaseStrategy{
public override void Do(ClientDto Client){
_repo.Save(Client);
}
}
public class UpdateStrategy:BaseStrategy{
public override void Do(ClientDto Client){
_repo.Update(Client);
}
}
public class DeleteStrategy:BaseStrategy{
public override void Do(ClientDto Client){
_repo.Delete(Client);
}
}
So, we have an abstract class, and 3 implementations, each one doing something with the client object. Now, the code of the save button in the form will be:
BaseStrategy stg = GetCorrectStrategy();
var Client = PopulateDTO();
stg.Do(Client);
this.close;
And the method GetCorrectStrategy() will instantiate the correct Strategy implementation, depending if the user is creating, editing or deleting the client.
I hope this answer will help you. But if didn't help you, I suggest you read about strategy pattern, It's one of the best uses of polymorphism in my opinion
Since several people have already given fine examples of polymorphism, I'll offer a different perspective that really helped me to grok it.
In functional programming, functions are the first class concepts in contrast to OOP where objects are supreme.
Polymorphism is to OOP what pattern matching is to FP. Here is a function that uses pattern matching (using an ML style syntax).
let f x =
match x with
| T -> //do stuff with a T to return some value
| S -> //do stuff with an S to return some value
| U -> //do stuff with a U to return some value
| V -> //do stuff with a V to return some value
So when you use the function f, you can pass it an object of either type T, S, U, or V. In strongly typed FP languages like F#, the type of x is denoted T|S|U|V. Such types are commonly referred to as Sum types or Tagged Unions.
If we fix up your example to make Human an abstract class, then it will become clear that polymorphism in OOP just gives you a way of expressing a sum type.
Thus, CleanTheRoom is a function that takes a type Human. But Human is just the name for the type Man|Woman|Child which is a sum type. The big difference between languages like C# and functional languages like F# is that one treats objects as top level things while the other treats functions as top level things. Also, everything in OOP languages like C# must have names. In a functional language we could denote the type Man|Woman|Child without having to explicitly name it.
The key is not to think of the code as having different CleanTheRoom methods, but rather think of CleanTheRoom as one method that takes a type Man|Woman|Child (which is named Human). Polymorphism is just the implementation detail.
In summary, polymorphism (especially with abstract classes) basically just give you a way to name sum types and do pattern matching.
See:
http://en.wikipedia.org/wiki/Tagged_union
http://en.wikipedia.org/wiki/Algebraic_data_type
An example in C#:
This is my class file
class parent
{
public virtual string saySomething(string s)
{
return s+":Parent";
}
}
class man : parent
{
public override string saySomething(string s)
{
return s+":Man";
}
}
class woman : parent
{
public override string saySomething(string s)
{
return s+":Woman";
}
}
class child : parent
{
public override string saySomething(string s)
{
return s+":Child";
}
}
Create Four Buttons and a label.
Here is the implementation on a simple form1
private void Form1_Load(object sender, EventArgs e)
{
p1= new parent();
}
private void button1_Click(object sender, EventArgs e)
{
label1.Text = p1.saySomething("I am parent!");
}
private void button2_Click(object sender, EventArgs e)
{
p1 = new man();
label1.Text = p1.saySomething("I am man!");
}
private void button3_Click(object sender, EventArgs e)
{
p1 = new woman();
label1.Text = p1.saySomething("I am woman!");
}
private void button4_Click(object sender, EventArgs e)
{
p1 = new child();
label1.Text = p1.saySomething("I am child!");
}
Is it run-time polymorphism?
P1 is an object. Depending upon the situation (Context), a button click, it is executing different piece of code. So, p1 is behaving differently depending upon the click event.
class Program
{
static void Main(string[] args)
{
List<ICleanTheRoom> cleanerList = new List<ICleanTheRoom>
{
new Child(),
new Woman(),
new Man()
};
foreach (var cleaner in cleanerList)
{
cleaner.CleanTheRoom();
}
}
}
internal interface ICleanTheRoom
{
void CleanTheRoom();
}
// No need for super type
//class Human : ICleanTheRoom
//{
// public virtual void CleanTheRoom()
// {
// }
//}
internal class Woman : ICleanTheRoom
{
public void CleanTheRoom()
{
throw new NotImplementedException();
}
}
class Man: ICleanTheRoom
{
public void CleanTheRoom()
{
throw new NotImplementedException();
}
}
class Child: ICleanTheRoom
{
public void CleanTheRoom()
{
throw new NotImplementedException();
}
}
Is it a new object created each time at runtime, clearly inheriting but no polymorphing.