Java: применить статический метод из суперкласса (контекст Mongo/Morphia)

Я разрабатываю архитектуру ODM на Java. У меня есть иерархическая структура с абстрактным классом Document верхнего уровня. Реализации объектов БД расширят этот класс.

public abstract class Document {
    ObjectId id;
    String db;
    String collection;
}

public class Student extends Document {
    db = "School";
    collection = "Student";

    String name;
    int age;
    float gpa;
}

Я хочу, чтобы каждый класс мог статически извлекать результаты для связанной с ним коллекции. Например, я хотел бы сделать что-то вроде Students.get(Students.class, new ObjectId(12345)), которое вернуло бы Student из базы данных. Обратите внимание, что мне нужно указать класс в методе get(), это ограничение библиотеки сопоставления объектов, которую я использую (Morphia).

Каков наилучший способ заставить каждый класс иметь этот метод get()? Есть пара ограничений:

  1. get() должен быть реализован как статический метод
  2. Я хотел бы по возможности избежать избыточного кода и не указывать класс для каждой реализации get(). Например, если у меня есть классы Student и Teacher, я хочу избежать указания Students.class и Teacher.class вручную. Я не уверен, что это возможно, поскольку get() является статическим методом.

Я думаю, что это разновидность распространенной абстрактной статической проблемы Java, но сначала я хочу убедиться, что подхожу к ней правильно.


person user2066880    schedule 19.01.2015    source источник


Ответы (1)


Я предполагаю, что ваш студенческий класс должен выглядеть примерно так:

@Entity(name="Student")
public class Student extends Document {
    protected String name;
    protected int age;
    protected float gpa;
    ...
}

Общие запросы будут примерно такими:

public <E extends BaseEntity> E get(Class<E> clazz, final ObjectId id) {
    return mongoDatastore.find(clazz).field("id").equal(id).get();
}

Почему вы хотите сделать это статическим? Вы бы жестко кодировали зависимости и ломали полиморфизм; что делает невозможным использование фиктивной реализации для тестов (которой не нужна настоящая база данных).

person xeraa    schedule 19.01.2015
comment
Я думаю, что единственная причина, по которой я хотел, чтобы он был статическим, заключается в том, что он не должен быть связан с каким-либо конкретным экземпляром класса. Не могли бы вы также объяснить, что вы упомянули о зависимостях жесткого кодирования и нарушении полиморфизма? Мне трудно понять это в моем контексте. Спасибо, очень ценю ваш вклад. - person user2066880; 19.01.2015
comment
Краткий ответ см. на stackoverflow.com/a/17997568/573153. Длинный, но очень подробный ответ см. misko.hevery.com/code-reviewers-guide / - person xeraa; 20.01.2015
comment
Полный пример кода см. на странице github.com/xeraa/morphia-demo/blob/master/src/main/java/net/ - person xeraa; 20.01.2015