Добрый день. Есть базовые классы Container и Component. Container содержит подкласс, например MyContainer который в качестве компонентов может содержать только класс MyComponent (и всех производных). При этом MyContainer2 компонентов может содержать только класс MyComponent2 и производные. Как такое делать?
Здравствуйте, Аноним, Вы писали:
А>Добрый день. Есть базовые классы Container и Component. Container содержит подкласс, например MyContainer который в качестве компонентов может содержать только класс MyComponent (и всех производных). При этом MyContainer2 компонентов может содержать только класс MyComponent2 и производные. Как такое делать?
За ссылку спасибо. почитаю
КЛ>2. Вы также можете использовать template'ы в C++ (или generic'и в C#):
Женерики нельзя использовать, т.к. используется ORM-инструмент, а он не хочер работать с женериками
Здравствуйте, Аноним, Вы писали:
КЛ>>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?
А>Да.
КЛ>>1. Обратите внимание на паттерн Компоновщик
А>За ссылку спасибо. почитаю
КЛ>>2. Вы также можете использовать template'ы в C++ (или generic'и в C#): А>Женерики нельзя использовать, т.к. используется ORM-инструмент, а он не хочер работать с женериками
Кодогенерация? В ряде случаев — очень оно. Эдакие темплейты на стадии пре-билда. (само собой, сгенеренные файлы кладутся в отдельную апку, которая исключается из репозитория, дабы уменьшить индусовость шаловливых ручек — ибо шапку запрещающих каментов редко кто читает)
Здравствуйте, Аноним, Вы писали:
А>Добрый день. Есть базовые классы 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);
}
}
}