OOAD — класс File-Format-Reader и класс Object-Model: что должно зависеть от чего?

Рассмотрим, в качестве примера, область GPS и географических (ГИС) объектов.

Мы моделировали бы значимые географические объекты (точки, пути, регионы) как классы на любом желаемом языке программирования, и эти классы были бы концептуальным представлением этих объектов без реализации.

С другой стороны, существует множество форматов файлов, которые сохраняют эти функции с более или менее одинаковым значением. В домене GPS наиболее распространенными форматами файлов являются GPX, KML, ShapeFile, WellKnownText и т. д.

Предположим, что я хочу создать класс GpsFeatureCollection, который будет содержать свойство Points, свойство Paths и так далее. Кроме того, я бы реализовал такие классы, как GpsReader, KmlReader, ShapeFileReader (и соответствующие им Writer) и так далее.

ВОПРОС В ТОМ:

Что является лучшей практикой в ​​OOAD:

  1. У вас есть GpsFeatureCollection для создания экземпляра класса FileFormat(Reader/Writer)?
  2. Есть GpsFeatureCollection для реализации Read/WriteFromFormat методов вместо классов?
  3. Пусть каждая программа чтения форматов файлов создаст экземпляр пустого GpsFeatureCollection, заполнит его данными, прочитанными из файла, а затем передаст заполненный объект в качестве возвращаемого значения?
  4. У вас есть класс-посредник, чтобы избежать зависимости между FileFormatClass и ObjectModelClass?
  5. Ни один из вышеперечисленных?
  6. "Смотря как..."

Мне действительно интересно делать «правильные вещи». В ближайших планах использовать Python, но, скорее всего, это будет иметь значение и для других языков. В настоящее время это вызывает некоторый «аналитический паралич» в моем любимом проекте...


person heltonbiker    schedule 12.07.2013    source источник


Ответы (1)


Вот мой подход, когда я передаю экземпляры чтения и записи методам read() и write(), это, кажется, обеспечивает хороший уровень разделения и, тем не менее, обеспечивает гибкость для выбора различных читателей и записывающих устройств.

Код использует синтаксис, подобный Java.

Объявите интерфейс Reader, мы предполагаем несколько реализаций, таких как KMLReader, ShapeFileReader и т. д.

interface Reader {
   GpsFeatureCollection read();
}

Объявите интерфейс Writer, мы предполагаем несколько реализаций, таких как KMLWriter, ShapeFileWriter и т. д.

interface Writer {
   void write(GpsFeatureCollection c);
}

Давайте объявим класс GpsFeatureCollection с методами read и write, которые принимают соответствующие интерфейсы в качестве параметров для выполнения задания.

class GpsFeatureCollection {

    ...

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

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

}

Некоторые примеры использования с использованием разных читателей и писателей.

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

// Writing data
data.write(new KMLWriter("/tmp/kmlfile"));
person Wand Maker    schedule 14.07.2013
comment
Это чистое золото! Большое тебе спасибо. В качестве единственного предложения я бы назвал интерфейсы IReader и IWriter (но не IGpsFeatureCollectionReader и т. д. :P). Спасибо еще раз! - person heltonbiker; 14.07.2013
comment
Рад, что вам понравилось. Java-люди не используют префикс I для интерфейса, хотя я не возражаю, если кто-то использует его, пока он используется постоянно. - person Wand Maker; 14.07.2013
comment
В качестве примечания (теперь, когда я пообедал и мой мозг снова работает), другой возможный дизайн мог бы иметь, скажем, класс GpxFormat с методами read и write, которые будут использоваться общим интерфейсом. Затем в том же классе можно было бы реализовать много стандартного/специфического кода, который, скорее всего, будет повторно использоваться методами ввода-вывода, а класс FileFormat будет своего рода просто обработчиком файлов, передаваемым в качестве аргументов любому методу. - person heltonbiker; 14.07.2013