jeudi 29 octobre 2015

How to design factory pattern for different types of values in one list?

I need to design a data structure that holds different types of values (doubles, strings, datetimes, etc.). The list of types is dynamically created by user. Based on that list another list of values should be created. Then this "record" of values is to be sent by WCF and stored in dynamically created db table. I'm starting with desiging this solution in c#. My current status is shown below. I'm not satisfied with my present solution, especially with factory and enums. Is there better way to do the things right?

Enum for my types:

public enum ValueType { Decimal, String, Boolean };

then interface:

public interface IValueType
    {
        object Data { get; }
        string ToString();
        ValueType? Type { get; }
    }

base class:

public abstract class ValueType<T> : IValueType
{
    protected T _Value;

    public ValueType(T value)
    {
        _Value = value;
    }

    public object Data
    {
        get { return _Value; }
    }

    public ValueType? Type
    {
        get { return null; }
    }
    public T Value { get; private set; }
    public override string ToString()
    {
        return _Value.ToString();
    }
}

one of implementation:

public class DecimalValueType : ValueType<decimal>
{
    public DecimalValueType( decimal val ) : base(val)
    {}
    public DecimalValueType(double val) : base((decimal)val)
    {}
    public DecimalValueType(int val) : base((decimal)val)
    {}
}

then factory:

public static class ValueTypeFactory
{
    private static Dictionary<ValueType, Type> dictValueType = new Dictionary<ValueType, Type>()
    {
        { ValueType.Decimal, typeof(DecimalValueType) },
        { ValueType.String, typeof(StringValueType) },
        { ValueType.Boolean, typeof(BooleansValueType) }
    };

    private static Dictionary<Type, Type> dictSimple = new Dictionary<Type, Type>()
    {
        { typeof(decimal), typeof(DecimalValueType) },
        { typeof(double), typeof(DecimalValueType) },
        { typeof(int), typeof(DecimalValueType) },
        { typeof(string), typeof(StringValueType) },
        { typeof(bool), typeof(BooleansValueType) }
    };

    public static IValueType MakeByValueType(ValueType type, params object[] initValues)
    {
        IValueType retObject = null;
        if (dictValueType.ContainsKey(type) )
        {
            Type t = dictValueType[type];
            retObject = (IValueType)Activator.CreateInstance(t,initValues);
        }
        return retObject;
    }

    public static IValueType MakeByType(params object[] initValues)
    {
        IValueType retObject = null;
        if ( initValues.Length > 0 )
        {
            Type type = initValues[0].GetType();
            if (dictSimple.ContainsKey(type))
            {
                Type t = dictSimple[type];
                retObject = (IValueType)Activator.CreateInstance(t, initValues);

            }
        }
        return retObject;
    }
}

sample use:

    List<IValueType> lista = new List<IValueType>();
    lista.Add(new DecimalValueType(12));
    lista.Add(new StringValueType("Test"));
    lista.Add(new BooleansValueType(true));
    lista.Add(ValueTypeFactory.MakeByValueType(ValueType.Decimal, 10.1));
    lista.Add(ValueTypeFactory.MakeByType(5.12));
    lista.Add(ValueTypeFactory.MakeByType("Test2"));

I would be happy with any advice.

Aucun commentaire:

Enregistrer un commentaire