我有一个班级Row
。
该类应具有Content-property。目前内容类型为:List<IRowContent>
(IRowContent
是一个界面)
其他类Column
和TextContent
,ImageContent
实现了接口IRowContent
。
我现在可以添加一些列到列表或真正的“内容”(文本或图像)。
但您也可以添加列和文本/图像。但如果一行包含文本/图像,则不应包含其他项目。
我如何设计我的类结构来支持它?
编辑:一些额外信息: 我想用“流畅的界面”http://en.wikipedia.org/wiki/Fluent_interface
构建一个布局我的想法是防止VisualStudio的智能感知错误使用。
这是我的课程: 布局有一个列表。
class Layout
{
//Attributes
public Color Background { get; set; }
public List<Column> Columns { get; set; }
public uint Margin { get; set; }
public Layout AddColumn(Column c)
{
return null;
}
public Layout SetColumnList(List<Column> c)
{
return null;
}
}
该列包含内容列表(IColumnContent)。该列本身来自IRowContent。
class Column : IRowContent
{
public List<IColumnContent> Content { get; private set; }
public Column AddToContent(IColumnContent obj)
{
return null;
}
public Column SetContent(List<IColumnContent> objs)
{
return null;
}
}
对于具有IRowContent的行,相同:
class Row : IColumnContent
{
public List<IRowContent> Content { get; private set; }
//...
}
ImageContent和TextContent实现两个接口:
class TextContent : IRowContent, IColumnContent
class ImageContent : IRowContent, IColumnContent
答案 0 :(得分:3)
如果您声明接口
interface IRowContent
{
bool SupportsOtherChildren{ get; }
...
}
class ImageContent : IRowContent
{
public bool SupportsOtherChildren
{
get { return false; }
}
}
class Column : IRowContent
{
public bool SupportsOtherChildren
{
get { return true; }
}
}
您可以覆盖集合的插入和删除方法以支持此行为:
class RowContentCollection : Collection<IRowContent>
{
bool containsSingleItem = false;
protected override void InsertItem(int index, IRowContent item)
{
if (containsSingleItem)
throw new InvalidOperationException("Collection contains an item that doesnt allow other items.");
containsSingleItem = !item.SupportsOtherChildren;
base.InsertItem(index, item);
}
protected override void RemoveItem(int index)
{
if (!this[index].SupportsOtherChildren)
containsSingleItem = false;
base.RemoveItem(index);
}
}
答案 1 :(得分:1)
总结并确保我理解正确:
Row
类应包含列列表。每列可以是Column
,TextContent
或ImageContent
类型的对象。所有这三个类都实现了RowContent
接口(在我看来应该命名为IColumnContent
...)。
如果这是正确的,那么你试图施加的限制(说实话我并不完全理解)不是类设计的问题,而是添加/删除逻辑的问题。我将Content
属性声明为
private List<RowContent> m_internalColumns;
public RowContent[] Columns { get { return m_internalColumns.ToArray(); }}
并创建Add
和Remove
方法,如下所示(伪代码):
public void Add(RowContent column)
{
if (adding column of type <typeof(column)> is allowed)
m_internalColumns.Add(column);
}
public void Remove(RowContent column)
{
m_internalColumns.Remove(column);
}
答案 2 :(得分:0)
您可以将Row
类设为通用:
class Row<T : IRowContent> {
public List<T> Content { ... }
}
然后,您可以拥有Row<Column>
,其中只能包含列,或Row<TextContent>
,其中只能包含文字内容。您甚至可以拥有允许混合内容的Row<IRowContent>
。
如果您想要一个只能包含文字和图片内容(但没有列)的行,请添加IRealContent : IRowContent
版本,并TextContent
和ImageContent
实施IRealContent
。然后,Row<IRealContent>
只能包含文字和图片。
答案 3 :(得分:0)
向接口本身提供有关问题的详细信息。
public interface IRowContent
{
bool SupportsChildren { get; }
// other properties
}
我还会向Row类引入自定义的Add和Remove方法,以确定添加的内容是否可以支持其他内容。
答案 4 :(得分:0)
我可能会做两件事之一。之一:
不是使用Row.Content.Add()
添加项目,而是向Row
添加方法以添加内容。 Row.AddContent(iRowContent content);
并将“逻辑”放在该方法中,以确定是否可以添加任何项目。
或者,不是使用List,而是实现自己的集合IList
,并以包含逻辑的方式编写Add()
方法。