Reputation: 2604
I have many T arrays to read. Each T array can represent data of type A, B or C. A: A list of T B: A single T C: Exactly three T
When I read a T array, I will be able to get a list of T, and determine by reading the first T in the list whether it's of type A, B or C. I thought of two possible approaches and would like to know their merits and cons.
1)
enum {A, B, C};
class X {
enum dataType;//A, B or C
List<T> data;//just store all as list of T
//other essential methods/properties
//throws exception if an instance cannot fit into either A, B or C.
X(T[] input)
{
//read input
}
}
2)
abstract class X
{
abstract int length{get;}
//and other common essential methods/properties
}
class A : X
{
List<T> data;
}
class B : X
{
T data;
}
class C : X
{
T data1, data2, data3;
}
class ConcreteX: X
{
List<T> data;
ConcreteX(T[] input)
{
//reads input and stores T(s) into data
}
}
class XFactory
{
getX(T[] input)
{
ConcreteX conX = new ConcreteX(input);
//depending on whether it's A, B or C, create an instance of A, B,
//or C and map the corresponding fields from conX to the instance.
//return that instance
}
}
Upvotes: 3
Views: 175
Reputation: 18570
In OOP the second way is more acceptable. The reason is, that if you would add behaviour depending on the type (A, B or C), in first case you would have to check for the enum value. In the second case, you add the specific behaviour to concrete types A, B and C. If you decided to add another type or remove one of them, in first case you would have to change all occourances of the type check, in the second case, change happens only in one place.
Upvotes: 1
Reputation: 10789
Well, if you need to have the generic class accept only a range of specific types then it might be easier to record the accepted types within an array. As you have not specified a specific language I will use c#, although I cannot guarantee it can be done with other lanaguages. I suppose if the language has the ability to at runtime create instances of the type they also should have the abilty to check against the type
private static List<Type> _acceptedTypes = { typeof(Type1), typeof(Type2) ... }
X(T[] input)
{
if(!_acceptedTypes.Contains(typeof(T)))
{
throw new SomeException();
}
...
}
Although personally this is not truely ideal as it is a runtime check (i.e. you only know about it when you try to use the class). It would be better to be able to apply constraints in a generic way which .net has but only against one type (which isn't helpful in your case).
Upvotes: 0