mercredi 28 octobre 2015

Using strategy to create subclasses from superclasses

I have a C#/OO/Design related question.

I am redesigning an old system that was ported to C#. We are refactoring the system to make it more simple and more object oriented.

In this system we have various objects related to our business domain - Folder, Document, User, Appointment, Task, etc. All of these objects inherit from a base object called, believe it or not, BaseObject:

public class BaseObject {
    public int Id { get; set; }
    public string Name { get; set; }
}

This object is not abstract because we actually instantiate it for some simple lists.

We also have our own Generic list:

public class CustomList<T> : IENumerable<T> where T : BaseObject {
    //... several properties and methods

    }
}

My questions is this: I have many objects that inherit from BaseObject. For example, I can create a CustomList<User> because User : BaseObject.

However, many of my user controls return CustomList<BaseObject>, simply because that is what most list-based user controls CAN return: they know each object's name because that's what they display, and they use its Id as a key.

So, I would like to be able to add the items from a CustomList<BaseObject> to any CustomList<T>. I want to be able to add objects, not just construct a new list.

But because I can't just cast from a superclass (BaseObject) to a subclass (e.g. User), I was thinking about implemeting the following method inside CustomList<T>:

public void AddRangeOfBaseObjects(IEnumerable<BaseObject> items, Func<BaseObject, T> constructor)
    {
        foreach (var item in items)
        {
            var newObject = constructor(item);
            Add(newObject);
        }
    }

Or in other words, if a class needs to create a CustomList from CustomList, it needs to supply both the CustomList and a method saying how to construct each new instance of T from BaseObject, and how to initialize its other members which BaseObject doesn't know.

I believe this is similar to a Strategy pattern. Of course the method itself hardly has any code, but due to the ubiquity of this action, it is still shorter to design it like this.

The question is - is this good design? Is there a better pattern for handling this situation of moving simplified version of objects from the UI into actual objects?

Aucun commentaire:

Enregistrer un commentaire