10 Replies Latest reply on Sep 24, 2009 10:03 PM by 843789

    extending Collections - ArrayList\Set

    843789
      hi all!
      i have an issue concerning "software design".
      sometimes i find myself creating a class where i have only one variable which is a Collection.here ill take an ArrayList for example.
      then the only work i do in the class, is on this ArrayList.
      so i find myself extending the class with arraylist:
      class AClass extends ArrayList<T> {
      }
      is that the way of doing it? should i extend an ArrayList in such a case?

      lets take a more specific example.
      i have a class DataReader to read data out of given file. the class reads the file only once, and get the data as an ArrayList<String[]>. the class uses one method loadFile(String filename);
      public class DataReader extends ArrayList<String[]>{
      //declare some constants neede for the file reading
      public DataReader(){
      }
      public void readFile(String filename){
      //reading the file
      String[] tempLine; //each line is String[] type 
      this.add(tempLine);//adding the line for the arraylist
      }
      }
      thats it. i use a DataReader object inside DataBaseClass, to read the data and then transfer it inside the DataBaseClass.
      so here it seems better to extend the ArrayList.
      what do you think?

      Thanks!
        • 1. Re: extending Collections - ArrayList\Set
          843789
          Very rarely do you want to extend ArrayList (or any Collection implementation at all) like this.

          Because if your class does something other than being a Collection, then it should not be a collection but have a collection instead.

          In your specific example, I'd ask this design-question:

          What is the DataReader? Is it the thing that reads the data or is it the data that is being read? Is it both? If it's both, then you are clearly violating the [single-responsibility principle|http://en.wikipedia.org/wiki/Single_responsibility_principle].

          The DataReader should return a List from some method, not implement List.
          • 2. Re: extending Collections - ArrayList\Set
            843789
            JoachimSauer wrote:
            What is the DataReader? Is it the thing that reads the data or is it the data that is being read? Is it both? If it's both, then you are clearly violating the [single-responsibility principle|http://en.wikipedia.org/wiki/Single_responsibility_principle].
            Tell that to [java.util.Properties|http://java.sun.com/j2se/1.5.0/docs/api/java/util/Properties.html] :P.
            • 3. Re: extending Collections - ArrayList\Set
              843789
              endasil wrote:
              JoachimSauer wrote:
              What is the DataReader? Is it the thing that reads the data or is it the data that is being read? Is it both? If it's both, then you are clearly violating the [single-responsibility principle|http://en.wikipedia.org/wiki/Single_responsibility_principle].
              Tell that to [java.util.Properties|http://java.sun.com/j2se/1.5.0/docs/api/java/util/Properties.html] :P.
              Properties JavaDoc sayz:Since: JDK1.0
              That says it all, really ;-)
              • 4. Re: extending Collections - ArrayList\Set
                843789
                JoachimSauer wrote:
                endasil wrote:
                JoachimSauer wrote:
                What is the DataReader? Is it the thing that reads the data or is it the data that is being read? Is it both? If it's both, then you are clearly violating the [single-responsibility principle|http://en.wikipedia.org/wiki/Single_responsibility_principle].
                Tell that to [java.util.Properties|http://java.sun.com/j2se/1.5.0/docs/api/java/util/Properties.html] :P.
                Properties JavaDoc sayz:Since: JDK1.0
                That says it all, really ;-)
                Every software engineer that's ever worked on the JLS or Java platform must absolutely hate the requirement for backwards compatability. Especially prior to 1.2, when everything was still, for many intents and purposes, in a beta phase.
                • 5. Re: extending Collections - ArrayList\Set
                  843789
                  JoachimSauer wrote:
                  endasil wrote:
                  JoachimSauer wrote:
                  What is the DataReader? Is it the thing that reads the data or is it the data that is being read? Is it both? If it's both, then you are clearly violating the [single-responsibility principle|http://en.wikipedia.org/wiki/Single_responsibility_principle].
                  Tell that to [java.util.Properties|http://java.sun.com/j2se/1.5.0/docs/api/java/util/Properties.html] :P.
                  Properties JavaDoc sayz:Since: JDK1.0
                  That says it all, really ;-)
                  Though I also feel obliged to show:
                  storeToXML ...
                  Emits an XML document representing all of the properties contained in this table. ...
                  Since:
                  *1.5*
                  • 6. Re: extending Collections - ArrayList\Set
                    843789
                    thanks JoachimSauer.

                    so that single-responsibility principle also applies on methods?
                    should my methods also perform only one task?
                    in my example, DataReader, the readFile(String filename) method should only read, and a get() method would be to retrieve the data in the ArrayList?
                    and i must not do it that way:
                    public ArrayList<String[]> getData(String filename){
                    //read the file, and pass the data to a new ArrayList<String[]> object: "dataList"
                    retrun dataList;
                    }
                    Thanks!
                    • 7. Re: extending Collections - ArrayList\Set
                      3004
                      japanir wrote:
                      thanks JoachimSauer.

                      so that single-responsibility principle also applies on methods?
                      should my methods also perform only one task?
                      Yes, but the definition of "one task" is somewhat flexible.
                      in my example, DataReader, the readFile(String filename) method should only read, and a get() method would be to retrieve the data in the ArrayList?
                      and i must not do it that way:
                      public ArrayList<String[]> getData(String filename){
                      //read the file, and pass the data to a new ArrayList<String[]> object: "dataList"
                      retrun dataList;
                      }
                      It's perfectly legitimate to have one method that does both of those things. But if there's a clear division between those two steps, and each one can be broken down into several smaller sub-steps, it's probably a good idea to break those two steps out into separate methods.
                      • 8. Re: extending Collections - ArrayList\Set
                        DrClap
                        And you can do that repeatedly. For example, when you get home tonight your task might be "Have Dinner". This looks like this:
                        Decide what I want for dinner.
                        If pizza:
                          Call pizza delivery company
                          Wait for pizza to arrive
                        Else:
                          If I don't have all the ingredients
                            Go shopping for ingredients
                          Make dinner
                        Eat dinner
                        Now there are several sub-tasks in there. Obviously some of them can be broken down into separate tasks... you can try that for an exercise if you like. It's the same in programming.
                        • 9. Re: extending Collections - ArrayList\Set
                          3004
                          DrClap wrote:
                          And you can do that repeatedly. For example, when you get home tonight your task might be "Have Dinner". This looks like this:
                          Decide what I want for dinner.
                          If pizza:
                          Call pizza delivery company
                          Wait for pizza to arrive
                          Else:
                          If I don't have all the ingredients
                          Go shopping for ingredients
                          Make dinner
                          Eat dinner
                          Now there are several sub-tasks in there. Obviously some of them can be broken down into separate tasks... you can try that for an exercise if you like. It's the same in programming.
                          Precisely. So if this is the body of the "Have Dinner" method, you can see it has several steps, but they're all part of the same overall single, cohesive job of "having dinner". You would probably not add a "Wash Dishes" step inside the "Have Dinner" method, but you might put "Have Dinner" and "Wash Dishes" inside "Perform Evening Routine", along with "Get Drunk," "Watch TV," and "Pass Out."

                          And if you ask 5 different programmers, you'll probably get 10 or 15 different answers as to how to divide things up (because every programmer has as least 2 or 3 ways of doing a given task), so there is not usually one clear-cut "right" answer.
                          • 10. Re: extending Collections - ArrayList\Set
                            843789
                            japanir wrote:
                            readFile(String filename)
                            Your question has already been answered very nicely, but there's one tiny hint that I'd like to give here.

                            Whenever I write a method that looks like this: "load(String filename)" I'll find that I regret it sooner or later.

                            Because at first I only want to read from a file, then I'll realize I might want to read from an URL. And finally I'll find that I want to load from any given Data source (stored in database? no problem! data already in memory? sure enough!).

                            So for those methods the best parameter type is usually an InputStream (or a Reader, if you're handling text data).