Лучший подход для обработки условных полей в модели - PullRequest
0 голосов
/ 10 февраля 2019

У меня есть 3 модели Person, Role и Position, представляющие людей в футбольном клубе, таких как

public class Person {
    private Long id;
    private String name;
    private Role role;
}

public class Role {
    private Long id;
    private String name; //like manager, goalkeeping_coach, player
}

public class Position {
    private Long id;
    private String name; //striker, midfielder, defender, goalkeeper
}

Проблема в том, что position имеет смысл только для человека, если его рольэто player.Поэтому, если я сделаю

public class Person {
    private Long id;
    private String name;
    private Role role;
    private Position position;
}

, то для всех person экземпляров, которые не имеют роли player, в поле position будут храниться нулевые значения.Точно так же могут быть другие атрибуты, которые имеют смысл только для экземпляров manager и / или goalkeeping_coach.

Я попытался сделать класс Person абстрактным

@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Person {
    private Long id;
    private String name;
    private Role role;
}

public class Player extends Person {
    private Position position;
}

public class Manager extends Person {

}

Это приведет кэкземпляры player и manager должны быть сохранены в разных таблицах.Но проблема теперь возникает, если меняется role из person (скажем, игрок уходит в отставку и становится менеджером клуба).Затем я должен был бы переместить строку из одной таблицы в другую (скажем, удалить экземпляр player и создать новый экземпляр manager, используя те же данные, исключая данные position), который не выглядит какхороший путь.

Итак, каков наилучший подход к этому сценарию?Можно ли иметь нулевые значения, как в первом случае?

Ответы [ 4 ]

0 голосов
/ 10 февраля 2019

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

Правильный способ для моделирования этого состоит в том, чтобыТаблицы Person и Role (которые у вас уже есть), а также таблица связывания PersonRole, которая будет иметь поля personId, roleId, startDate и endDate.Это решит проблему моделирования данных, но усложнит ваш код.

Однако многие приложения имеют дело только с мгновенным временем (например, дата следующей игры, следующий день выплаты жалованья).Они могут использовать предложенную вами иерархию «Manager extends Person», так как она верна в определенный момент времени.

0 голосов
/ 10 февраля 2019

Первое существенное отличие здесь заключается в том, идет ли речь о коде на стороне Java или коде на стороне базы данных.

Для Java-представления: получение Player и Manager от Person кажется правильным.Нет нулевых полей там.Поведение позаботится о том, является ли он игроком или менеджером, и вы можете написать конструкторы переноса, которые делают игрока менеджером (или наоборот, если это имеет смысл)

Для представления базы данных:Можно иметь нулевые поля (они дешевы с точки зрения пространства, и вы можете делать запросы, обрабатывая их нулевыми проверками).Если вы хотите отобразить их в собственной таблице, зависит от того, хотите ли вы запросить их по отдельности или в сочетании.Иногда требуется запрос более Person вместо Player, например, для оценки общей заработной платы.Затем вам нужно union (при условии, что вы используете какую-либо форму базы данных SQL).

По сути, правильный ответ заключается в том, что в зависимости от всей вашей архитектуры и назначения вашего программного обеспечения, нет единого правильного ответа., но вам придется вносить изменения в любом случае, в критических местах, если и когда дело доходит до взаимодействия с базой данных.

0 голосов
/ 10 февраля 2019

Требуется, чтобы соединение между Person и Role могло быть изменено.
Модель может отражать это, если вы создаете таблицу для этого соединения, а также соединение между Person и Position

// Person table has only Person details 
public class Person {
    private Long id;
    private String name;
}

// Role table has only Role details 
public class Role {
    private Long id;
    private String name; //like manager, goalkeeping_coach, player
}

// Position table has only ... 
public class Position {
    private Long id;
    private String name; //striker, midfielder, defender, goalkeeper
}

// connection of Person and Role 
public class PersonRole {
    private Long person_id;
    private Long role_id;
}

// connection of Person and Position
public class PersonPosition {
    private Long person_id;
    private Long position_id;
}

Этот дизайн решает требование человека, меняющего роли, а также условной релевантности должности.он также обслуживает будущие потребности, например, человек, имеющий несколько ролей и позиций

EDIT : я понял, что то, что я описал, на самом деле является моделью базы данных.в Java вы можете смоделировать таблицы соединений как отношение «многие ко многим» (если вы используете какой-либо ORM)

0 голосов
/ 10 февраля 2019

Один из способов решить эту проблему - иметь одну и ту же таблицу, обслуживающую как человека, так и менеджера, и фактически любого другого человека.У вас будут строки, которые не используются в зависимости от типа человека, но все общие поля останутся в этой отдельной таблице.Таким образом, нет необходимости удалять строки и создавать их в другой таблице при изменении роли.Вам нужно будет добавить поле для типа человека.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...