![]() |
Модераторы: bsa |
![]() ![]() ![]() |
|
EvilsInterrupt |
|
|||
Executables research ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1019 Регистрация: 14.7.2007 Где: Железнодорожный, МО, Россия Репутация: нет Всего: 9 |
Что тревожит:
Начать разрабатывать с использованием С++. Пояснение тревоги: Раньше сидел на Delphi и худо бедно привык к ее среде разработки и модели ООА\П. Потом при переходе на С используя MS Visual Studio 2005(8) Team Suite тоже довольно понятно. Процесс разработки упирается в простейшее: - Поиск ответа1 "Что хотим сделать ?" - Поиск ответа2,...,ответ_k "Как достичь ответ1 ?" - После к каждому ответу2 и до ответа_k задаем свои вопросы и получаем для них ответы2_1, ответы2_2 - Повторяем до тех пор пока не получим тривиальные ответы, которые оформляем функции. Получается своего рода алгоритмическое дерево. Одна ф-ция вызывает вторую, вторая третья, ну и разные вариации, хотя местами это не дерево а сетка, т.к. переплетения. + в этом подходе, это то что очень легко написать проверочный код и понять "А так ли я хочу это видеть ?", возможно появится : "млин, это же не совсем то что хочу" и потому можно на ранней стадии разработки увидеть косяк, ну и увидеть результат от которого будет зависеть дальнейшая разработка. ----- Решил на С++, т.к. почитал плюсы ОО-стиля анализа, проектирования и программирования, меня они впечатлили и решил попробовать. Что выходит ? В ОО- стиле, ничего подобного не могу!!! ;( Как возьмусь, так сразу же то одна ошибка, то мне чтото не понравится в классе и методе и если в процедурном всегда легко написать проверочный код и узнать а все ли так как я хочу, то в ОО-стиле надо четко задать конструктор, а это надо сделать инициализацию класса, причем продумать логику его создания, толи он по чтению тогда надо вернуть (I_IStream *) , толи он по записи тогда вернуть (I_OStream *) . Но это еще не все, в конкретике это будет C_FileStream который есть сынок C_IOStream и вот пока два класса не напишешь, ничего не получишь! Все сводится к тому, что результат можно увидеть через громадное количество разработанных методов, т.к. класс не создастся без инициализирующих действий. Вобщем, голова идет кругом, у меня даже желание пропадает, от такого количество сложностей, которые еще не понятно стоит ли преодолевать или это ошибочный путь ? Вопрос темы: Прошу прояснить, как следует подходить к процессу разработки на С++ , чтобы можно видеть маленькие промежуточные результаты, как вообще стоит подходить к разработки ОО-приложений ? Что делаю? 1. Читаю Гради Буча про ООА\П 2. В планах после него читать Фаулера про рефакторинг. ЗЫ: Этот вопрос относится больше всего к философии разработки. Да, не спорю, но мне бы хотелось слышать практический опыт. |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
задача в ооп решается посредством объектов, где каждый из объектов является тоже задачей.
объект реализует внутреннее состояние путем реакции на сообщения. состояние - это та же переменная и или их набор из процедурного. сообщение - это функция которая изменяет состояние. основное отличие от процедурного это именно локализация состояния. т.е в процедурном есть просто набор функций и данных, а в ооп весь тот же набор функций и данных разбит по группам т.е. по классам, и есть средства за контролем доступа и инициализации. Такое же дерево-сетка, один объект изменяет другой, тот третий .. приведите небольшой условный пример решения задачи в процедурном стиле, а я напишу вариант ее решения в ооп. ![]() |
|||
|
||||
EvilsInterrupt |
|
|||
Executables research ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1019 Регистрация: 14.7.2007 Где: Железнодорожный, МО, Россия Репутация: нет Всего: 9 |
Лучше будет взять реальную ситуацию и ее обсудить. В-общем, разрабатываю библиотеку по работе с файлом, памятью, сетью в единном стиле написания кода.
При процедурном, я бы объявил IO_CONTEXT и функции IO_GetByte, IO_GetWord, IO_GetDWord, IO_SetByte, IO_SetWord, IO_SetDWord, IO_ReadBuf, IO_WriteBuf, IO_Init, IO_Close, IO_Flush, IO_UpdateBuf, ну можете еще какие-нить возле этой темы пробегающие ) Как же пытаюсь напрограммить в ОО-стиле ? 1. Задаю вопрос : "Что будет делать клиентский код? Что ему надо? " - Иметь доступ по чтению - Иметь доступ по Записи - Иметь доступ по чтению или записи Исходя из этого прихожу к концепции стримов и задаю интерфейсы: class I_Stream; // << --- здесь методы Clone, SetSeek общие для всех интерфейсов стримов class I_IStream : public I_Stream; // Возврат байта, ворда, дворда, чтение буфера class I_OStream : public I_Stream; // Установка байта, ворда, дворда, запись буфера class I_IOStream : public I_IOStream; и реализовываю первый абстрактный класс class C_IOStream : public I_IOStream; Дальше спрашиваю себя : "Что конкретно будет юзер писать ?" - Работа с файлами, тогда class C_FileStream : public C_IOStream; - Работа с памятью , тогда class C_MemoryStream : public C_IOStream; - Работа с сетью, тогда class C_NetworkStream : public C_IOStream; Казалось бы все хорошо выглядит, но не удавалось пощупать результат, пока не продумал архитектуру библиотеки! И даже сейчас, я не могу пощупать, т.к. чтобы создать файловый стрим, мне надо реализовать множество методов, пусть даже сделав пустышки(костыли) на время. Мне бы хотелось знать методику разработки ОО-библиотек\приложений, которые бы позволяли сразу же видеть промежуточный результат, т.е. как бы написал клиентский код, посмотрел и спросил себя "А все ли верно?", но вот только как это сделать? ПОка не знаю и не умею, приходится писать и надеяться что все будет так как и надо, что невозникнет потом каких-либо нюансов! Замечу: Программисты давно стараются привлечь методики программирования, чтото заставляют проверять компилятор, чтото компоновщик, а чтото в UML тулзах на согласснованность проверят. Так что не думаю что уместна фраза : "А ты напиши и посмотри", надо как-то более практичный подход или "написал мало, проверил, убедился" вот только как как это "мало написал" ? |
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 85 Всего: 196 |
EvilsInterrupt, зачем ее писать? boost::asio и стандартные потоки iostream используй.
А разобравшись с ними, у тебя уже меньше вопросов будет возникать по поводу ООП. Это сообщение отредактировал(а) bsa - 22.4.2009, 10:58 |
|||
|
||||
EvilsInterrupt |
|
|||
Executables research ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1019 Регистрация: 14.7.2007 Где: Железнодорожный, МО, Россия Репутация: нет Всего: 9 |
bsa,
Плюс моей библиотеки в том, что потому будет моя собственная библиотека типов! для DWORD, BYTE, WORD . Потому что под Intel один порядок байт,а ты посмотри скажем под спарки или Motola какую нить и вывод, в свою библиотеку я смогу вставить свои типы, а вот чужую смогу,но это надо будет перелопачивать. К тому же маловат еще уровень, чтобы в бусте ковыряться |
|||
|
||||
Lazin |
|
||||||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 27 Всего: 154 |
boost::asio уже существует ![]() во первых следует начинать не с интерфейса класса, а с предметной области в данном случае у нас есть набор средств ОС, и средства для взаимодействия с ними это может выглядеть так: есть сущность - Service, некий объект отвечающий за взаимодействие с ОС для разных подсистем могут быть реализованы разные сервисы, к примеру: FileService, TCPService, NamedPipeService, MemoryMappedFileService. есть объект(сущность) Stream, с которым работает пользовательский код. Этот объект должен формировать пользовательский API. К примеру, он может содержать методы GetWord, SetWord, GetByte итд... Далее, должны-быть реализации, к примеру, FileStream, TCPStream, NamedPipeStraem. Каждый из этих объектов не должен работать с объектом ОС напрямую, вместо этого он должен использовать соответствующий сервис. К примеру, FileStream должен использовать FileServcie FileService может быть реализован примерно так
соответственно, у разных сервисов будут разные интерфейсы FileStream может его использовать примерно так:
FileStream должен знать только о FileService, больше ему ничего не нужно, один сервис может работать с множеством Stream объектов соответственно, для всех NamedPipeStram должен быть создан один сервис PipeServcie etc... это позволит разделить интерфейс и реализацию далее, можно провести рефакторинг, например выделить базовый класс для потоков(к примеру IStream) и базовый класс для сервисов, так-же можно создать фабрику объектов для Stream-ов и так далее ![]() в результате это может выглядеть как-то так:
или с помощью фабрики объектов
Соответственно, для другой платформы, тебе потребуется только создать новые сервисы, но не Stream-ы ![]() Это сообщение отредактировал(а) Lazin - 22.4.2009, 12:17 |
||||||||||
|
|||||||||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 85 Всего: 196 |
Порядок байт бывает Big endian (прямой) и little endian (обратный). Это тоже в бусте все учтено. Более того, в стандарте Си (не знаю, как в С++) stdint.h, который определяет типы вида uint32_t, sint8_t... Думаю, твои WORD'ы и прочее рядом не стояли... Изучение буста повысит твой уровень на порядок. И если у тебя не чисто академическая задача по написанию библиотеки, то не трать время на нее - на изучение буста ты потратишь гораздо меньше. Да и через пол году будет меньше разочарований: "ну, кто же так пишет?!?" P.S.: но я уверен, что многие здешние корифеи некоторое время назад тоже занимались изобретением велосипедов... Я в том числе. Просто совет - не трать время. |
|||
|
||||
J0ker |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 986 Регистрация: 17.9.2008 Репутация: 9 Всего: 14 |
||||
|
||||
J0ker |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 986 Регистрация: 17.9.2008 Репутация: 9 Всего: 14 |
||||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 85 Всего: 196 |
![]() |
|||
|
||||
Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 27 Всего: 154 |
||||
|
||||
J0ker |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 986 Регистрация: 17.9.2008 Репутация: 9 Всего: 14 |
существует небезосновательное мнение, что интерфейс класса гораздо важней для пользователя, чем его (класса) содержимое Это сообщение отредактировал(а) J0ker - 23.4.2009, 16:12 |
|||
|
||||
EvilsInterrupt |
|
|||
Executables research ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1019 Регистрация: 14.7.2007 Где: Железнодорожный, МО, Россия Репутация: нет Всего: 9 |
Ну по сути, оно походит на вопрос любого программиста, которые разрабатывает либу для себя: "А как мне будет удобно ее юзать ?". Следовательно он пишет простенький пример кода использования, определяет интерфейс использования и тем самым приходит к "Интерфейс класса" |
|||
|
||||
Lazin |
|
||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 27 Всего: 154 |
содержимое класса, пользователя волновать не должно, но только не разработчика класса ![]() архитектура приложения ведь не токлько из интерфейса состоит, к примеру
или
для программиста это не одно и то-же, но это один и тот-же дизайн, и в первом и во втором случае у нас есть некая сущность - поток данных, и мы в нее можем писАть и читать ![]() просто ОО дизайн позволяет сделать удобный интерфейс для того-же самого архитектурного решения, которое функционально эквивалентно, поэтому и нужно плясать не от того, как мы хотим что-бы это выглядело в коде, а от того, какую функциональность мы хотим получить ![]() |
||||||
|
|||||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 85 Всего: 196 |
Интерфейс класса вытекает из назначения. Реализация методов вытекает и из интерфейса, и из назначения, и из места, из которого у реализующего растут руки... Имхо.
|
|||
|
||||
![]() ![]() ![]() |
Правила форума "C/C++: Для новичков" | |
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Для новичков | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |