Так как я пишу на RenPy игру которая выходит за пределы простой визуальной новеллы, то можно считать что я пишу её на Phyton-e. А питон как известно поддерживает объектно-ориентированную парадигму. Я долго не понимал что это такое, но в итоге вроде бы разобрался в общих чертах. Но возникает второй вопрос. А нужна ли она?
Вопрос вполне практический, так как сейчас я взялся намётывать боевую систему. С точки зрения ООП надо все сущности загнать в классы: классы для существ, классы для оружия, классы для боевых приёмов и т.п.
С другой стороны все необходимые атрибуты можно прописать в виде вложенных словарей, как я делал это в предыдущем модуле. И такой подход работает вполне неплохо, даже экономит объём кода. Методы классов вполне можно заменить отдельными функциями.
Возникает вопрос. Нужно ли мне заморачиваться с ООП подходом и что это даст?
Зачем писать класс как класс, а не как словарь и функции?
Вопрос вполне практический, так как сейчас я взялся намётывать боевую систему. С точки зрения ООП надо все сущности загнать в классы: классы для существ, классы для оружия, классы для боевых приёмов и т.п.
С другой стороны все необходимые атрибуты можно прописать в виде вложенных словарей, как я делал это в предыдущем модуле. И такой подход работает вполне неплохо, даже экономит объём кода. Методы классов вполне можно заменить отдельными функциями.
Возникает вопрос. Нужно ли мне заморачиваться с ООП подходом и что это даст?
Зачем писать класс как класс, а не как словарь и функции?
Как гласит теория (подойдет для твоего случая):
ОтветитьУдалить1. Классы позволяют проводить конструирование из полезных компонент, обладающих простыми инструментами, что дает возможность абстрагироваться от деталей реализации.
2. Данные и операции вместе образуют определенную сущность и они не «размазываются» по всей программе, как это нередко бывает в случае процедурного программирования.
Использование классов позволит тебе не загромождать код большим числом функций (процедур). Ты можешь создать компактный класс с необходимыми методами.
На практике:
Тебе надо создать 30 вражеских юнитов.
1й тип врагов состоит из 15 юнитов, которые ты описываешь в классе 'ВРАГ1".
у этих юнитов будет всего 2 способности (т.е. 2 метода) : удар рукой и удар ногой.
2й тип врагов состоит из 15 юнитов, которые ты описываешь в классе 'ВРАГ2", которые наследует класс 'ВРАГ1".
у этих юнитов будет уже 3 способности (т.е. 3 метода) : удар рукой, удар ногой и удар хлыстом.
Так вот тебе во 2м классе достаточно описать 1 метод 'УДАР ХЛЫСТОМ', а остальные 2 метода будут унаследованы от предыдущего класса.
И кстати программы написанные с использованием ООП работают быстрее, чем программы использующие процедурное программирование.
Если будут еще вопросы - пиши.
1-2. Дядя это вы с кем сейчас говорили? Ничего не понял.
УдалитьКлассы не компактнее ни разу. Класс надо объявлять и инициализировать, но при этом методы в нем занимают столько же места сколько и функции вне класса. То же самое с переменными. Не важно где они в списке или в классе. В классе даже больше места займут: self.variable против 'variable'
Мне надо создать 30 юнитов. Я описываю все способности в трех функциях. Тип юнита1 прописываю как словарь. Тип юнита2 прописываю юнит1 + словарь с изменениями.
По объёму кода и простоте решения - экономия.
И кстати я не крузис пишу, мои программы и на калькуляторе должны быстро работать.
Так что пока не понятно в чем цимес...
Обычно ООП программы работают медленнее), но на питоне не должно быть заметно.
УдалитьЭтот комментарий был удален автором.
УдалитьЗаморачиваться точно стоит :)
ОтветитьУдалитьЯ в своё время тоже не мог понять нахрена это нужно. Потом в голове щелкнула идея, что это просто для удобства объединяем код и данные в одну кучку. Как раз в это время я начал писать сложный (на то время) проект с библиотеками и классы легко и просто вписались в идею разделения всего проекта на несколько файлов.
На первых этапах можно писать точно так же как и в процедурном программировании, только функции и процедуры будут как бы привязаны к классу.
Про скорость работы несогласен с предыдущим оратором особой разницы быть не должно.
Стоит.
ОтветитьУдалитьВы сами очень быстро почувствуете, насколько вам удобнее составлять систему из частей. И код писать проще, и ошибки находить.
А если к кодингу подключится кто-то помимо вас, то ООП - это вообще маст хэв, без которого два-три человека будут только мешать друг другу.
Почему?
Удалить>> Почему?
УдалитьГрубо говоря, классы - это как торговый автомат: нажали на одну кнопку - выпала шоколадка; на другую - сухарики. И вам не нужно знать, конструкцию аппарата, чтобы им пользоваться. Только уметь дать входящие данные (кнопки нажать) и забрать итоговый результат (получить хавчик).
Если вы уже один раз сконструировали такую машину - пользоваться ею сможет кто угодно. И ни вы, ни кто-то еще, уже не сломают ее, потому что вам просто не потребуется лезть во внутрь работающей системы.
Программирование становится строительством из готовых, отлаженных и рабочих блоков и даже целых комплексов, а не из отдельных кирпичиков, из которых кто угодно может собрать что угодно, включая полный авангард.
Класс - эта такая очень большая абстракция.
ОтветитьУдалитьТ.е. допустим. Собака - это класс. Шарпей - унаследованный от собаки класс. Конкретный тузик у тети Вали - экземпляр класса Шарпей.
Что дает такой подход? То что один раз определив что собаки умеют лаять (метод класса), нам не нужно каждый раз писать как именно это делает каждая порода и каждая конкретная собака в частности.
Естественно, не всегда стоит заморачиваться с классами. В том плане, что не всегда стоит городить отдельный класс когда можно ограничиться методом у уже существующего.
А чем это отличается от функции лая которая прописана вне класса но всё равно одна и та же у всех собак?
УдалитьТем, что допустим, собаки умеют лаять. Если эта функция просто выводит в чатик лай, то никаких проблем. А если эта же функция должна еще отнимать у той собаки, которая лает, стамину? Ей нужно будет передавать параметр, где хранится значение стамины. А если она еще, допустим увеличивает голод? Ей нужно будет передать параметр где хранится голод для этой собаки.
УдалитьПри работе с классом, после создания объекта класс может хранить переменные для значений стамины и голода для данной собаки.
Т.е. мы получаем следущие плюсы.
1) Все данные про собаку храняться в одном месте.
2) Другие объекты ничего не знают про состояние этой собаки, что ведет к уменьшению вероятности ошибки..
3) Значительно проще искать ошибки и сопровождать такой код. Засчет того, что вместо хранения разных переменных в разных местах (про которые нужно помнить в один и тот же момент времени) мы получаем аккуратный объект.
4) В случае необходимости мы можем переопределить функцию лая в потомках класса. Т.е. все собаки лаят "гав", а Доге лает "вов". При этом у нас останется единый интерфейс для лая: bark(), вместо двух функций. Можно использовать и одну функцию, но это приведет к переусложнению кода.
1) Ну есть же словарь собаки. В нём и хранятся все её переменные касающиеся её.
Удалить2) Других объектов вообще нет, если не ООП )
3) Вот это интересный момент. Да тут уже писали про структурирование, наверное это действительно плюс.
4) модификация единой функции имеет свои преимущества, особенно в объёме кода
Собственно что меня напрягает это появление микроклассов которые имеют один метод и полторы переменных, но при этом отдельно инициализируются и захламляют всё. Плюс проблемы с наследованием, особенно множественным и т.п. Чтобы писать объектами, особенно с иерархией наследования, надо заранее представлять себе какие они будут нужны в конце, а у меня такого понимания нет,я пишу программу на ощупь. Учусь прямо в процессе написания.
Но так или иначе я попробую сделать боёвку в рамках ООП и посмотрю как оно пойдёт на практике.
Не стоит доводить до абсурда и создавать класс на каждый чих.
УдалитьИ я не вижу никакой проблемы в инициализации. У нормального класса есть конструктор по умолчанию, лишних строк по сравнению с процедурным вариантом будет одна-две
Могу дать общий совет не ударяться в крайности.
УдалитьНе обязательно делать выбор между полным отсутвием ООП и классами для каждой мелочи объединенными в жуткую иерархию которая все равно 10 раз изменится до релиза. Баланс и золотая середина наше всё.
С иерархией действительно будут проблемы, если не знаешь точно что пишешь. В твоём случае не стоит особенно с ней маньячиться, достаточно делать наследование только там, где оно очевидно и само проситься.
А в чем проблема с инициализацией, я не очень понимаю если честно. Можно ведь просто не инициализировать, если так уж не хочется)
>микрокласс
УдалитьЯ уже писал, что доводить до абсурда не надо. Класс на 1 функцию это уж слишком
>надо заранее представлять
Попробуй начать с ТЗ. Заранее определи что ты хочешь получить в итоге, при этом сразу же в ТЗ оговори что возможно (но не факт) может измениться. А уже по этому делай архитектуру приложения/модуля.
Понятно, что за раз все не получится, еще придется вернуться к ТЗ и переписать интерфейсы.
Часть смысла ООП в модульности. Есть некий модуль (класс/набор классов), который предоставляет некий API/функционал, который скрыт от пользователя этого API/функционала. При этом внутренняя реализация этого функционала может меняться, не затрагивая другие модули. Таким образом достигается взаимодействие разработчиков - они работают над разными модулями согласовав взаимодействие между ними, например. Таким образом достигается удобство траблшутинга ошибка будет всегда внутри модуля. Так достигается раширямость - при изменении/добавлении модулей другие модули не меняются или меняются незначительно.
Отдельно стоит отметить питон. Как писалось тут в конечном счете все классы транслируются в словари, поэтому разделение на классы/словари не шибко критично в данном контексте. В этой свзязи я особой разницы не вижу, в том плане, что неправильно спланированные классы так же будут мешаться как неправильно спланированные словари. Ну и ООП это не обязательно классы, ООП - это подход к решению.
Ну и вообще про программирование с помощью ООП есть шикарнейшкая книга: "Совершенный код" Стива Макконелла. Там не столько про само программирование, сколько про подход.
УдалитьЕсли коротко: стоит)
ОтветитьУдалитьПочему стоит?
Если совсем просто то ООП дает два основных приемущества
- нет дублирования кода(при грамотной архитектуре)
- программа разбивается на классы.
Зачем разбивать на классы?
- Улучшается читаемость
- Можно разрабатывать классы отдельно(разными людьми)
- Возможность изменить реализацию класса не меняя остальную программу
Пример
В случае модели реакций можно создать класс Характер
в котором будут поля отвечающие за ауру/мораль
и методы: получить_реакцию итп
В этом случае весь код отвечающий за поведение будет компактно собран в одном месте и при сохранении имен методов мжно полностью изменить его логику работы незаметно для остальной программы(к примеру добавить усталость от однотипных действий).
В общем код станет во многих отношениях проще, но не сразу. Нужен некоторый навык, но он в любом случае рано или поздно понадобиться, когда программа станет слишком сложной без ООП. Лучше начинать тренироваться заранее)
В целом понятно, классы это больше способ структурирования данных для удобства работы с ними.
УдалитьА при чем тут дублирование? Его и в функциональной парадигме быть не должно. На то они и функции чтобы вызывать их много раз для решения однотипных задач.
Ага именно структурирование. Объединение данных и кода который с ними работает в одном месте.
УдалитьПардигма все-таки модульная. Функциональная это вообще из другой оперы.
Про дублирование:
У меня вообще были C и C++ в голове когда я это писал. В питоне это не так заметно.
Вообще при желании любой класс можно переписать через словари, тем более, что сам питон в итоге сам преобразует класс к паре словарей)
Отвечая на вопрос "Нужно ли мне заморачиваться с ООП подходом и что это даст?", то ответ "ДА". Но лучше сначала заморочиться с процедурным подходом. Для начала откажитесь от глобальных переменных и "goto" / "jump".
ОтветитьУдалитьКогда я начинал меня поставили в жесткие рамки стандартом кодирования ( https://www.dropbox.com/s/vhrh6d2j57ul80j/GooglePythonStyleGuide%28RUS%29.zip ). Примерно через 3 года пришло понимание почему так нужно было делать. В нашем стандарте (для C++) было 2 решающих правила: 1. НИКАКИХ глобальных объектов 2. Процедура должена помещаться на экран. Это сразу приводит к тому, что все входные и выходные параметры нужно передовать, плюс количество процедур растет быстро. Дальше чувство прекрасного (common sence) решает и ООП органично встраивается в ваш мозг.
А что плохого в джампах? Для питоновских кусков они в целом мне пока и не были ни разу нужны, а вот RenPy на них полагается изрядно так как построен из локаций как и QSP.
УдалитьЗа три года можно просто привыкнуть к чему угодно. Но иногда мы склонны путать то что привычно с тем что действительно удобно, правильно или хорошо.
Впрочем я верю что работа в строгих рамках будет способствовать качеству кода. И я хотел бы конечно писать код лучше. Но для меня это всё же вторично. Я хочу лучше писать код ради игр, а не делаю игры для того чтобы научиться лучше писать код. Если что-то мешает мне в этом процессе, я сразу теряю настроение (
А что за глобальные объекты?
УдалитьВозьмем, например, 00pythonearly.rpy. Те переменные, что там объявлены вначале доступны из ЛЮБОГО места в коде. Например функция
ОтветитьУдалитьdef interactionSucess(pattern) выглядит так, как будто она принимает на вход pattern и возвращает что-то. Но на самом деле она меняет все состояние программы. В точке вызова этого не видно. Если передать все необходимые параметры, то в точке вызова это будет выглядеть так
action_sucess = interactionSucess(interaction_pattern, my_girl, public, shame, disgust, fear, anger, guilt, suffer, insult, pleasure, tender, attraction, gratitude, confidence ...и еще много )
Это конечно "доставляет", но зато в точке вызова примерно видно что функция делает и что её для этого нужно. И если вся программа написана таким образом, то это делает код немного понятнее. НО глобольные переменные все портят. Они могут быть изменены из любого места в коде. Обычно это происходит внезапно (особенно если в проекте задействовано много людей).
А вообще не парьтесь :) Пишите в своё удовольствие и не нам вас учить
УдалитьОхотник сори не знаю как твоё имя.у меня не вопрос а совет(посмотри если будет время)самая популярная книга игра конца 1990 или начало 2000 не столь важно называется Гохан или странник изгоняющий мрак игра шикарная там нет 18+но может чтото возьмёшь для себя игра эта рельно кульная
ОтветитьУдалитьhttp://quest-book.ru/forum/viewtopic.php?t=1617
там и текст и персонажи и по мне можно чтото взять
Костя.пс мне 24 года
Я играл в школе в книги игры да. Но сейчас играть это в pdf-е я пожалуй не выдержу ))
УдалитьПроблема не в том что у меня нет идей что напихать в игру. Проблема как суметь реализовать всё что я придумал.
Как резюме. ООП как правило(зависит от реализации) ведет к инкапсуляции(изоляции) части кода и данных. Собственно дальше все сводится к правильному конструированию классов и правильность имеется в виду концептуальная а не синтаксическая. Конечно все что можно описать классами, можно описать и без них.Можно писать вообще на ассемблере. Как было сказано в "Ученые шутят" Если бы строители строили так же, как программисты пишут, то первый же залетевший дятел разрушил бы мир. ООП снижает остроту этой проблемы. А вообще то я бы на вашем месте присмотрелся к RPG maker ace там в основе ruby. Но большую часть можно вообще не писать, там интерфейс WYSIWYG позволяющий решить большинство задач. И при этом можно переопределить или расширить почти все именно потому, что все написано в рамках ООП и все коды доступны. Есть русификатор и русифицированный код. Сейчас фирма делает возможность порта игр на андройд. В случае вопроса легальности она стоит в районе 20 баксов. К нему есть куча расшареного кода реализующего все виды боевок(от пошаговых, до 3D). Квестовых систем и т.д. тут ссылок не привожу но достать на трекерах 5 минут. А вообще хотел выразить свой респект) Вы умница. Очень интересная модель поведения. http://informaticslib.ru/books/item/f00/s00/z0000024/st007.shtml
ОтветитьУдалитьЯ пробовал RPGmaker. Он для моих задач избыточен, там всё крутится вокруг модели с бродящим по карте спрайтом. Делать спрайты и карты это отдельный геморой, а вот польза для игрового процесса сомнительна. На мой взгляд один вред. Имхо именно реализация на RPGmaker-е запорола SimBrothel 2. Хотя первая часть была годная.
УдалитьЭтот комментарий был удален автором.
УдалитьЗнаешь,ты задал довольно интересный вопрос. Я несколько дней размышлял почему именно я пишу соблюдая ООП . Ответ получился одновременно простым и сложным. Если в двух словах : так проще.
ОтветитьУдалитьСама парадигма ООП не появилась на пустом месте. Она не противостоит процедурному а расширяет его. С помощью классов, можно составлять сложные отношения между обьеектами и при этом соблюдать четкую структуру кода. Модификаторы доступа , overwriting и overloding методов позволят тебе быть уверенным что твои обекты будут вести себя так как ты этого хочешь.
Это как сравнивать телегу с лошадью и автомобиль. Оба могут тебя доставить из пункта А в пункт Б. Но на авто это получится быстрее,комфортнее, никто тебе не будет ветрв под нос пускать и еще и песенку спеть может.
В заключение скажу что мне очень знакомо жто чувство,когда надо переходить от чего то старого и знакомого на что то новое и не совсем понятное. Первое время будет некомфортно, зато потом ты сможешь роектировать целые куски приложения в голове.
Кстати, я бы тебе сейчас посоветовал отложить реализацию в сторону, взять листок бумаги и ручку и написать все все идеи насчет твоего проекта. Тогда тебе яснее будет представляться функционал приложения, требуемые сущности и отношения между ними. Потом и релизация буддет проще. Плюс ты можешь поделиться планами с нами и получить тоннну советов.:)
В любом случае,успехов!!
ЗЫ: Пишу с телефона поэтому сорри за опечатки если что.
У меня никогда не получалось заранее написать техзадание целиком. Очень много конкретики становится понятно только тогда когда начинаешь пытаться реализовать более общие вещи в коде.
УдалитьВсё-таки пропасть между хотелкой описаной человеческим языком и работающей программой слишком велика.
Не такая уж и большая. Это для того и делается чтобы привести язык хотелок к требованиям к приложению. Если "рабыня должна плакать когда ее бьют", то по крайней мере мы знаем что нам нужен как минимум класс рабыня , в нем метод плакать, который будет зависеть от того бьют ее или нет. ООП позволяет более менее говорить с приложением на человеческом языке.
УдалитьПоэтому если у тебя еще нет всего плана в мельчайших подробностях то опиши хотя бы на том уровне детализированности какой есть. Поикрайней мере ты получишь две выгоды.
Вопервых ты сможешь собрать все свои идеи в кучку и разложить по полочкам. Сможешь увидеть "общий план" и понять чего не хватает.
Во вторых ты сможешь увидеть примерную структуру приложения. Ну если с этим будет трудно, то мы всегда поможем :D
А насчет того, что еще не все детали есть,не беспокойся. С ООП очень легко расширять и править функционал.
В общем, мы плохого не посоветуем :-)
Ну я естественно изначально пишу некоторую механику словами. Просто практика показывает что когда берешься за код всё сильно меняется + возникает много такого о чем заранее и не думал.
УдалитьВ общем вероятно я через некоторое время создам проект на GitHub и постараюсь организовать совместную с энтузиастами работу над кодом. Но это когда настанет время реализации.
Некоторое время назад я читал хорошую книжку по прграммированию. Там была такая фраза . Do not program in the language.Program into it. Перевод на русский несколько затруднителен,однако обшая идея такова : не меняй свои требования изза возможностей языка. Ищи новые возможности для реализации своих требований.
ОтветитьУдалить... Надо будет разработать единую конвенцию для подопытных чтобы потом мозги себе не ломали...
>>"И такой подход работает вполне неплохо, даже экономит объём кода."
ОтветитьУдалитьЭто ситуация из разряда "пот экономит кровь". Лишний абзац на инициализацию класса там-сям даёт возможность впоследствии писать очень приближённо к естественному языку, а не продираться сквозь конструкции из скобочек. Говорю как перешедший однажды в своих поделках с самопальных конструкций на ООП))
Ну и кроме того ООП как-то... упорядоченней. Взять те же методы - молоток как-то логичнее смотрится неподалёку от коробки с гвоздями, чем в одном ящике с расчёской и столовой посудой)
Ну кстати приближенность к естественному языку я уже оценил за время что пробую классы. Действительно читается проще.
Удалить