Форум программистов, компьютерный форум, киберфорум
Delphi
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.88/8: Рейтинг темы: голосов - 8, средняя оценка - 4.88
 Аватар для Duxan
1 / 1 / 0
Регистрация: 29.05.2013
Сообщений: 54

Правильное ООП и модульность

18.02.2014, 17:46. Показов 1792. Ответов 18
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Нужны советы опытных программистов.

Решил сделать рефакторинг проекта. Общие правила я знаю и стараюсь следовать им (понятные имена методов, избегание дублирование кода и т.д.).

Но хотелось бы разъяснить несколько вопросов.

Функции должны быть отделёны от интерфейса. Но стоит ли выносить их все в отдельный модуль? Сейчас, например, они все описаны в юните главной формы в классе формы, а сам модуль поделён на две части: в первой половине описываются события интерфейса, а во второй части методы функциональные.

И отсюда второй вопрос: стоит ли выделять отдельный класс для этих методов?

Заминка в том, что многие написанные методы работают с определёнными элементами на форме. То есть отдельный модуль уже будет узкоспециализированный. А если переписать их, добавив параметры, то это существенно снизит удобность. Вместо DoSmth придётся каждый раз писать DoSmth(AVar1, Avar2, Avar3).
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
18.02.2014, 17:46
Ответы с готовыми решениями:

Правильное ООП построение класса Aeroflot
Долго мучяюсь с тем что бы понять построение ооп. Решите задачу за всеми правилами что бы можно было хоть взглянуть на ее правильное...

Модульность и интегрированность
На лекциях как-то рассказали для справки что мир понял однозначный плюс модульной структуры систем после первой мировой войны. Тогда...

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

18
18.02.2014, 17:49
0
 Аватар для Duxan
1 / 1 / 0
Регистрация: 29.05.2013
Сообщений: 54
18.02.2014, 18:10  [ТС]
Не скажу, что прям уж совсем не по теме)

Идея понятна — в погоне за красотой кода есть риск чрезмерно усложнить архитектуру программы, не говоря уже о потраченном времени. Но всё же какой вариант предпочтительней (понятно, что первый потребует больше времени, но и ошибки при таком подходе быстрее находятся)? Или истина как всегда посередине?
0
пофигист широкого профиля
4770 / 3205 / 862
Регистрация: 15.07.2013
Сообщений: 18,613
18.02.2014, 20:25
Цитата Сообщение от Duxan Посмотреть сообщение
Или истина как всегда посередине?
Риторический вопрос.
1
Эксперт Python
 Аватар для dondublon
4653 / 2073 / 366
Регистрация: 17.03.2012
Сообщений: 10,183
Записей в блоге: 6
19.02.2014, 08:44
Цитата Сообщение от Duxan Посмотреть сообщение
Функции должны быть отделёны от интерфейса. Но стоит ли выносить их все в отдельный модуль? Сейчас, например, они все описаны в юните главной формы в классе формы, а сам модуль поделён на две части: в первой половине описываются события интерфейса, а во второй части методы функциональные.
Да, разумеется.
Только, наверное, не функции, а отдельный класс - без привязки к gui.
Цитата Сообщение от Duxan Посмотреть сообщение
И отсюда второй вопрос: стоит ли выделять отдельный класс для этих методов?
По ситуации. Можно и без класса обойтись, но классы же не зря придумали.

Цитата Сообщение от Duxan Посмотреть сообщение
Заминка в том, что многие написанные методы работают с определёнными элементами на форме.
Это плохо, отвязывайте.

Цитата Сообщение от Duxan Посмотреть сообщение
То есть отдельный модуль уже будет узкоспециализированный.
Ну так и надо.

Цитата Сообщение от Duxan Посмотреть сообщение
А если переписать их, добавив параметры, то это существенно снизит удобность. Вместо DoSmth придётся каждый раз писать DoSmth(AVar1, Avar2, Avar3).
По ситуации. Либо вы храните значения внутри класса, либо передаёте их через параметры, третьего не дано.
Если вам действительно "придётся каждый раз писать" - храните это в классе.
Главное - чтобы в классе не было ничего лишнего. Лишнее в классе в вашем случае - это всё, что относится к gui.
1
Житель Земли
 Аватар для DenNik
3004 / 3026 / 390
Регистрация: 26.07.2011
Сообщений: 11,465
Записей в блоге: 1
19.02.2014, 16:28
Цитата Сообщение от dondublon Посмотреть сообщение
Это плохо, отвязывайте.
это с какого перепуга? если у меня есть вывод в мемо, к примеру, какого ляда я должен описывать эту процедуру вне класса формы?
0
 Аватар для Duxan
1 / 1 / 0
Регистрация: 29.05.2013
Сообщений: 54
19.02.2014, 22:44  [ТС]
Спасибо за советы.

Цитата Сообщение от DenNik Посмотреть сообщение
это с какого перепуга? если у меня есть вывод в мемо, к примеру, какого ляда я должен описывать эту процедуру вне класса формы?
Как мне кажется, код не должен быть запутанным. А обилие классов и функций этому не способствует. Не очень удобно, когда чтобы добраться до кода действия какой-либо кнопки, приходиться по цепочке просмотреть полдюжины функций в разных модулях и классах.
0
пофигист широкого профиля
4770 / 3205 / 862
Регистрация: 15.07.2013
Сообщений: 18,613
20.02.2014, 01:43
Цитата Сообщение от dondublon Посмотреть сообщение
Да, разумеется.
"Забудьте всё, чему вас учили в Институте, как дурной сон..."
(с) М.Жванецкий

P.S. Если бы речь шла о написании учебника по основам ООП или о сферическом коне в вакууме (что почти одно и то же) я бы согласился с таким категоричным заявлением.
0
Эксперт Python
 Аватар для dondublon
4653 / 2073 / 366
Регистрация: 17.03.2012
Сообщений: 10,183
Записей в блоге: 6
20.02.2014, 08:05
Цитата Сообщение от DenNik Посмотреть сообщение
это с какого перепуга?
Ну вот так вот.
Цитата Сообщение от DenNik Посмотреть сообщение
если у меня есть вывод в мемо,
Прочитайте ещё раз, о чём я сказал "плохо".
Цитата Сообщение от northener Посмотреть сообщение
P.S. Если бы речь шла о написании учебника по основам ООП или о сферическом коне в вакууме (что почти одно и то же) я бы согласился с таким категоричным заявлением.
Будем меряться письками опытом работы?

Добавлено через 56 минут
Цитата Сообщение от Duxan Посмотреть сообщение
А обилие классов и функций этому не способствует.
Судя по вашему посту, вам это пока не грозит.

Цитата Сообщение от Duxan Посмотреть сообщение
Не очень удобно, когда чтобы добраться до кода действия какой-либо кнопки, приходиться по цепочке просмотреть полдюжины функций в разных модулях и классах.
Не очень удобно, когда вам понадобилось использовать написанный функционал в другом месте, не только по той кнопке, и ВНЕЗАПНО вы обнаруживаете, что его невозможно вытянуть, не потащив за собой StringGrid1, CheckBox1..3 и RadioButton1 и всё остальное.

Ну и возникает вопрос - если вы так хорошо разбираетесь в этом, зачем задаёте вопросы?
Или вы хотите получить от публики оправдание вашему говнокоду - "Да, классы действительно не нужны", чтобы на душе приятнее было?
0
 Аватар для Duxan
1 / 1 / 0
Регистрация: 29.05.2013
Сообщений: 54
20.02.2014, 11:40  [ТС]
Цитата Сообщение от dondublon Посмотреть сообщение
Не очень удобно, когда вам понадобилось использовать написанный функционал в другом месте, не только по той кнопке, и ВНЕЗАПНО вы обнаруживаете, что его невозможно вытянуть, не потащив за собой StringGrid1, CheckBox1..3 и RadioButton1 и всё остальное.

Ну и возникает вопрос - если вы так хорошо разбираетесь в этом, зачем задаёте вопросы?
Или вы хотите получить от публики оправдание вашему говнокоду - "Да, классы действительно не нужны", чтобы на душе приятнее было?
Хочу разобраться, как всё таки наиболее правильно, и в том числе и с точки зрения дальнейшего сопровождения. Часто говорят — смотрите исходники проектов. Но вот на них не пишется их рейтинг с точки зрения красоты и правильности архитектуры. Смотря код достаточно больших проектов, видел и дублирующий код, и интерфейс связанный с логикой, и минимум классов. И не поймёшь — то ли они так делают по незнанию (что странно, учитывая размер проекта), либо специально в целях экономии времени.
0
Эксперт Python
 Аватар для dondublon
4653 / 2073 / 366
Регистрация: 17.03.2012
Сообщений: 10,183
Записей в блоге: 6
20.02.2014, 12:02
Окончательного учебника не дам, даже не знаю, есть ли таковой.
В качестве дополнения к посту 5 могу только посоветовать написать ваш класс так, чтобы им можно было пользоваться в консольном приложении.
0
Житель Земли
 Аватар для DenNik
3004 / 3026 / 390
Регистрация: 26.07.2011
Сообщений: 11,465
Записей в блоге: 1
20.02.2014, 15:01
Цитата Сообщение от dondublon Посмотреть сообщение
Не очень удобно, когда вам понадобилось использовать написанный функционал в другом месте, не только по той кнопке, и ВНЕЗАПНО вы обнаруживаете, что его невозможно вытянуть, не потащив за собой StringGrid1, CheckBox1..3 и RadioButton1 и всё остальное.
если у меня возникает функционал, который нужно использовать в разных местах, то я, естественно, оформляю это отдельной функцией с передачей ей нужного " StringGrid1, CheckBox1..3 и RadioButton1 и всё остальное".
в данном вопросе нет черного и белого. не стоит категорично заяалять
Цитата Сообщение от dondublon Посмотреть сообщение
Это плохо, отвязывайте.
не зная структуры программы.
0
Эксперт Python
 Аватар для dondublon
4653 / 2073 / 366
Регистрация: 17.03.2012
Сообщений: 10,183
Записей в блоге: 6
20.02.2014, 15:15
Цитата Сообщение от DenNik Посмотреть сообщение
если у меня возникает функционал, который нужно использовать в разных местах, то я, естественно, оформляю это отдельной функцией с передачей ей нужного " StringGrid1, CheckBox1..3 и RadioButton1 и всё остальное".
в данном вопросе нет черного и белого. не стоит категорично заяалять
"Если" Как будто он изредка возникает, внезапно.
А я буду категорично заявлять, уж извините.
Потому что знаю, как устроена нормальная программа. Это айсберг, в котором большая, подводная часть - это именно без-гуишный функционал. И таки да, передавать туда gui-шные элементы - это тоже говнокод.
Цитата Сообщение от DenNik Посмотреть сообщение
не зная структуры программы.
Зная структуру программы (вернее, про её отсутствие), топикстартер достаточно всё описал. Ещё замечания?
1
Житель Земли
 Аватар для DenNik
3004 / 3026 / 390
Регистрация: 26.07.2011
Сообщений: 11,465
Записей в блоге: 1
20.02.2014, 16:13
Цитата Сообщение от dondublon Посмотреть сообщение
И таки да, передавать туда gui-шные элементы - это тоже говнокод.
окей, гуру. приведи пример неговнокода применительно к ситуации, когда нужно взаимодействовать с gui, но без привязки к gui (тавтология получилась, уж не обессудьте), а также чтобы НЕ
Цитата Сообщение от dondublon Посмотреть сообщение
передавать туда gui-шные элементы
0
Эксперт Python
 Аватар для dondublon
4653 / 2073 / 366
Регистрация: 17.03.2012
Сообщений: 10,183
Записей в блоге: 6
20.02.2014, 16:27
Цитата Сообщение от DenNik Посмотреть сообщение
окей, гуру. приведи пример неговнокода применительно к ситуации, когда нужно взаимодействовать с gui, но без привязки к gui (тавтология получилась, уж не обессудьте), а также чтобы НЕ
Возможны варианты.
Смотрим со стороны gui. Не-гуишный код назовём ядром (просто чтобы как-то назвать).
1. Ничего в ядро не передаём, только получаем. Кстати, самая простая и частая ситуация.
2. Когда в gui не можем отследить момент, что в ядре что-то произошло, а отобразить надо - из gui подписываемся на события ядра. Разумеется, сами события должны быть запрограммированы.
Ну и
3. Передавать контол в ядро тоже можно, в некоторых случаях это бывает хорошо, НО! обязательно при этом абстрагируем контрол, чтобы ядро не как конкретный контрол его рассматривало, а как нечто более абстрактное. По хорошему - интерфейс (не в смысле gui, а в смысле IInterface). Имеет смысл, когда класс в ядре только затем и делается, чтобы его рисовать.

Добавлено через 1 минуту
DenNik, предвижу сарказм про ненужное усложнение. Ну что ж, такова селяви.
0
 Аватар для Duxan
1 / 1 / 0
Регистрация: 29.05.2013
Сообщений: 54
20.02.2014, 21:23  [ТС]
Распишу более конкретно.

В программе динамически создаются вкладки на Page Control. За это отвечает процедура NewTab без параметров (так как Page Control существует в единственном экземпляре и сразу ясно, где создавать). Согласно вышесказанному, стоит переписать эту процедуру NewTab, передавая ей в качестве параметра нужный Page Control? И аналогично со всеми другими процедурами?

И вопрос по поводу свойств. Свойства нужны для работы с полями. Но только ли через них работать?
На примере: есть поле типа динамического массива, в котором хранятся ссылки на создаваемые табы. В данном случае я работаю не используя свойства, просто напрямую обращаясь к нужной вкладке:
FTabList[I].Key.Name := 'Smth';
В данном случае то мне кажется удобным, при том что само поле описано в секции Private. Или же я просто не понял смысл свойств?
0
Эксперт Python
 Аватар для dondublon
4653 / 2073 / 366
Регистрация: 17.03.2012
Сообщений: 10,183
Записей в блоге: 6
21.02.2014, 08:09
Цитата Сообщение от Duxan Посмотреть сообщение
В программе динамически создаются вкладки на Page Control. За это отвечает процедура NewTab без параметров (так как Page Control существует в единственном экземпляре и сразу ясно, где создавать). Согласно вышесказанному, стоит переписать эту процедуру NewTab, передавая ей в качестве параметра нужный Page Control? И аналогично со всеми другими процедурами?
Я бы сделал на событиях. Это не так сложно, даже писать особо не надо - уже костяк написан.
В TList<T> (Generics.Collections)
Ваши данные объединяете в класс, внутри класса список ваших объектов TList<T>.
У него уже готово событие OnNotify, на него подписываетесь.
В этой процедуре делаете обработку - если появился новый итем, исходя из него уже делаете NewPage.
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
BigData = class
 ... MyObjects: TList<MyObject>;
 
Из gui:
 
  ByBigData.OnNotify = OnCOllectionNotify; // внутри BigData передать в list
 
procedure MyForm.OnCOllectionNotify(Sender: TObject; const Item: T; Action: TCollectionNotification);
begin
    if Action = cnAdd then
        THis.NewTab;
end;
Конечно, можно и ещё аккуратнее сделать, в частности, прямо в BigData определять Action, но тут уж писать мне лень.
2
 Аватар для Duxan
1 / 1 / 0
Регистрация: 29.05.2013
Сообщений: 54
21.02.2014, 09:17  [ТС]
Спасибо за идею, попробую реализовать.
0
 Аватар для pHOMM
480 / 253 / 51
Регистрация: 30.06.2010
Сообщений: 651
22.02.2014, 23:55
Долго слежу за темкой.
Во всём согласен с dondublon.
Могу добавить ещё такую мысль. Для работы с гуёвыми контролами с целью наполнения данными неких сущностей, можно использовать разные подходы, начиная от обычного MVC и заканчивая Bindings , для чего существуют всякие библиотеки.
Для тренировки навыка работы в ООП стоит заморочиться такими вещами. Конечно, в реальных проектах так бывает усложнять некогда и незачем. Но также и бывает, что при необходимости каких-то переделок и доводок могут быть сложности с жёстким кодом, что увеличит время разработки. Гибкость, конфигурируемость и модифицируемость сильно облегчают жизнь, и ооп в этом неслабо помогает.
Цитата Сообщение от Duxan Посмотреть сообщение
И вопрос по поводу свойств. Свойства нужны для работы с полями. Но только ли через них работать?
На примере: есть поле типа динамического массива, в котором хранятся ссылки на создаваемые табы. В данном случае я работаю не используя свойства, просто напрямую обращаясь к нужной вкладке:
FTabList[I].Key.Name := 'Smth';
В данном случае то мне кажется удобным, при том что само поле описано в секции Private. Или же я просто не понял смысл свойств?
Тут всё просто. Свойство служит для сокрытия способов доступа к данным через методы, т.е. при обычном чтении и присвоении массива Вы не заметите необходимости свойств. Но стоит чуть вывести систему из равновесия - например не уследить за индексами, или когда код из разных мест меняет данные, и нарушается целостность (когда нечто хранит данные в таком массиве, а другой их поменял, первый не будет "осведомлён" об изменениях и будет "полагать" что данные старые). На примере индексов - при неверном индексе - будет исключение доступа к памяти, работая через метод же, легко набросить проверку индекса и упростить ошибку до обычного сообщения пользователю, а код который работал с массивом при переделке на массивовое свойство даже не потребуется менять.
Более того, свойства часть используются для ограничения области видимости и возможностей доступа - например только на чтение. Внутри одного модуля, элементы разных классов конечно видят всю подноготную других классов (кроме случая с модификатором strict), поэтому разделение на модули даст ещё большее повышение надёжности классов - Вы будете уверены что никакой другой код не имеет доступа к внутренностям, а может работать только через публичные методы и свойства только разрешённым образом.
Есть ещё одна интересная особенность свойств. Вы можете не иметь под них даже данных (полей), а вычислять значение на лету, в функции, для внешнего же пользователя данного класса, это будет выглядеть как обращение к "переменной", что упрощает понимание.
И ещё много всяких тонкостей и особенностей есть. Советую почитать http://delphikingdom.ru/asp/vi... logid=1186
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
22.02.2014, 23:55
Помогаю со студенческими работами здесь

модули и блоки или просто модульность
Всем добрый вечер. Собственно интересует такой вопрос. Есть шаблон вида: так вот как сделать так что бы при переходе вида:...

Модульность в java, объясните пожалуйста новичку
Я уже знаком с синтаксисом в java, с устройством классов, объектов, наследованием, но не знаком ещё ни с одной библиотекой. Я где то читал...

Модульность. Программа, ссылающаяся на другую (как реализовать?)
Здравствуйте! Пишу курсовую, собственно уже все готово (тьфу тьфу тьфу), есть две программы, меню и игра, Из меню я вызываю всякие...

Правильное swprintf, правильное wprintf ?
Вродеж бы по ,,инструкции,,.... ..... wchar_t str = L&quot;tanya&quot;; // обозначает, что строка не однобайтная, а двуб ...

Изучаю Python, сейчас учу основы ООП, где можно найти задачи по ООП
Скиньте пожалуйста источники с задачами(желательно на русском)


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
Новые блоги и статьи
Как я обхитрил таблицу Word
Alexander-7 21.03.2026
Когда мигает курсор у внешнего края таблицы, и нам надо перейти на новую строку, а при нажатии Enter создается новый ряд таблицы с ячейками, то мы вместо нервных нажатий Энтеров мы пишем любые буквы. . .
Krabik - рыболовный бот для WoW 3.3.5a
AmbA 21.03.2026
без регистрации и смс. Это не торговля, приложение не содержит рекламы. Выполняет свою непосредственную задачу - автоматизацию рыбалки в WoW - и ничего более. Однако если админы будут против -. . .
Программный отбор значений справочника
Maks 21.03.2026
Установка программного отбора значений справочника "Сотрудники" из модуля формы документа. В качестве фильтра для отбора служит предопределенное значение перечислений. Процедура. . .
Переходник USB-CAN-GPIO
Eddy_Em 20.03.2026
Достаточно давно на работе возникла необходимость в переходнике CAN-USB с гальваноразвязкой, оный и был разработан. Однако, все меня терзала совесть, что аж 48-ногий МК используется так тупо: просто. . .
Оттенки серого
Argus19 18.03.2026
Оттенки серого Нашёл в интернете 3 прекрасных модуля: Модуль класса открытия диалога открытия/ сохранения файла на Win32 API; Модуль класса быстрого перекодирования цветного изображения в оттенки. . .
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru