Russian Qt Forum

Программирование => Общий => Тема начата: Igors от Август 10, 2013, 05:41



Название: Архитектура ..
Отправлено: Igors от Август 10, 2013, 05:41
Добрый день

Навеяно этим
Перед тем как браться за реальный проект, нужно сесть, успокоиться, возможно, посмотреть в окно, взять листок бумаги и ручку и набросать примерный план того, что и как должно справляться с поставленной задачей: какие основные сущности следует ввести, что должна делать конкретная сущность и какие взаимосвязи между ними должны быть.. Этот процесс не быстрый, возможно он займёт не один день.. и всё же.. После этого более детально определяется интерфейс каждой сущьности с расчётом возможных потенциальных расширений в будущем. Здесь, пожалуй, самый ответственный момент, которому нужно уделить большее внимание. И это один из самых ответственных моментов в разработке архитектуры, который может занять большую часть времени.

И вот когда уже придёт осознание и понимание этих двух предшествующих шагов, выбирается соответствующий инструментарий.
И только после этого можно чего то там пытаться программировать..
Ах как красиво звучит :) Но так ли это происходит на самом деле? Я неоднократно наблюдал совсем иную картину (в том числе и в исполнении автора). Все наоборот - сначала подбирается соответствующий инструментарий (популярный оборот "смотреть в сторону.."). В этом по меньшей мере есть смысл -  если либа это делает, то чего городить велосипед? А начиная с "тшательного продумывания сущностей" мы почти наверняка окажемся с велосипедом. А приняв либу/тул мы во многом вынуждены "плыть по течению" подлаживаясь под либу (что впрочем необязательно плохо).

А Вы как думаете?


Название: Re: Архитектура ..
Отправлено: Old от Август 10, 2013, 07:48
Вы бы написали, что лично вы подразумеваете под архитектурой. Судя по этому посту, это совсем не тоже самое, про что писал m_ax.


Название: Re: Архитектура ..
Отправлено: m_ax от Август 10, 2013, 10:35
Вот ведь знал ведь, что нельзя произносить это новое, матное слово.. :)


Название: Re: Архитектура ..
Отправлено: Bepec от Август 10, 2013, 11:01
Холиварчик от Igors - надо обязательно почитать :)

Архитектура меняется в зависимости от условий :D


Название: Re: Архитектура ..
Отправлено: Igors от Август 10, 2013, 11:55
Вы бы написали, что лично вы подразумеваете под архитектурой. Судя по этому посту, это совсем не тоже самое, про что писал m_ax.
Вот ведь знал ведь, что нельзя произносить это новое, матное слово.. :)
Ну вот, и сразу в кусты. Куда же Вы, и чего сами хватаетесь за boost::iterator при первой же возможности - вместо того чтобы "глубоко продумывать сущности"? :)

Клевать начинающего легко, но по сути он делает то же самое. Есть мощный инструмент QRegExp, вот он его и приспосабливает всяко-разно. А почему он не должен этого делать? Зачем думать о каких-то "сущностях" (да еще и не один день) когда есть подходящий класс? Что Вы сами показали ему кодом? Реализацию на бусте - ну это разница только в инструменте, подход-то тот же самый. Правда у Old были попытки самомтоятельного мЫшления, но это быстро увяло.

Так зачем тогда свистеть о глубокомысленных сущностях - надо просто жрать как можно больше boost. std, Qt - и пытона про запас  :)


Название: Re: Архитектура ..
Отправлено: Old от Август 10, 2013, 12:00
Скажите пожалуйста, какое отношение имеет boost, std и другие библиотеки к архитектуре приложения?
О чем вы говорите?
Вы традиционно не можете сформулировать ваши мысли.

Есть мощный инструмент QRegExp, вот он его и приспосабливает всяко-разно. А почему он не должен этого делать? Зачем думать о каких-то "сущностях"
Ну вот опять. Какое отношение имеет конкретный инструмент решения конкретной подзадачи к архитектуре? О сущностях нужно думать при проектировании, а не при реализации.

(да еще и не один день) когда есть подходящий класс?
Какой подходящий класс? Ему предлагали продумать архитектуру всей подсистемы операций над текстом, а не конкретного решения по разбиению текста на слова.
Вот вы, не долго думая, предложили сделать класс CTextAnalyzer, куда пихать разные методы для обработки текста. Это один из вариантов архитектуры, по мне так самый неудачный, т.к. совершенно не расширяемый без перекомпиляции. Я бы сделал несколько сущностей, вместо одной:
контекст - содержит исходные данные;
операция - абстрактный класс, от которого порождаются все операции над контекстом;
реальные операции - на входе получают входные данные и возвращают результат;
коллекция операций.
Это второй вариант. Скорее всего, я бы продумывал возможность связи операций "пайпами", что бы результат одной операции, можно было использовать как входные данные для другой и т.д. Что бы пользователь мог формировать цепочки операций для сложной обработки.
Даже для такой простой задачи, нужно потратить время на проектирование. Кстати, после правильного проектирования, вы уже не увидите в контексте этой подзадачи никаких внешних библиотек, они будут спрятаны в реализации. А работать вы будете с понятиями предметной области самой задачи. Не так красиво как, скажем, в форте, но все же.

Что Вы сами показали ему кодом?
Конкретное решение конкретной маленькой подзадачи.

Правда у Old были попытки самомтоятельного мЫшления, но это быстро увяло.
Ну я уже не молод. :)
Жаль, что вы так и не попробовали самостоятельно мыслить.


Название: Re: Архитектура ..
Отправлено: Igors от Август 11, 2013, 11:42
Я бы сделал несколько сущностей, вместо одной:
контекст - содержит исходные данные;
операция - абстрактный класс, от которого порождаются все операции над контекстом;
реальные операции - на входе получают входные данные и возвращают результат;
коллекция операций.
Это второй вариант. Скорее всего, я бы продумывал возможность связи операций "пайпами", что бы результат одной операции, ...
Такая архитектура слабо связана с задачей. Сначала человек захотел подсчитать частоту слов. Потом подумалось - хорошо бы еще учесть русский/английский. Потом еще чего-то. Именно так оно и происходит - пусть не всегда но часто, и ничего плохого в этом нет. Никакой "обработки" нет, есть "статистика". На мой взгляд реальнее так

1) Исходная строка хранится в оригинальном виде и никогда не меняется

2) Есть явная сущность "слово". Исходя из "1" слово должно быть ссылкой на участок исходной строки. Хранить ли указатель на исходную строку в слове? Думаю что нет, пусть слово будет тупым std::pair<int, int> внутри класса "анализатор" который имеет разные геттеры для выдачи слов-строк клиенту.

3) Ну что класс анализатор надо так или иначе выделять - само собой, упоминаю лишь для полноты картины.

Вот и все с сущностями, дальше можно просто писать, там достаточно очевидно.

Ну вот опять. Какое отношение имеет конкретный инструмент решения конкретной подзадачи к архитектуре?
Да самое прямое - архитектура и продумывние сущностей просто исчезают, вытесняются инструментом. Хранить слово в виде ссылки (см выше) вроде бы идейно/правильно, НО ни с regexp ни с бустом это дружить не будет. То есть "попастись" и "покушать плюшек" не удастся. Придется писать свое - а это ж велик!! :) Плэтому делается наоборот - подгоняется к инструменту. Напр есть QString::split - значит нам нужно иметь QStringList. Есть удобная возможность замены в QRegExp - используем ее для вычеркивания русских/английских слов. В исполнении начинающего такая беспринципность/безыдейность бросается в глаза. Но стоит блеснуть дустом и сказать что, мол, "более элегантно" - и может вполне пройдет. Хотя метод тот же самый  :)


Название: Re: Архитектура ..
Отправлено: Old от Август 11, 2013, 11:59
Такая архитектура слабо связана с задачей.
С чего бы это?

Сначала человек захотел подсчитать частоту слов. Потом подумалось - хорошо бы еще учесть русский/английский.
Я задал человеку вопрос и он сразу сказал, что будет много сложной обработки текста. Т.е. он уже знает, что ее будет много и разной, и я уверен, что он знает какой именно.

Потом еще чего-то. Именно так оно и происходит...
Все верно, если сразу не подумать, то так оно и будет.

Вот и все с сущностями, дальше можно просто писать, там достаточно очевидно.
Если для вас удобней так - пожалуйста. Мне не понятно, для чего выделять слова. К тому же непонятно, кто же будет работу работать (сортировать/искать/фильтровать слова/что-там еще Spark понадобиться) - сам парсер? Представляю какой это будет класс, что делать если понадобятся другие операции? Что делать если для расчета чего-то сложного потребуется результаты разных примитивных операций?

Да самое прямое - архитектура и продумывние сущностей просто исчезают, вытесняются инструментом.
Это потому что вы не умеете делать правильно. Для этого нужно почитать умных книжек про ООП, но для вас это глупость. ;)
Обратите внимание, не по C++, а именно по ООП.

Плэтому делается наоборот - подгоняется к инструменту.
Вопросов нет. :)


Название: Re: Архитектура ..
Отправлено: m_ax от Август 11, 2013, 12:13

Ну вот опять. Какое отношение имеет конкретный инструмент решения конкретной подзадачи к архитектуре?
Да самое прямое - архитектура и продумывние сущностей просто исчезают, вытесняются инструментом.
Да, да.. У вас что не одна крайность, то другая  :)

Цитировать
Хранить слово в виде ссылки (см выше) вроде бы идейно/правильно, НО ни с regexp ни с бустом это дружить не будет. То есть "попастись" и "покушать плюшек" не удастся. Придется писать свое - а это ж велик!!
А вы почитайте про boost::regex http://www.boost.org/doc/libs/1_54_0/libs/regex/doc/html/index.html (http://www.boost.org/doc/libs/1_54_0/libs/regex/doc/html/index.html)  
Может тогда и велик свой с Pair<int int> писать не придётся)


Название: Re: Архитектура ..
Отправлено: Old от Август 11, 2013, 13:42
Да, да.. У вас что не одна крайность, то другая  :)
Все как всегда. :)

Я конечно понимаю, что ТС это не нужно, но я хочу написать это сообщение для тех, кто хочет разобраться с ООП и всякими там архитектурами.
Основная задача ООП это возможность описания (решения) задачи в терминах предметной области, т.е. мы вначале описываем эти самые термины, а потом решаем задачу используя их.
Давайте рассмотрим один из вариантов проектирования, на примере задачи Spark: есть текст, нужно собирать различную статистику по этому тексту, уметь фильтровать/искать/сортировать слова и иметь возможность расширять эти операции, использовать их совместно.
Какие мы можем выделить термины:
Source - источник данных. Объект этого класса может загружать текст из файла, получать из строки/вектора символов. Мы можем сделать своего наследника, который будет получать текст из архива, файла ресурсов или сети/сайта/...
Parser - парсер текста. Объект который сможет в зависимости от заданных параметров разбивать текст на токены по заданным символам, регулярным выражениям или мы можем задать свой функтор, который будет разбивать текст по любым нужным нам правилам.
StatData - статистические данные.
Парсер получает на входе объект Source, обрабатывает его и возвращает результат в объекте StatData. Дальше эти статистические данные можем передавать в операции (Operation), например, нам нужно отфильтровать из всего набора слов только заданные - мы передаем объект StatData в объект операции FilterOp, на выходе мы получаем объект StatData только с заданными словами. Дальше мы можем отсортировать эти слова по нужному нам правилу, передаем нужные слова в операцию SortOp  и на выходе получаем StatData с отсортированными словами. В дальнейшем мы можем расширять операции с помощью разделяемых библиотек или создать класс операций JavaScriptOp/LuaOp/PythonOp и появиться возможность описывать операции скриптами.
Что же мы имеем. После описания терминов мы можем описывать решение нашей задачи терминами нашей предметной области Source, StatData, Parser, Operation, ... Как вы видите, здесь уже нет никаких QRegExp, split и всяких бустов. Все они спрятаны внутри наших терминов. В дальнейшем мы можем спокойно изменять реализацию терминов (например перейти с Qt на boost) и это затронет само решение задачи минимально. Вам не придется переписывать весь код.
Код
C++ (Qt)
Source src( "text.txt" );
StatData res;
 
Parser p;
p.setRegExpSeparator( "[\\s\\.,:;-()]+" );
StatData data = p.process( src );
 
FilterOp op1( "Shit*" );
res = op1.process( data );
 
SortOp op2( SortOp::Word, SortOp::Asc );
res = op2.process( res );
 

ООП нужно прочувствовать и понять, поэтому я очень не рекомендую учить C++ (а главное ООП) совместно с Qt. Qt зажимает обучаемого в свое дерево классов, учащийся не решает задачу с ООП, а размазывает решение по слотам разных виджетов, получая монстра, которого невозможно развивать и поддерживать, не говоря уже от отделения функционала от GUI.


Название: Re: Архитектура ..
Отправлено: Igors от Август 12, 2013, 09:55
А вы почитайте про boost::regex http://www.boost.org/doc/libs/1_54_0/libs/regex/doc/html/index.html (http://www.boost.org/doc/libs/1_54_0/libs/regex/doc/html/index.html)  
Может тогда и велик свой с Pair<int int> писать не придётся)
Да очень может быть. Но тогда не надо заливать про какое-то тщательное обдумывание, а прямо сказать - начинаем с выбора инструментария. Как я уже говорил, это как минимум резонно.

В дальнейшем мы можем спокойно изменять реализацию терминов (например перейти с Qt на boost) и это затронет само решение задачи минимально. Вам не придется переписывать весь код.
Код
C++ (Qt)
Source src( "text.txt" );
StatData res;
 
Parser p;
p.setRegExpSeparator( "[\\s\\.,:;-()]+" );
StatData data = p.process( src );
 
FilterOp op1( "Shit*" );
res = op1.process( data );
 
SortOp op2( SortOp::Word, SortOp::Asc );
res = op2.process( res );
 
А зачем 3 process? И зачем выносить наружу Parser, FilterOp и SortOp? Мне кажется это "action" а не класс. Я бы сделал все методами CTextAnalyzer, которые возможно могут принимать функторы. Ну и первое что бросается в глаза - а не слишком ли широко размахнулись? Про частоту слов пока ничего - наверное еще класс? Не многовато ли сущностей? Может лучше начать с обдумывания конечного класса, которым будет непосредственно пользоваться UI. Как оно по индексу получит текст слова и (в одном из вариантов) частоту? Выдать 2 контейнера - ну неэкономично, да и общность рубит капитально. Что бы Вы предложили?

ООП нужно прочувствовать и понять, поэтому я очень не рекомендую учить C++ (а главное ООП) совместно с Qt. Qt зажимает обучаемого в свое дерево классов, учащийся не решает задачу с ООП, а размазывает решение по слотам разных виджетов, получая монстра, которого невозможно развивать и поддерживать, не говоря уже от отделения функционала от GUI.
За исключением неудачного слова "рекомендую" (учитель нашелся) - все очень правильно, полностью согласен


Название: Re: Архитектура ..
Отправлено: Old от Август 12, 2013, 10:12
А зачем 3 process?
Для выполнения трех разных действий: разбиения исходного текста, фильтрации и сортировки. Не? :)

И зачем выносить наружу Parser, FilterOp и SortOp?
Потому что это отдельные сущности выполняющие разные функции.
Здесь я привел всего пару операций, их будет больше в зависимости от потребностей Spark. Причем их можно выполнять в разных последовательностях для получения сложных результатов.

Я бы сделал все методами CTextAnalyzer, которые возможно могут принимать функторы.
Не выразительное название. Лучше всего его назвать MainWindow. :)

Ну и первое что бросается в глаза - а не слишком ли широко размахнулись?
Пяток классов...? Конечно нет. Но для привычных вам хелловорлдов/ФиндРеплейсов это конечно многовато.

Про частоту слов пока ничего - наверное еще класс?
Ну как же, после разбиения исходного текста уже будет все посчитано и возвратиться из Parser::process в StatData.

Не многовато ли сущностей?
Вы уже запутались? :)

Может лучше начать с обдумывания конечного класса, которым будет непосредственно пользоваться UI.
Так это и есть конечные классы, которые будут использоваться хоть из GUI хоть из main().

Как оно по индексу получит текст слова и (в одном из вариантов) частоту?
Используя методы класса StatData.

Выдать 2 контейнера - ну неэкономично, да и общность рубит капитально.
Какую общность кто рубит? Не рассуждайте о неведомых вам вещах. :)

Что бы Вы предложили?
Глупость. Почитать вам книги. :)

все очень правильно, полностью согласен
Мне совершенно не важно ваше мнение, в вещах, в которых вы, как мне кажется, совершенно не разбираетесь.  ;)


Название: Re: Архитектура ..
Отправлено: m_ax от Август 12, 2013, 11:11
Цитировать
Да очень может быть. Но тогда не надо заливать про какое-то тщательное обдумывание, а прямо сказать - начинаем с выбора инструментария. Как я уже говорил, это как минимум резонно.
Я привёл эту ссылку лишь по той причине, что вы не зная возможности которые предоставляет boost::regex утверждали, что написание вашего велика будет оправдано:
Цитировать
Хранить слово в виде ссылки (см выше) вроде бы идейно/правильно, НО ни с regexp ни с бустом это дружить не будет. То есть "попастись" и "покушать плюшек" не удастся. Придется писать свое - а это ж велик!!

Вот в этом весь Вы  :)



Название: Re: Архитектура ..
Отправлено: Akon от Август 13, 2013, 00:55
Цитировать
А зачем 3 process? И зачем выносить наружу Parser, FilterOp и SortOp? Мне кажется это "action" а не класс. Я бы сделал все методами CTextAnalyzer, которые возможно могут принимать функторы. Ну и первое что бросается в глаза - а не слишком ли широко размахнулись? Про частоту слов пока ничего - наверное еще класс? Не многовато ли сущностей? Может лучше начать с обдумывания конечного класса, которым будет непосредственно пользоваться UI. Как оно по индексу получит текст слова и (в одном из вариантов) частоту? Выдать 2 контейнера - ну неэкономично, да и общность рубит капитально. Что бы Вы предложили?

Т.н. конечный класс - это против ООП  :) ООП проповедует множество классов при условии возложения на них четких конкретных задач. Т.е. имеется как-бы сфокусированность класса на определенной задаче (high cohesion). На практике ищется компромисс - достаточная сфокусированность при минимальном числе классов. Ваш единственный конечный (расфокусированный) класс - это одна из крайностей. Такому подходу есть даже название - божественный объект (god object); антипаттерн.

Представьте, есть GUI компонент (виджет), задающий параметры парсера. Ему достаточно только более узкого класса Parser, а не чего-то большего (CTextAnalyzer). Представьте, вам нужно написать модульные тесты - не в пользу CTextAnalyzer. Короче, в задаче выделен фокус - парсер. Хреновый архитектор плохо расставит фокусы, получится "мутная" ООП декомпозиция.

CTextAnalyzer с функторами или виртуальными методами (менее гибко) - тоже вариант для определенных задач, например, если просто проанализировать текст с целью получить только результат, не выводя динамику и не изменяя параметров в процессе анализа. Но, если потребовать более сложного, например, в отношении парсинга, то функтор парсинга преобразуется в класс парсера с методами и состоянием.


Название: Re: Архитектура ..
Отправлено: Igors от Август 13, 2013, 09:12
Т.н. конечный класс - это против ООП  :)
Виноват, неудачно выразился. Я имел ввиду не сколько там классов, а каким образом UI будет забирать готовые данные для их конечной визуализации. Т.е. как это выглядит с точки зрения UI

ООП проповедует множество классов при условии возложения на них четких конкретных задач...
Хмм.. ну вот допустим предлагается класс SortOp. Да, вроде задача на него возложена четко - сортировать. Но как он будет сортировать по частоте? Откуда он возьмет хеш/мап частот? Построит сам? Ну частоты могут быть нужны и без сортировки. Исходный контейнер ему тоже надо подавать. Выходит SortOp ничего не решает, чего тогда его выделять?

И кто будет строить цепочки из 3 process? Логичнее при изменениях в UI сразу заряжать опции и, возможно, вызывать один propcess/go. А так где хранить экземпляры этих многочисленных классов?

Однако мы как бы все дальше и дальше уходим в "мир грез". Задачка-то детская, а мы уже нагородили 3 класса, и вроде как это только начало  :)

Я привёл эту ссылку лишь по той причине, что вы не зная возможности которые предоставляет boost::regex утверждали, что написание вашего велика будет оправдано:
Цитировать
Хранить слово в виде ссылки (см выше) вроде бы идейно/правильно, НО ни с regexp ни с бустом это дружить не будет. То есть "попастись" и "покушать плюшек" не удастся. Придется писать свое - а это ж велик!!

Специально оставил свою цитату чтобы показать - я такого не утверждал :) Бросаясь немедленно в boost::regex Вы вероятно избегнете многих велосипедов, но в то же время и "попадете под влияние". Какую структуру данных выберете для слова? Ну конечно же бустовскую, вряд ли вообще задумаетесь над какой-то сущностью. А поскольку "слово" проходит везде - все будет завязано на итератор дуста. А ведь разбиение на слова - лишь скромная подзадача. Логичнее было ее локализовать - а там уж применить столь любимый Вами буст.


Название: Re: Архитектура ..
Отправлено: Old от Август 13, 2013, 09:34
Хмм.. ну вот допустим предлагается класс SortOp. Да, вроде задача на него возложена четко - сортировать. Но как он будет сортировать по частоте? Откуда он возьмет хеш/мап частот? Построит сам?
Попробуем на пальцах. :) Ему передается объект StatData, вот в нем и будет хеш. Этот хеш будет строиться парсером при разбиение исходного текста.

И кто будет строить цепочки из 3 process?
Ээээ. пользовательский код. :)

Логичнее при изменениях в UI сразу заряжать опции и, возможно, вызывать один propcess/go.
А так и есть. Вы просто не понимаете как это работает. :)

А так где хранить экземпляры этих многочисленных классов?
На Луне? :)

Однако мы как бы все дальше и дальше уходим в "мир грез". Задачка-то детская, а мы уже нагородили 3 класса, и вроде как это только начало  :)
Да нет, это для вас она десткая, а у Spark должно быть много сложной работы.

Бросаясь немедленно в boost::regex Вы вероятно избегнете многих велосипедов, но в то же время и "попадете под влияние". Какую структуру данных выберете для слова? Ну конечно же бустовскую, вряд ли вообще задумаетесь над какой-то сущностью. А поскольку "слово" проходит везде - все будет завязано на итератор дуста.
Бред. Жаль что вы не читаете/не понимаете сообщения других участников обсуждения. :(

Логичнее было ее локализовать - а там уж применить столь любимый Вами буст.
Так вот это и делается. :)

Процитирую вас же:
Выполняйте, и для typeOffset тоже. Свое мнение будете высказывать когда освоите что говорят  :)


Название: Re: Архитектура ..
Отправлено: Bepec от Август 13, 2013, 09:41
Ребят, а мб вы поспорите о разработке, проблемах и ошибках при разработке модульных приложений? По этой теме я б послушал дебаты :D


Название: Re: Архитектура ..
Отправлено: Old от Август 13, 2013, 10:48
Споры и дебаты не интересны, а вот обсудить и что-то придумать можно.
У вас есть вопрос/проблема - вбрасывайте. :)


Название: Re: Архитектура ..
Отправлено: Bepec от Август 13, 2013, 12:04
Да задумался я тут о своих прикладных программах - аля анализаторы/парсеры и прочая фигня. Их довольно много - штук 20. Вот и восхотелось собрать их "в одно". Чтобы можно было добавлять / удалять новые и что бы не было проблемы аля "где лежит что-то там". Как это получше сделать?


Название: Re: Архитектура ..
Отправлено: Old от Август 13, 2013, 12:38
Да задумался я тут о своих прикладных программах - аля анализаторы/парсеры и прочая фигня. Их довольно много - штук 20. Вот и восхотелось собрать их "в одно". Чтобы можно было добавлять / удалять новые и что бы не было проблемы аля "где лежит что-то там". Как это получше сделать?
Вы хотите переделать их в плагины и использовать их в одной оболочки? Или просто запускать разные программы из одной оболочки?


Название: Re: Архитектура ..
Отправлено: Bepec от Август 13, 2013, 12:45
Вот и думаю как лучше сделать и реально ли это :D Плагинами хотелось. "


Название: Re: Архитектура ..
Отправлено: Old от Август 13, 2013, 12:55
Вот и думаю как лучше сделать и реально ли это :D Плагинами хотелось. "
Для такой архитектуры очень важно качественно продумать интерфейсы.
Как и что анализаторы/парсеры анализируют (что является входными данными) и что получается на выходе (выходные данные)?


Название: Re: Архитектура ..
Отправлено: Bepec от Август 13, 2013, 13:18
В принципе на входе у них у всех массив строк - пакеты данных. Их основная задача разбор их по протоколам, анализ, вывод графиков и зависимостей.

update: Ну и часть цепляется к базе данных для более масштабного анализа, или же к файлам лога.


Название: Re: Архитектура ..
Отправлено: Igors от Август 13, 2013, 16:06
Попробуем на пальцах. :) Ему передается объект StatData, вот в нем и будет хеш. Этот хеш будет строиться парсером при разбиение исходного текста.
А чего это парсеру считать частоту - его дело побить на слова. Вообще впечатление что Вы просто нахрюкали классов на каждый чих, нисколько не заботясь о их взаимодействии/зависимостях. Как клиенту пользоваться задуманными классами - не знаете, где хранить их экземпляоы - тоже. В каком формате "слово" - тоже пока ничего нет. Зато классов уже много  :)

Вы просто не понимаете как это работает. :)
Здесь и дальше - просто дешевые понты - игнорирую


Название: Re: Архитектура ..
Отправлено: Old от Август 13, 2013, 20:12
Вообще впечатление что Вы просто нахрюкали классов на каждый чих, нисколько не заботясь о их взаимодействии/зависимостях. Как клиенту пользоваться задуманными классами - не знаете, где хранить их экземпляоы - тоже. В каком формате "слово" - тоже пока ничего нет. Зато классов уже много  :)
Я то знаю как ими пользоваться, что где хранить и как все это взаимодействует, да и все остальные, как я понял, тоже. :)  Специалисту это должно быть понятно по тому наброску кода в моем сообщении. :)
Объяснять это все вам на пальцах дело муторное и не благодарное. Да и не нужно это вам. Всего хорошего. :)


Название: Re: Архитектура ..
Отправлено: Old от Август 13, 2013, 21:18
В принципе на входе у них у всех массив строк - пакеты данных. Их основная задача разбор их по протоколам, анализ, вывод графиков и зависимостей.
 
update: Ну и часть цепляется к базе данных для более масштабного анализа, или же к файлам лога.
Давайте начнем с ядра и прикинем, какие возможности оно должно предоставлять модулям.
Ядро - это программа которая загружает и регистрирует модули. Она предоставляет главное окно, в котором модули с помощью специального api могут размещать свои окна, панель главного меню и панели инструментов (доступ к ним так же возможен через специальные api).
Ядро загружает модули и инициализирует их, передавая каждому модулю ссылку на рабочее пространство (workspace). Рабочее пространство это объект, который объединяет в себе все рычаги управления. Так мы избавимся от 100500 синглетонов, которые частенько очень не удачно используют как точки доступа к некоторым объектам из любого места.
Рабочее пространство должно быть расширяемым: любой модуль может добавить указатель на себя, что бы другие модули могли использовать его функционал.
Теперь нужно продумать все api:
* управление окнами
* управление меню
* управление панелями инструментов
Предлагаю продумать их вместе. :)



Название: Re: Архитектура ..
Отправлено: Old от Август 13, 2013, 23:30
Набросал проект. На нем можно будет упражняться. :)
Привожу функцию main с комментариями, там показан текущий функциона. Загружается и регистрируется внешний сервис логер и в main он достается и используется.
Код
C++ (Qt)
int main( int argc, char *argv[] )
{
       QApplication app( argc, argv );
 
       // Создаем рабочее пространство
       Workspace ws;
 
       // Загружаем модули
       // При загрузке модули могут регистрировать в рабочем пространстве свои сервисы
       PluginManager pluginmanager;
       pluginmanager.loadPlugins( ws );
 
       // Выводим список сервисов
       ws.dump();
 
       // Получаем указатель на логгер по его интерфейсу
       ILogger *l = ws.service<ILogger>();
       Q_ASSERT( l );
       // Используем сервис логирования
       l->log( "Test string" );
 
       return 0;       // app.exec();
}
 


Название: Re: Архитектура ..
Отправлено: Bepec от Август 14, 2013, 07:04
Смотрю.


Название: Re: Архитектура ..
Отправлено: Old от Август 14, 2013, 07:11
Ядро - это программа.... Она предоставляет главное окно..., панель главного меню и панели инструментов...
Я вот сейчас подумал. А почему ядро должно предоставлять GUI? Пусть его предоставляет один из модулей.
Он создаст главное окно и будет обеспечивать весь api связанный с GUI.
Верес, какой вы видите GUI для ваших анализаторов? MDI/SDI? Наличие главного меню/панелей инструментов?


Название: Re: Архитектура ..
Отправлено: Igors от Август 14, 2013, 08:16
Я использую немного другой подход. Плагин экспортирует аж одну ф-цию, называется Main.
Код
C++ (Qt)
int Main( int command, size_t dataSize, void * data );
Дальше просто рисуете N структур которые подаете как data. А оте все "турусы на колесах" работать не будут


Название: Re: Архитектура ..
Отправлено: Bepec от Август 14, 2013, 08:37
Я лично пока никак не вижу, склоняюсь к MDI (если правильно понимаю это слово), как в Visual studio.


Название: Re: Архитектура ..
Отправлено: Old от Август 14, 2013, 08:56
Я лично пока никак не вижу, склоняюсь к MDI (если правильно понимаю это слово), как в Visual studio.

Это набросок интерфейсов, что бы модули могли манипулировать GUI. Эти интерфейсы зарегистрирует специальный модуль gui.
Код
C++ (Qt)
class IMainWindow : public Interface
{
public:
   // Добавить/удалить окно в область MDI
   void    addWindow( QWidget * ) = 0;
   void    removeWindow( QWidget * ) = 0;
 
    // Установить/получить активное окно
   void    activateWindow( QWidget * ) = 0;
   QWidget *activeWindow() = 0;
 
   // Получить список всех окон
   QList<QWidget*> windows() = 0;
};
 
class IMainMenu : public Interface
{
public:
   // Добавить/удалить действие в указанный пункт меню
   void    addAction( const QString &menu, QAction *, int index = -1 ) = 0;
   void    removeAction( const QString &menu, QAction * ) = 0;
   void    addSeparator( const QString &menu, int index ) = 0;
};
 
class IToolBar : public Interface
{
public:
   // Добавить/удалить действие в указанный пункт меню
   void    addAction( QAction *, int index = -1 ) = 0;
   void    removeAction( QAction * ) = 0;
   void    addSeparator( int index ) = 0;
};
 

Сейчас нужно продумать зависимости модулей друг от друга с определением правильного порядка их инициализации.
Что бы не получилось, что мы инициализируем модуль, который попытается использовать сервисы другого модуля, который еще не инициализирован.
В том же QtCreator для этого используются специальные файлы, но я думаю с интерфейс плагина лучше добавить еще один метод, который будет возвращать список строк с именами модулей, которыми он пользуется.


Название: Re: Архитектура ..
Отправлено: Bepec от Август 14, 2013, 08:57
Извините меня пожалуйста, я не успеваю за вашей скоростью. Не хватает времени на работе всё это попробовать и понять. :(


Название: Re: Архитектура ..
Отправлено: Old от Август 14, 2013, 09:02
Извините меня пожалуйста, я не успеваю за вашей скоростью. Не хватает времени на работе всё это попробовать и понять. :(
Это ничего. :)
Я сейчас основные мысли свои запишу, а потом будем исследовать разные варианты. Плюс может еще кто-то захочет поделиться своими мыслями.


Название: Re: Архитектура ..
Отправлено: voral от Август 14, 2013, 11:15
Черт - не понятный треп вылился в интересное обсуждение. Не уловлю вы обсуждаете на примере общих исходников теста. Или "на бумажке" оперируя только интерсными участками?

По поводу MDI/SDI (если я правильно понял тему) - это вообще не важный момент. Он касается только реализации модуля gui. По хорошему надо исходить, что может быть и тот и тот вариант.

Идея со специальным методом сообщающим необходимые модули мне кажется вполне рабочей. Только, имхо, стоит различать модули которые должны быть загружены на момент загрузки данного модуля и модули которые будут необходимы для работы. 
Тоже на уровне сырой идеи.
По первому списку определяется порядок загрузки, по второму списку по окончанию регистрации/загрузки всех модулей принимаем решение, примерно следующая последовательноть:
 идем от последнего загруженного модуля к первому. На каждом модуле (пусть модуль А) выполняем примерно следующее:
- если все нужные модули загружены все ок
- если какого либо модуля (модуль Б) не достает или он неработоспособный:
а. если наличие модуля обязательно - помечаем  модуль А как неработоспособный
б. не обязательно - помечаем как ограничено работоспособный

Если Все модули оказываются неработоспособными работать дальше смысла нет. Если ограниченно - просто сообщения при попытке соответствующиего вызова

Почему, на мой взгляд, это важно: предположим программа работает с БД, при этом мы должны вести протокол работы. При этом должны в протокол попадать и ошибки работы с БД.

Модуль протокола он зависит от БД (нам туда писать надо). ок БД загружаем первым. Но ошибки при работе с БД надо отправлять в модуль протокола (напрямую писать не правильно. Может юзер решит, что протокол в базе это лишний мусор и подключит модуль который будет писать в текстовые файлы.





Название: Re: Архитектура ..
Отправлено: voral от Август 14, 2013, 11:18
Упс... Как я умудрился два раза прочитав тему пропустить исходное сообщение, с которого началось все интересное не знаю.  :-[
Может быть мои идеи черезмерны для данной задачи.....


Название: Re: Архитектура ..
Отправлено: Old от Август 14, 2013, 14:40
По поводу MDI/SDI (если я правильно понял тему) - это вообще не важный момент. Он касается только реализации модуля gui. По хорошему надо исходить, что может быть и тот и тот вариант.
Да, это совершенно не важно для всей системы в целом, но не хочется придумывать сферического коня в вакууме. Поэтому я и предлагаю исследовать этот вопрос на примере реальной задачи.

Идея со специальным методом сообщающим необходимые модули мне кажется вполне рабочей. Только, имхо, стоит различать модули которые должны быть загружены на момент загрузки данного модуля и модули которые будут необходимы для работы. 
Проблема циклических зависимостей может возникнуть только если вы разрабатываете сразу несколько модулей или написали свой модуль и хотите научить других с ним работать. И в первом и во втором случае приходиться модифицировать исходники нескольких модулей.
В этом случае это легко обходиться без дополнительных телодвижений со стороны загрузчика модулей. Для этого можно использовать invokeMethod.

Сейчас продумываю как лучше формировать последовательность инициализации модулей. Мысли и идеи приветствуются. :)


Название: Re: Архитектура ..
Отправлено: Igors от Август 21, 2013, 10:25
Черт - не понятный треп вылился в интересное обсуждение. Не уловлю вы обсуждаете на примере общих исходников теста. Или "на бумажке" оперируя только интерсными участками?
Первоисточник - вот этот многострадальный топик
http://www.prog.org.ru/index.php?topic=25332.msg182126#msg182126 (http://www.prog.org.ru/index.php?topic=25332.msg182126#msg182126)
Читать все замахаетесь, кратко - человек пока не умеет создавать классы и лепит все в MainWindow. Вот стало интересно а как же правильно.

По поводу MDI/SDI (если я правильно понял тему) - это вообще не важный момент.
...
Идея со специальным методом сообщающим необходимые модули мне кажется ...
..
Почему, на мой взгляд, это важно:
Одна вещь Вам кажется неважной, другая - важной. Это Ваше право, но точно так же другой может считать наоборот - в результате обсуждать нечего  :)

Извините меня пожалуйста, я не успеваю за вашей скоростью. Не хватает времени на работе всё это попробовать и понять. :(
Ну хорошо хоть без "ребят" :)  А на деле видимо так: глянул - что-то сложновато, надо вникать и вжиться в темплейт (слава богу один). Потом надо приспособить как-то к своей задаче - и хз удастся ли. Та ну его нафиг, тем более не так уж горит. Если в чем-то ошибся - поправьте.

Предложенный Old интерфейс в библии обозначается типа "проекты которые мы знаем как делать" , т.е. техника/шаблон известны, наверняка не раз юзалось, так почему бы не задействовать?  Манечка с возвратом интерфейсов известна давно и часто переоценивается. Когда-то (давно) я написал пару плагинов для Adobe Acrobat - и был удивлен что никаких интерфейсов/классов нет, а просто на С (одна точка входа). Однако пофыркав я обнаружил что это совсем не так уж плохо. Впрочем если модули независимы - проходит любой протокол обмена хост-плагин.

Да, и по-взрослому API плагина должно предоставлять свой кросс-платформенный UI (а не делать предположения о Qt или др фреймврке)  :)


Название: Re: Архитектура ..
Отправлено: Bepec от Август 21, 2013, 10:36
to Igors:

Это называется дежурство на полигоне без компьютера, интернета и цивилизации :) Увы. Дикарём становлюсь.


Название: Re: Архитектура ..
Отправлено: _Bers от Август 25, 2013, 15:39
Есть у кого нибудь готовый механизм для анализа строки?

Требования: с++ (без qt)
Требования: удобный, простой для понимания, оптимизирован по скорости (парсить нужно быстро в рантайме)

Например, есть текстовый файл. Формат - любой. Не обязательно xml-подобный.
Нужно очень быстро собрать для него загрузчик.

Другой пример: в рантайме создается динамическая структура данных полная по тьюрингу.
Нужно конвертировать содержимое структуры в sql-подобный синтаксис.

Другой пример: скриптовый движок. Нужно в рантайме парсить исходный текст скрипта, и исполнять его.

В общем, требуется механизм, который позволяет удобно и легко для программиста быстро создавать собственные парсеры под разные задачи.


Название: Re: Архитектура ..
Отправлено: m_ax от Август 25, 2013, 19:32
В общем, требуется механизм, который позволяет удобно и легко для программиста быстро создавать собственные парсеры под разные задачи.

boost::spirit   


Название: Re: Архитектура ..
Отправлено: _Bers от Август 25, 2013, 19:52
boost::spirit   

Отклонено. Стоит более внимательно относится к собеседнику:

В общем, требуется механизм, который позволяет удобно и легко для программиста быстро создавать собственные парсеры под разные задачи.


Название: Re: Архитектура ..
Отправлено: Igors от Август 26, 2013, 09:59
В общем, требуется механизм, который позволяет удобно и легко для программиста быстро создавать собственные парсеры под разные задачи.
Ну слышал есть еще Бизон. Написал не один парсер и задумывался об "общности". Довольно трудно. Как правило время на написание парсера - ну 2-3 дня максимум, обычно меньше. Что-то обобщить и продумать не удается. Да, через годик опять возникнет нечто подобное - и опять придется что-то городить, ну это день, переживу. Также не видно какого-то "доминирующего" известного тулза. 


Название: Re: Архитектура ..
Отправлено: Old от Август 27, 2013, 17:46
Реализовал зависимости модулей друг от друга, с защитой от циклических зависимостей.
Добавил еще один модуль gui, который зависит от logger.
Показал, как можно пост-инициализировать logger, что бы он мог настроить свой ui, уже после загрузки модуля gui (логер добавляет окно с логом).
Интерфейс gui пока примитивный для примера.

Основной функционал готов, остается хорошо продумывать интерфейсы и их реализовывать. :)


Название: Re: Архитектура ..
Отправлено: voral от Август 28, 2013, 01:10
Просто беглый пуск:
1. make:
Цитировать
[  4%] Generating moc_moduleloader.cxx
[  8%] Generating moc_workspace.cxx
/home/alex/ProjectC/modprog/modprg/core/workspace.h:0: Note: No relevant classes found. No output generated.
2. Если модули не доступны прога вылетает
Код:
$ ./modprg
Available modules: ()
Initialized modules: ()
Registration services:  ()
Ошибка сегментирования


Название: Re: Архитектура ..
Отправлено: Old от Август 28, 2013, 05:36
1. make:
Все правильно, для Workspace не нужно генерировать moc файл.

2. Если модули не доступны прога вылетает
Так и должно быть. Не нужно демку собирать как релиз, там для контроля используются assert'ы, или уберите из main строки показывающие как использовать сервис логера.