| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > Какой код лучше соответствует ООП ? |
| Автор: ivanoop 10.12.2013, 11:33 | ||
| Всем привет! Пишу игру-стрелялку. Player - класс игрока, Point - класс точки в которой находится игрок. Как лучше оформить метод перемещения игрока в точку: поместить в класс игрока или сделать класс менеджера перемещения или реализовать оба способа?
|
| Автор: bsa 10.12.2013, 12:03 |
| ivanoop, первый вариант выглядит более естественно. |
| Автор: ivanoop 10.12.2013, 12:15 | ||||
А чем плохо сделать Move без класса?
В чём преимущества
|
| Автор: vinter 10.12.2013, 12:36 |
| Ну вот представь, что ты Игрок. Вариант 1: ты берешь себя защкирку и перемещаешь. Это выглядит для тебя правильным? Move не должен быть методом Player. |
| Автор: ivanoop 10.12.2013, 12:55 | ||
А что неправильного? Вот ты идёшь куда-то пешком. Кто тебя перемещает? |
| Автор: vinter 10.12.2013, 13:04 |
тоже верно, но мне не нравится. Move должен быть внешней сущностью на мой взгляд |
| Автор: xvr 10.12.2013, 13:13 |
Player должен предоставлять интерфейс (причем минимальный) для изменения своего состояния. Что у Player'а будет в этом интерфейсе для изменения позиции? Если он умеет только перемещаться из точки в точку (без каких либо дополнительных атрибутов, типа траектории или в крайнем случае просто скорости), то Move и будет таким интерфейсом. Сделать Move не членом класса это значит открыть этой самой функции Move внутренности Player'а, что бы она могла изменить позицию (которая хранится где то внутри Player'а), что является явным нарушением принципа инкапсуляции. Другой вариант - когда Player вообще не хранит позицию, а за это отвечает кто то другой (типа мэнеджера игрового поля), так же возможен (и возможно это будет даже лучше, т.к. кто то должен отслеживать геометрическое взаимодейтсвие Player'ов друг с другом, а это лучше делать там, где есть полная картина игрового мира). В таком случае Move должен быть членом этого самого мэнеджера 3й вариант - Player хранит позицию, но перемещение описывается какой то сложной траекторией. В таком случае у Player'а есть примитив - переместится по заданному вектору (короткому), а собственно перемещением занимается внешний класс TrackPath (например). В таком случае метод Move будет и у Player'а и у TrackPath'а, и 2й будет использовать 1й для реального перемещения |
| Автор: baldina 10.12.2013, 13:34 |
тогда он должен быть в курсе внутренней реализации, это плохо. Добавлено через 18 секунд xvr написал уже... |
| Автор: vinter 10.12.2013, 14:22 |
вовсе не обязательно, достаточно иметь setPosition или что-то схожее. |
| Автор: ZeusAtVingrad 11.12.2013, 09:31 |
| А почему player'а кто-то перемещает или даёт команду переместиться? Разве он не сам решает и стремится куда-то попасть? Под влиянием своих внутренних алгоритмов (ну или решения игрока-человека). |
| Автор: kolobok0 13.12.2013, 00:00 | ||
Для начала надо подчерпнуть инфы из класики - как это по уму. А потом уже пытаться понимать прочитанное, потом играться на своих кошках и лишь потом программировать. Если взять труды одного из основоположников ООА и ООП - Гради Буча, то в данной методологии есть основной принцип. Идти от задачи, от жизни. В жизни у Вас что и кто умеет перемещать или перемещаться? Давайте поразмышляем. Человек может перемещаться? Да. Его может, кто то перемещать? Да. Но это уже будет свойством другой(!) сущности. У человека могут быть доп. условия перемещения? Да. инвалид, только прыгает(ну типа мозгами поехал), ползёт(типа кругом война), произошёл взрыв гранаты рядом(воздействие на объект, вектора воздействия и силу имеем. а вот повреждения - опять же задача не ударной волны и не гранаты!!! Есть ещё "пару" правил: - не надо программировать ради программирования(только от задачи). - не надо резать будущие возможности(читай потребности объекта) в угоду оптимизации или другой своей внутренней потребности(обращаю внимание ВАШЕЙ потребности, а не бизнес задачи!). - не надо додумывать как программист на этапе ООА и ООП (типа а вот так будет круче, быстрее, правильнее и прочая ересь с точки зрения ОО) - после нахождения сущностей от жизни, проигрывания сценариев по юзанью найденных сущностей и их интерфейсов(динамическая модель) - можно просчитать те объекты которые уже необходимы для оптимизационных дел. Например, при сканировании бд не имеет смысла тащить на уровне сущностей все данные из таблиц. Вы же делаете операцию поиска в таблицах(к примеру) или там сканирования - вот и необходимо уже на этапе осмысления с точки зрения оптимальности по скорости работать с "коллекциями", а не со списками объектов. - И т.д... читайте лучше класику - там многое чаво подчерпнёте грамотного. только нуна думать конечно же и осязать всё, что прочтёте. удачи вам (круглый) |
| Автор: ivanoop 13.12.2013, 09:17 | ||||||
Если игрок сам захотел переместиться, то пишем строку
Если игрока поместили в автомобиль и перемещают, пишем строку
Поэтому в реализации метода car.Move придется вызвать метод player.Move. То есть опять игрок перемещается сам. |
| Автор: vinter 13.12.2013, 10:01 |
Поэтому надо не метод Move иметь а свойство Position, которое простейшим образом реализуется через setPosition()/position() |
| Автор: baldina 13.12.2013, 12:10 |
налицо более одной системы координат Добавлено через 1 минуту и 36 секунд я к тому, что перемещают только автомобиль. игрок перемещается как следствие (т.к. его локальная СК связана не с глобальной, а с СК авто) |
| Автор: akizelokro 14.12.2013, 13:24 |
| Менеджер точек и игроков всяко понадобится (контейнер точек можно и отбросить, если их множество достаточно прозаично и легко описывается "плоским" множеством (т.е., достаточно простой набор без дополнительных свойств точек). Функции перемещения нужны и там, и там (в классе игрока и в классе менеджера). Здесь должны учитываться такие зависимости, может ли в одной точке находиться более одного игрока, если нет, то менеджер делает перебор контейнера (множества игроков) с целью определить доступность хода, если ход разрешён, то вызывает для конкретного игрока метод Player::MoveTo(Point &) |
| Автор: akizelokro 14.12.2013, 14:08 | ||||
| Проблема вообще в рзаработанности ТЗ для задачи, написано оно, например, мной, или кем-то ещё (находится в стадии постоянного пересмотра). Если в стадии пересмотра и доработки, значит, придётся менять структуру и функциональную нагрузку схемы классов (что-то добавится, а может быть, и не добавится). В случае если добавится, то структура классов и функциональная нагрузка на классы и методы должна быть максимально гибкой, но и сразу включать необходимый набор ограничений, которые, вероятней всего, понядобятся в последующем. Например, на первоначальном этапе выбрана схема "одна точка - не больше одного игрока", а в последующем может осуществиться переход к схеме "одна точка - от нуля до бесконечного числа игроков". Так что метод самого хода прописать в класс игрока Player::MoveTo(Point & dest), а более общий метод Game::MoveTo(Player & victim, Point& dest) в классе, содержащем контейнер игроков, и этот общий метод будет проверять допустимость хода и в случае возможности вызывать
Для соображений удобства может показаться приемлемым написание что-то навроде функции
Но тут надо понимать, что раз пишется "менеджер", то на стадии неокончательной схемы классов такие функции несут в себе риск появления ошибок. |