Добрый день. Прошу поделиться опытом, как правильно и логично реализовать следующее:
Имеем 4 класса Cat, Dog, Owl, Monkey
Каждый класс имеет как общие свойства, так и свои уникальные, которых нет в других классах. Есть апи ручка условно назовем ее SetAnimal. При вызове этой ручки передаётся тип животного и в контроллере идет проверка если тип такой то+ личные свойства животного подходят под проверку делаем такие то действия, для пример
если тип = cat то создаем класс new Cat(params)
или если тип monkey && weight > 20, new Monkey
...
При это в одной главной таблице создается запись что животное принято, animals -> id, date, type
и затем для каждого животного свой класс и запись в свою таблицу new Cat(requestParams), new Dog(requestParams), etc
1. Тип животного в базе не хранится, не вижу в этом смысла, насколько это корректно?
2. В каком виде корректно передавать типы животного? Видел реализацию где в качестве типа это какой то id, (т.е. Cat = 1, Dog = 2, и т.д.) и в базе так и хранят
Animals
id | date | typeId
1 |. ... | 1. - cat
2 | ..... | 2. - dog
При этом этот typeId не является внешним ключом к какой либо таблице.
Не лучше ли хранить в поле вместо цифр слово типа
id | date | type
1 |. ... | cat - cat
2 | ..... | dog - dog
Определение какой класс животного мы создаем в методе контроллера, хочется избежать if else if ...
Какой паттерн можно использовать, стратегия, фабричный метод?
Хочется чтобы в контроллере на входе получая тип, логика понимала что это класс такой то, создавала его и передавала параметры.
Что то вроде
cat => new Cat()
dog => new Dog()
...
При этом также хочется сделать валидацию на входные параметры для каждого из животного. У каких то параметров валидация одинаковая, у других своя уникальная, в том числе и поля.
Может быть имеет смысл разбить одну апи ручку на на несколько?
т.е. для каждого будет свои
POST /api/animals/cat {name: '..', anotherParam1}
POST /api/animals/dog {name: '..', anotherParam2}
POST /api/animals/owl {name: '..', anotherParam4: ''}
Для каждого создать свою request модель с валидацией, не придется в методе определять тип, сразу будет new Cat(params)...
Тебе-б надо подсократить текст вопроса. Слишком много написано.
Больше кода - меньше словесных описаний. Нужна реализация хендлера - напиши заголовок хендлера
и многоточие. Сразу станет понятно.
Не могу сказать что мой ответ будет истинным, но может он чем-то поможет!
При вызове этой ручки передаётся тип животного и в контроллере идет проверка если тип такой то+ личные свойства животного подходят под проверку делаем такие то действия, для пример
если тип = cat то создаем класс new Cat(params)
или если тип monkey && weight > 20, new Monkey
Думаю, такой подход не очень хороший, так как при увеличении тех же животных придется городить больше ифов (свитчей и т.д.) в одном методе. В последствии будет большой и неудобный метод!
Как вы ответили в конце лучше будет сделать несколько конечных точек
POST /api/animals/cat {name: '..', anotherParam1}
POST /api/animals/dog {name: '..', anotherParam2}
POST /api/animals/owl {name: '..', anotherParam4: ''}
и в каждом уже прописать нужную логику. Будет лучше читаться и легче изменяться.
При этом также хочется сделать валидацию на входные параметры для каждого из животного. У каких то параметров валидация одинаковая, у других своя уникальная, в том числе и поля.
Для проверки полей или валидации рекомендую создать отдельные классы по типу CatValidator, MonkeyValidator которые будут наследоваться от, например, IValidator с методом Validate.
При это в одной главной таблице создается запись что животное принято, animals -> id, date, type
и затем для каждого животного свой класс и запись в свою таблицу new Cat(requestParams), new Dog(requestParams), etc
Не понятно зачем вам главная таблица Animals с перечнем всех животных, можете уточнить?
Для каждого создать свою request модель с валидацией, не придется в методе определять тип, сразу будет new Cat(params)...
Как мне кажется такой вариант будет неплохой. Также валидацию можно будет сделать c помощью атрибутов и встроенной в asp.net валидацией(ModelState.IsValid)
Не понятно зачем вам главная таблица Animals с перечнем всех животных, можете уточнить?
Это общая таблица учета всех животных. Каждому животному выдается свой уникальный идентификатор, как раз id в таблице animals. С датой создания записи, подвязанным пользователем и типом животного.
В поле тип думаю использовать именно слово cat/dog/owl, хотя не уверен что это удобно и может быть надо создать какой то enum, где присвоить числовые значения
В поле тип думаю использовать именно слово cat/dog/owl, хотя не уверен что это удобно и может быть надо создать какой то enum, где присвоить числовые значения.
Как мне кажется, более предпочтительней будет в таблице сохранять цифры, а в коде создать enum и орудовать им.
Во-первых, это будет удобно. Во-вторых легко расширяемо. В-третьих легко изменяемо.
Думаю, строку для типа можно использовать только в том случае, если к вашей БД могут подключится другие "пользователи" и у вас нет какой либо документации.
Это только мое мнение и может быть неверно. У меня пока-что маловато опыта)