Подскажите паттерн для Целое-Часть
От: Аноним  
Дата: 20.10.10 07:22
Оценка:
Добрый день. Есть базовые классы Container и Component. Container содержит подкласс, например MyContainer который в качестве компонентов может содержать только класс MyComponent (и всех производных). При этом MyContainer2 компонентов может содержать только класс MyComponent2 и производные. Как такое делать?
Re: Подскажите паттерн для Целое-Часть
От: Кирилл Лебедев Россия http://askofen.blogspot.com/
Дата: 20.10.10 07:30
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Добрый день. Есть базовые классы Container и Component. Container содержит подкласс, например MyContainer который в качестве компонентов может содержать только класс MyComponent (и всех производных). При этом MyContainer2 компонентов может содержать только класс MyComponent2 и производные. Как такое делать?


1. Обратите внимание на паттерн Компоновщик

2. Вы также можете использовать template'ы в C++ (или generic'и в C#):

typedef std::vector<MyComponent *> MyContainer;
typedef std::vector<MyComponent2 *> MyContainer2;


3. Вполне возможно, что не подойдёт ни то, ни другое. Но тогда подробнее опишите, в чём собственно состоит задача.
С уважением,
Кирилл Лебедев
Software Design blog — http://askofen.blogspot.ru/
Re[2]: Подскажите паттерн для Целое-Часть
От: Аноним  
Дата: 20.10.10 07:32
Оценка:
КЛ>1. Обратите внимание на паттерн Компоновщик

За ссылку спасибо. почитаю

КЛ>2. Вы также можете использовать template'ы в C++ (или generic'и в C#):

Женерики нельзя использовать, т.к. используется ORM-инструмент, а он не хочер работать с женериками
Re[3]: Подскажите паттерн для Целое-Часть
От: GarryIV  
Дата: 20.10.10 07:38
Оценка:
Здравствуйте, Аноним, Вы писали:

КЛ>>1. Обратите внимание на паттерн Компоновщик


А>За ссылку спасибо. почитаю


КЛ>>2. Вы также можете использовать template'ы в C++ (или generic'и в C#):

А>Женерики нельзя использовать, т.к. используется ORM-инструмент, а он не хочер работать с женериками

На каком языке\платформе надо решение то? А то сейчас на Nemerle решение приведут
WBR, Igor Evgrafov
Re[4]: Подскажите паттерн для Целое-Часть
От: Аноним  
Дата: 20.10.10 07:45
Оценка:
GIV>На каком языке\платформе надо решение то? А то сейчас на Nemerle решение приведут

На C# надо. ПОчитал я ссылку. Что-то не то. В нём предполагается иметь 1 контейнер содержащий классы определённой иерархии. А у меня как бы 2 иерархии. Первая — контейнеры, 2 — компоненты. Но при этом определённые контейнеры могут содержать лишь определённые классы компонентов
Re[5]: Подскажите паттерн для Целое-Часть
От: Аноним  
Дата: 20.10.10 08:04
Оценка:
Здравствуйте, Аноним, Вы писали:

GIV>>На каком языке\платформе надо решение то? А то сейчас на Nemerle решение приведут


А>На C# надо. ПОчитал я ссылку. Что-то не то. В нём предполагается иметь 1 контейнер содержащий классы определённой иерархии. А у меня как бы 2 иерархии. Первая — контейнеры, 2 — компоненты. Но при этом определённые контейнеры могут содержать лишь определённые классы компонентов


Пусть Container и Component будут интерфейсами, MyContainer2 будет классом реализующим интерфейс Container, MyComponent2 класс реализующий Component.
MyContainer2 будет содержать список из MyComponent2.

Какой базовый интерфейс то нужен, для Container и Component?
Re[6]: Подскажите паттерн для Целое-Часть
От: Аноним  
Дата: 20.10.10 08:22
Оценка:
А>>На C# надо. ПОчитал я ссылку. Что-то не то. В нём предполагается иметь 1 контейнер содержащий классы определённой иерархии. А у меня как бы 2 иерархии. Первая — контейнеры, 2 — компоненты. Но при этом определённые контейнеры могут содержать лишь определённые классы компонентов

А>Пусть Container и Component будут интерфейсами, MyContainer2 будет классом реализующим интерфейс Container, MyComponent2 класс реализующий Component.

А>MyContainer2 будет содержать список из MyComponent2.

Правильно ли я понимаю, что в каждом классе Container будет свойство типа Components?
Re[7]: Подскажите паттерн для Целое-Часть
От: Аноним  
Дата: 20.10.10 08:27
Оценка:
Здравствуйте, Аноним, Вы писали:

А>>>На C# надо. ПОчитал я ссылку. Что-то не то. В нём предполагается иметь 1 контейнер содержащий классы определённой иерархии. А у меня как бы 2 иерархии. Первая — контейнеры, 2 — компоненты. Но при этом определённые контейнеры могут содержать лишь определённые классы компонентов


А>>Пусть Container и Component будут интерфейсами, MyContainer2 будет классом реализующим интерфейс Container, MyComponent2 класс реализующий Component.

А>>MyContainer2 будет содержать список из MyComponent2.

А>Правильно ли я понимаю, что в каждом классе Container будет свойство типа Components?


Да.
Re[8]: Подскажите паттерн для Целое-Часть
От: Аноним  
Дата: 20.10.10 08:47
Оценка:
А>>>Пусть Container и Component будут интерфейсами, MyContainer2 будет классом реализующим интерфейс Container, MyComponent2 класс реализующий Component.
А>>>MyContainer2 будет содержать список из MyComponent2.

А>>Правильно ли я понимаю, что в каждом классе Container будет свойство типа Components?


А>Да.


А с Дженериками было бы красивее
Re[3]: Подскажите паттерн для Целое-Часть
От: Mr.Delphist  
Дата: 20.10.10 10:53
Оценка:
Здравствуйте, Аноним, Вы писали:


КЛ>>1. Обратите внимание на паттерн Компоновщик


А>За ссылку спасибо. почитаю


КЛ>>2. Вы также можете использовать template'ы в C++ (или generic'и в C#):

А>Женерики нельзя использовать, т.к. используется ORM-инструмент, а он не хочер работать с женериками

Кодогенерация? В ряде случаев — очень оно. Эдакие темплейты на стадии пре-билда. (само собой, сгенеренные файлы кладутся в отдельную апку, которая исключается из репозитория, дабы уменьшить индусовость шаловливых ручек — ибо шапку запрещающих каментов редко кто читает)
Re: Подскажите паттерн для Целое-Часть
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 22.10.10 19:34
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Добрый день. Есть базовые классы Container и Component. Container содержит подкласс, например MyContainer который в качестве компонентов может содержать только класс MyComponent (и всех производных). При этом MyContainer2 компонентов может содержать только класс MyComponent2 и производные. Как такое делать?


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

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;

namespace Core
{
    public abstract class CollectionBase<TItemType> : IEnumerable<TItemType>
    {
        private readonly List<TItemType> _list = new List<TItemType>();
        private readonly Action _changed;

        protected CollectionBase(Action changed)
        {
            _changed = changed;
        }

        protected void RaiseChanged()
        {
            if(_changed == null)
                return;

            _changed();
        }

        #region IList Members

        public int Count
        {
            get { return _list.Count; }
        }

        public abstract bool IsReadOnly { get; }

        public IEnumerator<TItemType> GetEnumerator()
        {
            return _list.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        public bool Contains(TItemType item)
        {
            return _list.Contains(item);
        }

        public void CopyTo(TItemType[] array, int arrayIndex)
        {
            _list.CopyTo(array, arrayIndex);
        }

        public int IndexOf(TItemType item)
        {
            return _list.IndexOf(item);
        }

        public abstract void Clear();

        public virtual TItemType this[int index]
        {
            get { return _list[index]; }
            set { throw new NotSupportedException(); }
        }

        public virtual void Add(TItemType item)
        {
            Debug.Assert(item != null);

            if (item == null)
                throw new NotSupportedException();

            CheckAdding(item);
            _list.Add(item);
            OnAdded(item);
        }

        public virtual bool Remove(TItemType item)
        {
            CheckRemoving(item);
            bool bRet = _list.Remove(item);

            if (bRet)
                OnRemoved(item);

            return bRet;
        }

        public virtual void Insert(int index, TItemType item)
        {
            Debug.Assert(item != null);

            if (item == null)
                throw new NotSupportedException();

            CheckAdding(item);
            _list.Insert(index, item);
            OnAdded(item);
        }

        public virtual void RemoveAt(int index)
        {
            TItemType item = this[index];
            CheckRemoving(item);
            _list.RemoveAt(index);
            OnRemoved(item);
        }

        public virtual TItemType[] ToArray()
        {
            TItemType[] array = new TItemType[Count];

            CopyTo(array, 0);

            return array;
        }

        #endregion

        protected abstract void OnAdded(TItemType item);
        protected abstract void OnRemoved(TItemType item);
        protected abstract void CheckAdding(TItemType item);
        protected abstract void CheckRemoving(TItemType item);
    }
}

using System;

namespace Core
{
    public class ItemCollection<TItem> : CollectionBase<TItem>
    {
        private readonly Action<TItem> _adding;
        private readonly Action<TItem> _added;
        private readonly Action<TItem> _removing;
        private readonly Action<TItem> _removed;

        public ItemCollection(Action<TItem> adding, Action<TItem> added, Action<TItem> removing, Action<TItem> removed)
            : base(null)
        {
            _adding = adding;
            _added = added;
            _removing = removing;
            _removed = removed;
        }

        public ItemCollection(Action<TItem> added, Action<TItem> removed)
            : this(null,added, null, removed)
        {
        }

        public override bool IsReadOnly
        {
            get { return false; }
        }

        public override void Clear()
        {
            while (Count > 0)
            {
                RemoveAt(Count - 1);
            }
        }

        protected override void CheckAdding(TItem item)
        {
            if (Contains(item))
                throw new ItemAlreadyExistException();
            RaiseAdding(item);
        }

        protected override void OnAdded(TItem item)
        {
            RaiseAdded(item);
        }

        protected override void CheckRemoving(TItem item)
        {
            if (!Contains(item))
                throw new ItemNotFoundException();
            RaiseRemoving(item);
        }

        protected override void OnRemoved(TItem item)
        {
            RaiseRemoved(item);
        }

        private void RaiseAdding(TItem item)
        {
            if(_adding != null)
                _adding(item);
        }
        private void RaiseAdded(TItem item)
        {
            if(_added != null)
                _added(item);
        }
        private void RaiseRemoving(TItem item)
        {
            if(_removing != null)
                _removing(item);
        }
        private void RaiseRemoved(TItem item)
        {
            if(_removed != null)
                _removed(item);
        }
    }
}



примерно так


    public interface IContainer : INotifyPropertyChanged
    {
        ...
        ItemCollection<IObject> Components { get; }
        ...
    }
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.