Hello,
It's been a long time since I've done some polymorhpic programming and nowI'm struggling to get my head round it again

Here's what I've got...

an interface

 public interface INote
   {
      string note { get; set; }
   }

I've 2 options dervived from this

   public class Disclipinary : INote
   {
      public string note { get; set; }
   }


   public class Absence : INote
   {
      public string note { get; set; }
   }

Now I've got the conccept of saving. So, I new up a global saver which I figured would act like delegate in order to call the right class to save it but sadly it doesn't work... or rather I'm ina pickle

 public class GlobalSaver
   {
      public void saveMe(INote note )
      {

      }
   }

   public interface businessRules
   {
     void Save(INote note);
   }

   public class AbsenceSaver : businessRules
   {
      public  void Save(INote note)
      {

      }
   }

   public class DisciplinarySaver : businessRules
   {
      public  void Save(INote note)
      {

      }
   }

And then called from main

 Absence a = new Absence();
         GlobalSaver saver = new GlobalSaver();
         saver.saveMe(a);

What I'm after is newing up a absence or disciplinary and then saving it without having to either do a switch or a cast in order to know which save routine to call. Surely it should know which one to call based on the object?

If you want to do this kind of inversion then you will need to implement the saveMe function on the INote interface.

Some would argue this breaks the seperation of concerns design methodology though.

Do they actually equire separate saving methodolgies?

Yup since they're linked to two different tables in the database. I can't change that, and the underlying logic within their methods is completely different. The INote shouldn't get the save me since its just a data object. The save routines are writen has part of the DAL (Data access layer) and thus should be responsible?

Edited 3 Years Ago by Acidburn

This is what I've come up with in the end.......

   public class Disclipinary : INote
   {
      public string note { get; set; }
   }


   public class Absence : INote
   {
      public string note { get; set; }
   }

   public interface INote
   {
      string note { get; set; }
   }

 public interface businessRules
   {
     void Save(INote note);
   }

 public class GlobalSaver : Saver
   {

   }

   public abstract class Saver
   {
      public virtual void Save(Absence a)
      {
      }

      public virtual void Save(Disclipinary s)
      {
      }
   }
}

and called by

   Absence a = new Absence();
         GlobalSaver saver = new GlobalSaver();
         saver.Save(a);

If you truly wanted to have the data object handling its own Save method though I'd do a design something like this...

public interface INote
{
    String Note { get; } // I generally only enforce Get. I don't like being able to Set on interfaces
    void Save();
}

public interface IBusinessRules
{
    void SaveNote(INote note);
}

public class SickNoteSaver : IBusinessRules
{
    public void SaveNote(INote note)
    {
        // Do stuff specific to saving the Sick Note
        // You will need to cast the INote to SickNote
    }
}

public class AbsenceNoteSaver : IBusinessRules
{
    public void SaveNote(INote note)
    {
        // Do stuff specific to saving Absence Note
        // You will need to cast the INote to AbsenceNote
    }
}

public abstract class Note : INote
{
    private readonly IBusinessRules _businessRules;
    public String Note { get; set; }

    public Note(IBusinessRules businessRules)
    {
        _businessRules = businessRules;
    }

    public void Save()
    {
        _businessRules.SaveNote(this);
    }

}

public class SickNote : Note
{
    // Put some class specific stuff in here
}

public class AbsenceNote : Note
{
    // Put some class specific stuff in here
}

Hmm.. I dont like having the save routine part of the object. This object is passed around quite a lot. Through the business layer - DAL layer and the presentation layer.

Hence my design.

I do like it though :)

This article has been dead for over six months. Start a new discussion instead.