2
\$\begingroup\$

I have created a polymorphic system, but I don't know whether this is the correct way of doing it. Am I abusing Polymorphism here? Here is the code:

class WriteObj
{
    public string Obj1 { get; set; }
    public string Obj2 { get; set; }
    public string Obj3 { get; set; }
}

The above code is a data object that I am passing around in the methods, since I would be using a List of these objects.

abstract class BaseWriter
{
    public abstract void Write(List<WriteObj> writeObjList);
}

class ConsoleWriter : BaseWriter
{
    public override void Write(List<WriteObj> writeObjList)
    {
        for (int i = 0; i < writeObjList.Count; i++)
        {
            Console.Writeline("I am in Console Writer, parameter: " + writeObjList[i].Obj1);
        }

    }
}

class FileWriter : BaseWriter
{
    public override void Write(List<WriteObj> writeObjList)
    {
        for (int i = 0; i < writeObjList.Count; i++)
        {
            Console.Writeline("I write in file, parameter: " + writeObjList[i].Obj1);
        }
    }
}

class DatabaseWriter : BaseWriter
{
    public override void Write(List<WriteObj> writeObjList)
    {
        for (int i = 0; i < writeObjList.Count; i++)
        {
            Console.Writeline("I write in database, parameter: " + writeObjList[i].Obj2);
        }
    }
}

In my main method I call them like:

    static void main()
    {
        List<WriteObj> col = new List<WriteObj>();
        col.AddRange(new WriteObj[2] { new WriteObj { Obj1 = "this is obj1 iteration 1", Obj2 = "This is obj2 iteration 1" }, 
            new WriteObj { Obj1 = "this is obj1 iteration 2", Obj2 = "This is obj2 iteration 2" } });

        //some factory will generate these concrete types, 
        //but the sake of simplicity I am instantiating it like that.
        BaseWriter a = new ConsoleWriter();
        a.Write(col);

        BaseWriter b = new FileWriter();
        b.Write(col);

        BaseWriter c = new DatabaseWriter();
        c.Write(col);
    }

Is it Ok to pass List of WriteObj in the Write method of the respective concrete implementations?


Update : I have used abstract class because it will be having some methods in it. I haven't mentioned it here for the sake of simplicity.

\$\endgroup\$
  • 1
    \$\begingroup\$ Seems ok. I might consider making the Writer method take a more generic parameter, perhaps ICollection or even a ReadOnlyCollection to enforce an abstraction that the method is there to write the data and not alter it? \$\endgroup\$ – dreza Aug 25 '13 at 9:48
4
\$\begingroup\$

Yes, I don't see a problem with that.

If you don't have any implementation at all in the base class, consider making it an interface instead:

interface IWriter {
    void Write(List<WriteObj> writeObjList);
}

class ConsoleWriter : IWriter {
  public void Write(List<WriteObj> writeObjList) {
    foreach (WriteObj obj in writeObjList) {
      Console.Writeline("I am in Console Writer, parameter: " + obj.Obj1);
    }
  }
}

etc.
\$\endgroup\$
0
\$\begingroup\$

Yes, you could take that way. I would recomend to make BaseWriter an interface IWriter too. But I have an other suggestion.

interface IWriter
{
    void Write(List<WriteObject> writeObjectList);
}

public class ConsoleWriter : IWriter
{
    public void Write(List<WriteObject> writeObjectList)
    {
        // your implementation
    }
}

public class Writer // bad name but I dont have a better now
{
    private IWriter _writer; // or make it public and delete the constructor

    public Writer(IWriter writer)
    {
        _writer = writer;
    }

    public void Write(List<WriteObject> writeObjectList)
    {
        _writer.Write(writeObjectList);
    }
}

In this case, you do not use polymorphism. So your design is more flexible. You could change the way of writing your objects while runtime. Give it a try ;-)

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.