Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Value" member field can be one of four different types - best design?

I have a class called "DataModel" or something, which is basically a unit of data which can be either a string or a number or a date or a boolean with various (identical) attributes.

What is the best way to write this model?

  1. Have the value be of type Object

    interface DataModel {
       Object getValue();  // cast to whatever is needed
       int getValueType(); // uses four constants
    }
    
  2. Have four different implementations "StringModel", "NumberModel", etc., each with their own typed "getValue()" method. This means if you had a DataModel, you'd have to cast to the correct Model to get to the value.

    interface DataModel {
       int getValueType();
    }
    interface NumberDataModel extends DataModel {
      Integer getValue();
    }
    ...
    
  3. Have four different methods, each throwing an exception if called for a wrong value type:

    interface DataModel {
      String getStringValue();
      Integer getIntegerValue();
      ...
      int getValueType();
    }
    
  4. Use generics. This has the downside that I theoretically could have any object of any type...on the other hand I could just throw an IllegalStateException in the constructor if T was not one of the 4 allowed types...

    interface DataModel<T> {
      T getValue();
    }
    
  5. It doesn't matter. Any of the above. ;)

like image 337
Epaga Avatar asked Jan 22 '26 01:01

Epaga


2 Answers

4 seems the best - even if you don't want to implement any old type there's no particular reason why you shouldn't theoretically allow it - it won't interfere with anything else you're doing.

like image 198
cyborg Avatar answered Jan 23 '26 13:01

cyborg


1 is fine if you don't plan to add many/any new types AND you don't need to allow 3rd parties to add their own types. I would probably use an enum rather than an int.

I don't see much advantage of doing 2 over 4. 4 is generic, tho you may want to include the getValueType() even in the generic case so that you can have code interrogate the type at runtime, often useful.

I don't think 3 is the right way to go unless the content of your model supports being retrieved in different ways (like JDBC does somewhat) but I don't think that is the case here.

From past experience I would do 4 and add the getValueType() to it.

like image 39
Mike Q Avatar answered Jan 23 '26 14:01

Mike Q