Question

Let's consider, as an example, the domain of GPS and Geographical (GIS) entities.

We would model the meaningful geographic entities (points, paths, regions) as classes in any desired programming language, and these classes would be a conceptual, "implementation-free" representation of these entities.

On the other hand, there are a lot of file formats that save these features with more or less the same meaning. In the GPS domain the most common file formats are GPX, KML, ShapeFile, WellKnownText, etc.

Supposing, then, I want to create a GpsFeatureCollection class which would contain a Points property, a Paths property, and so on. Also, I would implement classes like GpsReader, KmlReader, ShapeFileReader (and their respective Writers) and so on.

THE QUESTION IS:

Which is the best practice in OOAD:

  1. Have a GpsFeatureCollection to instantiate a FileFormat(Reader/Writer) class?
  2. Have a GpsFeatureCollection to implement Read/WriteFromFormat methods instead of classes?
  3. Have each file format reader to instantiate an empty GpsFeatureCollection, populate it with data read from file, then pass the populated object as a return value?
  4. Have a mediator class to avoid any dependency between FileFormatClass and ObjectModelClass?
  5. None of the above?
  6. "Well, it depends..."

I am really interested in doing "the right thing". My immediate plans are to use Python, but most probably this would matter for other languages too. This is causing some "analysis paralysis" in my pet project currently...

Was it helpful?

Solution

Here is my take wherein I pass reader and writer instances to read() and write() methods, this seems to achieve good level of decoupling and yet provides flexibility to pick various readers and writers.

Code uses Java-like syntax

Declare a Reader interface, we will assuming multiple implementation such KMLReader, ShapeFileReader, etc

interface Reader {
   GpsFeatureCollection read();
}

Declare a Writer interface, we will assuming multiple implementation such KMLWriter, ShapeFileWriter, etc

interface Writer {
   void write(GpsFeatureCollection c);
}

Let's declare GpsFeatureCollection class to have read and write methods which accept respective interfaces as parameter to perform the job.

class GpsFeatureCollection {

    ...

    public static GpsFeatureCollection read(Reader r) {
       return r.read();
    } 

    public static void write(Writer w) { 
        w.write(this);
    }

}

Some example of usage using different readers and writers.

// Reading data
GpsFeaureCollection data = GpsFeatureCollection.read(new ShapeFileReader("/tmp/shapefile"));

// Writing data
data.write(new KMLWriter("/tmp/kmlfile"));
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top