LINUX.ORG.RU

Проконсультируйте по проектированию классов для редактора


0

1

У меня очень слабые навыки проектирования программного обеспечения и мне нужно проконсультироваться немного по поводу создания специализированного векторного графического редактора. Я набросал UML схему, правда она неполная. «Каркас» построен на паттерне компановщик. В качестве «Leaf» я привёл пример cRectangle. А в качестве «Composite» - cCompositePrimitive. Класс cManipulator выполняет операции над cCompositePrimitiveю Методов в классах cCompositePrimitive и cManipulator намного больше, чем я написал. И это на мой вгляд очень плохо. Смысл ведь в том, что как бы главный объект здесь - объект класса cCompositePrimitive и в него добавляются все примитивы в том числе и объекты класса cCompositePrimitive. И так получается, что часть методов которые необходимы только для «корневого» cCompositePrimitive - грубо говоря методы для операций на объектами холста, есть и в самих объектах cCompositePrimitive расположенных на холсте. Каким образом лучше как-то разграничить методы, которые необходимы только корневой и не нужны для обычных составных объектов. Эти методы в cCompositePrimitive оканчиваются на «_». И вот как лучше в cManipulator передавать корневой cCompositePrimitive как член класса cManipulator или просто как в каждый метод класса cManipulator добавить входный параметр - указатель на cCompositePrimitive?


Чтобы корень не перегружать есть Visitor Design Pattern. Конечно, в лучшем мире у нас бы были мультиметоды, но..

Absurd ★★★
()

Если ты хочешь отразить знание о том, что у тебя есть корневой composite, и это холст, то введи такую сущность (Canvas).

Дополнительные замечания. У тебя слишком много обязаностей у каждой сущности. Например вытащи из IDrawObject метод draw - откуда объект знает куда и как ее нужно рисовать? С методом toXML тоже самое. Вытаскивай все это в другие сущности. cManipulator у тебя классический GodObject - свалка не связаных методов. У тебя я там вижу несколько фабрик и методы с суффиксом «_», которые должны уехать в Canvas.

dizza ★★★★★
()
Ответ на: комментарий от dizza

спасибо за хороший фидбэк то, что у меня полная свалка - это я прекрасно понимаю и понимаю что это ОЧЕНЬ неправильно, для этого я обратился за консультацией 1) и куда переместить Draw (в Canvas), точнее в какую сущность. Холст реально это объект GtkDrawingArea, Указатель на него я передаю в метод Draw и уже рисую там - видимо неверно. Согласен

2) Просто я не могу понять как Canvas будет рисовать объект ведь он же не знает какой конкретно графический примитив нужно нарисовать и каким образом конкретный объект рисовать (Ellipse и Polygon ведь по разному рисуются)

3) Из cManipulator я вытаскиваю сущности, а потом из объектов этих сущностей сделать композицию в cManipulator ? Экземпляры новых класов будут членами cManipulator или нет?

g-71
() автор топика
Ответ на: комментарий от dizza

А с вами как-нибудь можно связаться (jabber, icq)? немного поговорить (много времени не отниму) e-mail в профайле мой, если конечно можно

g-71
() автор топика
Ответ на: комментарий от g-71

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

Я думаю пишите сюда, так даже будет лучше - может кто-то добавит от себя.

dizza ★★★★★
()
Ответ на: комментарий от g-71

и куда переместить Draw (в Canvas), точнее в какую сущность

Этому почему-то не учат вузов, но есть масса операций, не принадлежащих никакой сущности. Они по своей натуре некие процедуры или как их еще называют, службы. Метод draw лучше всего поместить в некую stateless сущность Painter, которая и будет сервисом рисования.

Просто я не могу понять как Canvas будет рисовать объект ведь он же не знает какой конкретно графический примитив нужно нарисовать и каким образом конкретный объект рисовать

Тут видимо небольшая путаница. Под понятием «холст» в твоем случае можно понимать 2 вещи: 1) некая сущность из графической билиотеки, которую ты используешь для рисования своих объектов. 2) некая сущность из твоей предметной области. Если говорить о втором случае (а я имел именно его), холст ничего не должен знать про рисование. Объект Painter должен взять твой холст, взять с него все объекты и рисовать их на холсте из gtk (GtkDrawingArea)

Из cManipulator я вытаскиваю сущности, а потом из объектов этих сущностей сделать композицию в cManipulator ? Экземпляры новых класов будут членами cManipulator или нет?

По смыслу, который ты хочешь заложить в cManipulator понятно, что ты хочешь сделать фассад к твоему редактору. Назови cManipulator сEditor-ом, и да, делая композицию твоих сущностей на нем. Но помни, cEditor должен быть простым оьъектом. Его методы должны быть похожи по смыслу на операции, выполяемые пользователем. Если фассад станет слишком большим, разбей его на несколько фассадов, например на cEditorSettings, cEditorMain.

dizza ★★★★★
()
Ответ на: комментарий от dizza

хорошо, спасибо Вам огромное, ну я вот написал чуть выше:

вот у меня так выглядит метод Draw:

class IDrawObject
{
public:
    virtual void Draw(GtkWidget *drawingarea) = 0;
    virtual bool IsInsidePoint(const int x, const int y) = 0;
    virtual void MoveObject(const int dX, const int dY) = 0;
    virtual void ResizeObject(const int x, const int y, const int dX, const int dY) = 0;

соответственно если объект cCompositePrimitive реализация этого метода будет такая

void сCompositePrimitive::Draw(GtkWidget *DrawingArea)
{
	for(CEitem_type it = begin(); it !=  end(); ++it)
		(*it)->Draw(DrawingArea);
}
а у конкретного примитива, так примерно:
void сRectangle::Draw(GtkWidget* DrawingArea)
{
    GdkRectangle update_rect;
    GdkGC* gc = gdk_gc_new(DrawingArea->window);
 
    update_rect.x = m_posX1;
    update_rect.y = m_posY1;
    update_rect.width = m_posX2 - m_posX1;
    update_rect.height = m_posY2 - m_posY1;
	
	// визуализация самого прямоугольника
    gdk_gc_set_rgb_fg_color (gc, &m_colorFG);
    gdk_draw_rectangle (DrawingArea->window, gc, true, update_rect.x, update_rect.y, update_rect.width, update_rect.height);
ну тут по кода в данный момент я думаю всё понятно и вот как лучше огранизовать Canvas? Хотя бы примерно

Просто очень многие методы не получится вынести, потому что тут как бы паттерн компановщик и рекуурсирный по сути обход объектор идёт или я видимо чего-то не знаю

g-71
() автор топика

Как много замечательных средств предоставляет объектно-ориентированное программирование для решения проблем, которых вне этого самого ООП вообще не существует.

runtime ★★★★
()

ООП ГОЛОВНОГО МОЗГА

сабж

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.