Паттерн Composite
От: SomewhereSomehow Россия  
Дата: 30.09.10 12:52
Оценка:
Здравствуйте все!
Есть небольшой вопрос по паттерну Composite
Казалось бы тривиальная задача, но что-то туплю.

Допустим есть два абстрактных класса один простой, второй сам является наследником первого и еще содержит в себе массив дочерних. Как например сложная геометрическая фигура сама является фигурой, но состоит из нескольких простых. Для примера выбрал именно фигуры.
Собственно реальные классы конкретных фигур наследуются от базовых абстраткных. Один соотвтст. конкретная простая фигура (унаследован от базового простого), другой — конкретная составная фигура (унаследован от базового составного).
И хотелось бы во втором классе, который унаследован от составной фигуры, обращаться к элементам массива дочерних фигур как к типу класса унаследованной простой фигуры, а не базовой простой фигуры.

Немного путанно звучит, наверное понятнее будут по коду.

    // абстрактрные классы фигур
    public abstract class ShapeBase
    {
        // размеры, ширина высота
        public virtual int Width { get; set; } 
        public virtual int Height { get; set; } 
        // простой конструктор
        public ShapeBase(){Width = 10;Height = 20;}
    }
    public abstract class ShapeCompositeBase: ShapeBase
    {
        // размер композитной фигуры, сумма соотв.размеров дочерних
        public override int Width { get { return Shapes.Sum(new Func<ShapeBase, int>(SumW)); }  }
        public override int Height { get{ return Shapes.Sum(new Func<ShapeBase, int>(SumH)); } }
        private int SumW(ShapeBase sb) {return sb.Width;}
        private int SumH(ShapeBase sb) {return sb.Height;}
        //дочерние фигуры
        public virtual List<ShapeBase> Shapes { get; set; } 
        public ShapeCompositeBase()
        {
            Shapes = new List<ShapeBase>();
        }
    }
    // производные класы
    // представляет конкретную простую фигуру
    public class SimpleShape : ShapeBase { public int SpecProperty { get; set; } }//свойство производного класса 
    // представляет конкретную сложную фигуру состоящую из конкретных простых
    public class CompositeShape : ShapeCompositeBase{}

    public static class MyTester
    {
        public static void Test()
        {
            SimpleShape ss = new SimpleShape();
            CompositeShape cs = new CompositeShape();
            cs.Shapes.Add(ss);
            cs.Shapes.Add(ss);
            
            // вот тут хотелось бы иметь коллекцию типа List<SimpleShape> а не List<ShapeBase>
            // чтобы не разыменовывать, а обращаться напрямую ведь cs.Shapes лежат объекты SimpleShape
            // а не ShapeBase. Хотя конечно я нигде это не указывал, потмоу как если попытаться в CompositeShape
            // добавить public override List<SimpleShape> Shapes { get; set; } - будет ошибка:
            // "CompositeShape.Shapes': type must be 'System.Collections.Generic.List<ShapeBase>' to match overridden member 'ShapeCompositeBase.Shapes'"
            ((SimpleShape) cs.Shapes[0]).SpecProperty = 1;
            // вместе с тем нужно сохранить возможность передавать объекты коллекции на обработку как ShapeBase
            ShowSizes(cs.Shapes[0]);
            ShowSizes(cs);
            /* 
             * соответственно вопрос
             * как можно в производном классе сложной фигуры, хранить коллекцию конкретных простых фигур,
             * пока нашел только способ с промежуточным классом-коллекцией, которая инкапсулирует преобразование 
             * из ShapeBase в SimpleShape, а само свойство в CompositeShape скрывается следующим образом:

             * SimpleShapeCollection shapes = new SimpleShapeCollection(base.Shapes);
             * public new SimpleShapeCollection Shapes { get{ return shapes; } }

             * Но это похоже на какие-то костыли, наверняка есть способ поизящнее аткое организоать..
             */
        }
        public static void ShowSizes(ShapeBase sb)
        {
            //some code to show Width,Height
        }
    }
Re: Паттерн Composite
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 30.09.10 13:32
Оценка: -1
Здравствуйте, SomewhereSomehow, Вы писали:

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


Загадочный вопрос

SS>Немного путанно звучит, наверное понятнее будут по коду.


SS>
            
SS>            // вот тут хотелось бы иметь коллекцию типа List<SimpleShape> а не List<ShapeBase>
SS>            // чтобы не разыменовывать, а обращаться напрямую ведь cs.Shapes лежат объекты SimpleShape
SS>            // а не ShapeBase. Хотя конечно я нигде это не указывал, потмоу как если попытаться в CompositeShape
SS>            // добавить public override List<SimpleShape> Shapes { get; set; } - будет ошибка:
SS>            // "CompositeShape.Shapes': type must be 'System.Collections.Generic.List<ShapeBase>' to match overridden member 'ShapeCompositeBase.Shapes'"
SS>            ((SimpleShape) cs.Shapes[0]).SpecProperty = 1;
SS>            // вместе с тем нужно сохранить возможность передавать объекты коллекции на обработку как ShapeBase
SS>            ShowSizes(cs.Shapes[0]);
SS>            ShowSizes(cs);
SS>            /* 
SS>             * соответственно вопрос
SS>             * как можно в производном классе сложной фигуры, хранить коллекцию конкретных простых фигур,
SS>             * пока нашел только способ с промежуточным классом-коллекцией, которая инкапсулирует преобразование 
SS>             * из ShapeBase в SimpleShape, а само свойство в CompositeShape скрывается следующим образом:

я бы делал примерно так - сам композит не стоит перегружать лишними методами, пропертями. 

[c#]
public static class Helper
{
    public static IList<TShape> Shapes(this ShapeBase shapeBase)
        where TShape : ShapeBase
    {
        return Shapes.CastTo<TShape>().ToList();
    }
}
Re: Паттерн Composite
От: cvetkov  
Дата: 30.09.10 14:07
Оценка:
Здравствуйте, SomewhereSomehow, Вы писали:

SS>
SS>    public abstract class ShapeCompositeBase<T:ShapeBase>: ShapeBase
SS>    {
SS>        // размер композитной фигуры, сумма соотв.размеров дочерних
SS>        public override int Width { get { return Shapes.Sum(new Func<ShapeBase, int>(SumW)); }  }
SS>        public override int Height { get{ return Shapes.Sum(new Func<ShapeBase, int>(SumH)); } }
SS>        private int SumW(ShapeBase sb) {return sb.Width;}
SS>        private int SumH(ShapeBase sb) {return sb.Height;}
SS>        //дочерние фигуры
SS>        public virtual List<T> Shapes { get; set; } 
SS>        public ShapeCompositeBase()
SS>        {
SS>            Shapes = new List<T>();
SS>        }
SS>    }
SS>


я немного подзабыл C# T:ShapeBase означает констрейнт на тип T
вобщем нужены генерики
... << RSDN@Home 1.2.0 alpha 4 rev. 1227>>
Re: Паттерн Composite
От: Кирилл Лебедев Россия http://askofen.blogspot.com/
Дата: 30.09.10 14:43
Оценка:
Здравствуйте, SomewhereSomehow, Вы писали:

SS>Собственно реальные классы конкретных фигур наследуются от базовых абстраткных. Один соотвтст. конкретная простая фигура (унаследован от базового простого), другой — конкретная составная фигура (унаследован от базового составного).

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

ИМХО, разделение фигур на простые и составные, а также — базовые простые и базовые составные — лишнее. Это и порождает проблему. Сделайте так, чтобы любая фигура — даже если она простая — могла бы быть и составной. Поместите список "детей" в самый базовый класс.

Собственно, об этом я писал в статье Освобождение узников оператора if. Там разбирается похожий пример с окнами. С одной стороны, окно может иметь дочерние окна, с другой стороны — не у всех окон они есть (например, у кнопок). Вывод, который сделан в статье: "Если кажется, что это не так (например, Вас удивляет, зачем "кнопке" иметь дочерние окна), скажите себе: "Лучше иметь 1 избыточную переменную и компактную программу, чем громоздкую программу без избыточных переменных". Функция избыточной переменной у кнопки — "устранять лишнюю логику". Очень полезная "кнопочная избыточность"."

В Вашем случае рекомендую поступить точно так же.
С уважением,
Кирилл Лебедев
Software Design blog — http://askofen.blogspot.ru/
Re[2]: Паттерн Composite
От: SomewhereSomehow Россия  
Дата: 30.09.10 15:04
Оценка:
Здравствуйте, Ikemefula, Вы писали:
I>я бы делал примерно так — сам композит не стоит перегружать лишними методами, пропертями.
I>
I>public static class Helper
I>{
I>    public static IList<TShape> Shapes(this ShapeBase shapeBase)
I>        where TShape : ShapeBase
I>    {
I>        return Shapes.CastTo<TShape>().ToList();
I>    }
I>}
I>

Спасибо.
Вас не затруднит чуть подробнее описать суть того, что вы предлагаете?
А то приведенный фрагмент кода как-то не очень понятен (как мне так и компилятору).

И что значит "не перегружать лишними методами и свойствами"...
Там вроде вообще нет методов, только два свойства, которые для составных фигур реализуют несколько иную логику вычисления длины и ширины по сравнению с простыми фигурами.
Как иначе определить такое поведение если не тут?
Re[2]: Паттерн Composite
От: SomewhereSomehow Россия  
Дата: 30.09.10 15:10
Оценка:
Здравствуйте, cvetkov, Вы писали:

C>Здравствуйте, SomewhereSomehow, Вы писали:


SS>>
SS>>    public abstract class ShapeCompositeBase<T:ShapeBase>: ShapeBase
SS>>    {
SS>>        // размер композитной фигуры, сумма соотв.размеров дочерних
SS>>        public override int Width { get { return Shapes.Sum(new Func<ShapeBase, int>(SumW)); }  }
SS>>        public override int Height { get{ return Shapes.Sum(new Func<ShapeBase, int>(SumH)); } }
SS>>        private int SumW(ShapeBase sb) {return sb.Width;}
SS>>        private int SumH(ShapeBase sb) {return sb.Height;}
SS>>        //дочерние фигуры
SS>>        public virtual List<T> Shapes { get; set; } 
SS>>        public ShapeCompositeBase()
SS>>        {
SS>>            Shapes = new List<T>();
SS>>        }
SS>>    }
SS>>


C>я немного подзабыл C# T:ShapeBase означает констрейнт на тип T

C>вобщем нужены генерики

А смысл который вы хотели донести? Т.е. сделать абстрактный класс составной фигуры генерик типом, чтобы...что?
КАк это будет выглядеть?
Re[2]: Паттерн Composite
От: SomewhereSomehow Россия  
Дата: 30.09.10 15:22
Оценка:
Здравствуйте, Кирилл Лебедев, Вы писали:

КЛ>Здравствуйте, SomewhereSomehow, Вы писали:


SS>>Собственно реальные классы конкретных фигур наследуются от базовых абстраткных. Один соотвтст. конкретная простая фигура (унаследован от базового простого), другой — конкретная составная фигура (унаследован от базового составного).

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

КЛ>ИМХО, разделение фигур на простые и составные, а также — базовые простые и базовые составные — лишнее. Это и порождает проблему. Сделайте так, чтобы любая фигура — даже если она простая — могла бы быть и составной. Поместите список "детей" в самый базовый класс.


КЛ>Собственно, об этом я писал в статье Освобождение узников оператора if. Там разбирается похожий пример с окнами. С одной стороны, окно может иметь дочерние окна, с другой стороны — не у всех окон они есть (например, у кнопок). Вывод, который сделан в статье: "Если кажется, что это не так (например, Вас удивляет, зачем "кнопке" иметь дочерние окна), скажите себе: "Лучше иметь 1 избыточную переменную и компактную программу, чем громоздкую программу без избыточных переменных". Функция избыточной переменной у кнопки — "устранять лишнюю логику". Очень полезная "кнопочная избыточность"."


КЛ>В Вашем случае рекомендую поступить точно так же.


Не поверите, так сначала и было.
Я сделал один класс, Назовем его БазоваяФигура в который поместил свойства: Высота,Ширина,Дочерние объекты.
От него унаследовал два класса: Фигура1, Фигура2 (назовем пок атак, чтобы не путаться с составными и простыми т.к. теперь все составные).
Далее мне необходимо в классе Фигура2 держать список объектов Фигура1. Вместо этого у меня есть массив объектов БазоваяФигура.
Проблема все равно остается.
Либо я не до конца понимаю вашу мысль.
Re[3]: Паттерн Composite
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 30.09.10 15:35
Оценка:
Здравствуйте, SomewhereSomehow, Вы писали:

SS>Здравствуйте, Ikemefula, Вы писали:

I>>я бы делал примерно так — сам композит не стоит перегружать лишними методами, пропертями.
I>>
I>>public static class Helper
I>>{
I>>    public static IList<TShape> Shapes(this ShapeBase shapeBase)
I>>        where TShape : ShapeBase
I>>    {
I>>        return Shapes.CastTo<TShape>().ToList();
I>>    }
I>>}
I>>

SS>Спасибо.
SS>Вас не затруднит чуть подробнее описать суть того, что вы предлагаете?

Я предлагаю сделать экстеншт метод, который будет приводить чилдов к нужному типу.

SS>И что значит "не перегружать лишними методами и свойствами"...

SS>Там вроде вообще нет методов, только два свойства, которые для составных фигур реализуют несколько иную логику вычисления длины и ширины по сравнению с простыми фигурами.

А список чилдов ?
Re: Паттерн Composite
От: SomewhereSomehow Россия  
Дата: 30.09.10 15:38
Оценка:
Еще поясню свою мысль, зачем это надо.
По моему мнению, совсем хорошо бы это выглядело если бы:

Были классы
SimpleShape, CompositeShape, AnyOtherShape.

Интерфейс:
ISizeCalculatable.

Все классы имплементят этот интерфейс в соответствии со своей логикой.
Ну и соответвенно в метод обработки передается ShowSizes(ISizeCalculatable sb)

Этот метод хорош еще тем, что по сути, кроме базовго набора свойств и того, что формы могут включать в себя другие формы — их ничего не объединяет, что согласуется со смыслом интерфейсов.
Ои могут иметь абсолютно разные наборы свойств, кроме тах базовых что я вынес в абстрактный класс.
Но совершенно четко известно, что набор базовых свойств будет расширяться, и в случае с интерфейсом, добавление одного свойства в интерфейс — повлечет за собой необходимость дописывать реализацию это свойствя во все классы реализующие этот интерфейс.
Так что хотелось бы все-таки понять, как обойтись абстрактными классами (или генериками, только хз как).
Re[4]: Паттерн Composite
От: SomewhereSomehow Россия  
Дата: 30.09.10 15:44
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>Здравствуйте, SomewhereSomehow, Вы писали:


SS>>Здравствуйте, Ikemefula, Вы писали:

I>>>я бы делал примерно так — сам композит не стоит перегружать лишними методами, пропертями.
I>>>
I>>>public static class Helper
I>>>{
I>>>    public static IList<TShape> Shapes(this ShapeBase shapeBase)
I>>>        where TShape : ShapeBase
I>>>    {
I>>>        return Shapes.CastTo<TShape>().ToList();
I>>>    }
I>>>}
I>>>

SS>>Спасибо.
SS>>Вас не затруднит чуть подробнее описать суть того, что вы предлагаете?

I>Я предлагаю сделать экстеншт метод, который будет приводить чилдов к нужному типу.


Ну я так понял необходимо будет явно вызывать этот метод? Если так, то я как раз от этого хотел уйти.

SS>>И что значит "не перегружать лишними методами и свойствами"...

SS>>Там вроде вообще нет методов, только два свойства, которые для составных фигур реализуют несколько иную логику вычисления длины и ширины по сравнению с простыми фигурами.

I>А список чилдов ?


А куда в таком случае помещать список чайлдов как не в композит?
Re[3]: Паттерн Composite
От: Кирилл Лебедев Россия http://askofen.blogspot.com/
Дата: 30.09.10 15:56
Оценка:
Здравствуйте, SomewhereSomehow, Вы писали:

SS>Не поверите, так сначала и было.

SS>Я сделал один класс, Назовем его БазоваяФигура в который поместил свойства: Высота,Ширина,Дочерние объекты.
Зачем в базовом классе Вам понадобились высота и ширина? (Я предлагал только добавить туда список дочерних объектов.)

SS>От него унаследовал два класса: Фигура1, Фигура2 (назовем пок атак, чтобы не путаться с составными и простыми т.к. теперь все составные).

Чем Фигура1 отличалась от Фигура2? И чем они обе отличались от БазоваяФигура?

SS>Далее мне необходимо в классе Фигура2 держать список объектов Фигура1. Вместо этого у меня есть массив объектов БазоваяФигура.

Почему Фигура2 должна знать о том, какие дочерние фигуры в ней содержатся? Почему Фигуре2 принципиально, чтобы в ней находились Фигуры1?
С уважением,
Кирилл Лебедев
Software Design blog — http://askofen.blogspot.ru/
Re[4]: Паттерн Composite
От: SomewhereSomehow Россия  
Дата: 30.09.10 16:15
Оценка:
Здравствуйте, Кирилл Лебедев, Вы писали:

КЛ>Здравствуйте, SomewhereSomehow, Вы писали:


SS>>Не поверите, так сначала и было.

SS>>Я сделал один класс, Назовем его БазоваяФигура в который поместил свойства: Высота,Ширина,Дочерние объекты.
КЛ>Зачем в базовом классе Вам понадобились высота и ширина? (Я предлагал только добавить туда список дочерних объектов.)

Если высота и ширина являются общими для всех фигур, то почему следует делать в каждом производном классе те же самые свойства что можно определить в базовом?

SS>>От него унаследовал два класса: Фигура1, Фигура2 (назовем пок атак, чтобы не путаться с составными и простыми т.к. теперь все составные).

КЛ>Чем Фигура1 отличалась от Фигура2? И чем они обе отличались от БазоваяФигура?

Отличия я тут не приводил, ибо сути вопроса не меняют, но они достаточные, для того чтобы разносить их в разные классы.
Суть не в том чем одна фигура отличается от другой, это пример, я его выбрал т.к. он помогает более ясно представить паттерн композит (по крайней мере для меня).
Если смущает слово фигра, можете обозначить КлассА, КлассБ.
Примем необходимость разных классов, как условие задачи.

SS>>Далее мне необходимо в классе Фигура2 держать список объектов Фигура1. Вместо этого у меня есть массив объектов БазоваяФигура.

КЛ>Почему Фигура2 должна знать о том, какие дочерние фигуры в ней содержатся? Почему Фигуре2 принципиально, чтобы в ней находились Фигуры1?
Потому что фигура2 должна использовать свойства и методы фигуры1, при этом нельзя выносить эти методы в базовый класс, т.к. далеко не все (а точнее вообще никто) из наследников базового класса не будет иметь методов и свойств специфичных для фигуры1.
Re[5]: Паттерн Composite
От: minorlogic Украина  
Дата: 01.10.10 00:23
Оценка: +1
Здравствуйте, SomewhereSomehow, Вы писали:

SS>Суть не в том чем одна фигура отличается от другой, это пример, я его выбрал т.к. он помогает более ясно представить паттерн композит (по крайней мере для меня).

SS>Если смущает слово фигра, можете обозначить КлассА, КлассБ.

Хочу уточнить , композит представляет такой же интерфейс как и базовый класс. Т.е. для пользователя композита он не должен никак отличаться от базового , в этом то и его суть.
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[2]: Паттерн Composite
От: BluntBlind  
Дата: 01.10.10 03:26
Оценка: +1 -1
Здравствуйте, SomewhereSomehow, Вы писали:

SS>Все классы имплементят этот интерфейс в соответствии со своей логикой.

SS>Ну и соответвенно в метод обработки передается ShowSizes(ISizeCalculatable sb)

SS>Этот метод хорош еще тем, что по сути, кроме базовго набора свойств и того, что формы могут включать в себя другие формы — их ничего не объединяет, что согласуется со смыслом интерфейсов.

SS>Ои могут иметь абсолютно разные наборы свойств, кроме тах базовых что я вынес в абстрактный класс.
SS>Но совершенно четко известно, что набор базовых свойств будет расширяться, и в случае с интерфейсом, добавление одного свойства в интерфейс — повлечет за собой необходимость дописывать реализацию это свойствя во все классы реализующие этот интерфейс.
SS>Так что хотелось бы все-таки понять, как обойтись абстрактными классами (или генериками, только хз как).

Visitor
Автор(ы): Андрей Корявченко
Дата: 06.12.2006
Очень часто в программах встречаются сложные структуры, представляющие собой дерево или граф, состоящий из разнотипных узлов. И, конечно же, при этом имеется необходимость обрабатывать этот граф. Самое очевидное решение — добавить в базовый класс виртуальный метод, который перекрыть в наследниках для выполнения нужного действия и осуществления дальнейшей навигации по дереву.
Однако у этого приема есть серьезный недостаток: в нем структура данных оказывается увязанной с обрабатывающими ее алгоритмами. Если нам понадобится алгоритм, отличный от реализованного, то придется добавлять еще один виртуальный метод. Еще хуже, если классы, составляющие дерево, содержатся в недоступном для модификации коде.
Одним из вариантов решения проблемы высокой связности в данном случае является паттерн Посетитель.
Re[5]: Паттерн Composite
От: Кирилл Лебедев Россия http://askofen.blogspot.com/
Дата: 01.10.10 07:46
Оценка: +1
Здравствуйте, SomewhereSomehow, Вы писали:

SS>Если высота и ширина являются общими для всех фигур, то почему следует делать в каждом производном классе те же самые свойства что можно определить в базовом?

Ок.

SS>Отличия я тут не приводил, ибо сути вопроса не меняют, но они достаточные, для того чтобы разносить их в разные классы.

SS>Суть не в том чем одна фигура отличается от другой, это пример, я его выбрал т.к. он помогает более ясно представить паттерн композит (по крайней мере для меня).
Как верно заметил minorlogic паттерн Компоновщик как раз-таки предполагает, что у всех классов одинаковый интерфейс. В список дочерних элементов можно добавить объект любого класса иерархии, и от этого ничего не поменяется. Если же данное условие не выполняется, то надо смотреть на конкретную задачу, т.к. либо решение (использовать Компоновщик) неправильное, либо его не так нужно применять к конкретной задаче.

КЛ>>Почему Фигура2 должна знать о том, какие дочерние фигуры в ней содержатся? Почему Фигуре2 принципиально, чтобы в ней находились Фигуры1?

SS>Потому что фигура2 должна использовать свойства и методы фигуры1, при этом нельзя выносить эти методы в базовый класс, т.к. далеко не все (а точнее вообще никто) из наследников базового класса не будет иметь методов и свойств специфичных для фигуры1.
Всё это очень странно. Если Вы не можете распространить методы фигуры1 на всю иерархию, то это означает, что фигура1 не вписывается в паттерн Компоновщик. И тут возможны два варианта:

(1) либо всё-таки "вписать" фигуру1 в иерархию, распространив её специфичные методы на все классы иерархии;
(2) либо вынести различия в отдельные структуры данных, никак не связанные с иерархией классов компоновщика.

В любом случае, надо смотреть на конкретную задачу.
С уважением,
Кирилл Лебедев
Software Design blog — http://askofen.blogspot.ru/
Re[3]: Паттерн Composite
От: cvetkov  
Дата: 01.10.10 07:52
Оценка:
Здравствуйте, SomewhereSomehow, Вы писали:


SS>А смысл который вы хотели донести? Т.е. сделать абстрактный класс составной фигуры генерик типом, чтобы...что?

чтобы он был контейнером для типов фигур которые нужны.

потом к тебя будет класс

class МногоКвадратиков : ShapeCompositeBase<Квадратик> {

void обработатьКвадратики(){
Квадратик квадратик = Shapesх[1];
квадратик.обработать();
}

}

SS>КАк это будет выглядеть?

ну както так. просто я думал дальше и так понятно будет
... << RSDN@Home 1.2.0 alpha 4 rev. 1227>>
Re[5]: Паттерн Composite
От: SomewhereSomehow Россия  
Дата: 01.10.10 10:30
Оценка: :)
Спасибо за советы!
Да, видимо компоновщик в чистом виде не подходит...
Сейчас читаю и вникаю в Visitor, по наводке BluntBlind, возможно это то что нужно, но пока до конца не разобрался.
Re[4]: Паттерн Composite
От: SomewhereSomehow Россия  
Дата: 01.10.10 10:33
Оценка:
Здравствуйте, cvetkov, Вы писали:

C>Здравствуйте, SomewhereSomehow, Вы писали:



SS>>А смысл который вы хотели донести? Т.е. сделать абстрактный класс составной фигуры генерик типом, чтобы...что?

C>чтобы он был контейнером для типов фигур которые нужны.

C>потом к тебя будет класс


C>class МногоКвадратиков : ShapeCompositeBase<Квадратик> {


C>void обработатьКвадратики(){

C> Квадратик квадратик = Shapesх[1];
C> квадратик.обработать();
C>}

C>}


SS>>КАк это будет выглядеть?

C>ну както так. просто я думал дальше и так понятно будет

Спасибо за разъяснения.
В генериках я слабоват, попробую поразбираться в них в разрезе вашей идеи..
Re[3]: Паттерн Composite
От: minorlogic Украина  
Дата: 01.10.10 11:22
Оценка:
Здравствуйте, BluntBlind, Вы писали:

BB>Visitor
Автор(ы): Андрей Корявченко
Дата: 06.12.2006
Очень часто в программах встречаются сложные структуры, представляющие собой дерево или граф, состоящий из разнотипных узлов. И, конечно же, при этом имеется необходимость обрабатывать этот граф. Самое очевидное решение — добавить в базовый класс виртуальный метод, который перекрыть в наследниках для выполнения нужного действия и осуществления дальнейшей навигации по дереву.
Однако у этого приема есть серьезный недостаток: в нем структура данных оказывается увязанной с обрабатывающими ее алгоритмами. Если нам понадобится алгоритм, отличный от реализованного, то придется добавлять еще один виртуальный метод. Еще хуже, если классы, составляющие дерево, содержатся в недоступном для модификации коде.
Одним из вариантов решения проблемы высокой связности в данном случае является паттерн Посетитель.


Хочу напомнить что этот шаблон предполагает полную заморозку структуры классов. Т.е. расширять иерархию. будет очень сложно.
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Ищу работу, 3D, SLAM, computer graphics/vision.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.