我想实现一个流畅的界面,让我指定一个表,其中表和列具有属性的列。我想能够像这样初始化表类:这个流畅的接口可以简化吗?
var t = TableBuilder.Create()
.WithName("test")
.WithColumn("col1").WithType("Int32")
.WithColumn("col2").WithType("String")
.WithColumn("col3");
我想出了一个解决方案,工作。我的问题是,实施可以简化,还是应该采取完全不同的方法?我在类似案例中看到了扩展方法的用法,但我不知道他们是否会帮助我或者在这种情况下如何使用它们。
下面是代码(下面的一些评论):
interface ITable
{
ITable WithName(string tableName);
ITableAndColum<ITable, IColumn> WithColumn(string columnName);
}
interface IColumn
{
IColumn WithType(string typeName);
}
interface ITableAndColum<TTable, TColumn>
where TTable : ITable
where TColumn : IColumn
{
ITableAndColum<ITable, IColumn> WithColumn(string columnName);
ITableAndColum<ITable, IColumn> WithType(string typeName);
}
class TableAndColumn : ITableAndColum<ITable, IColumn>
{
public ITable Table { get; set; }
public IColumn Column { get; set; }
public ITableAndColum<ITable, IColumn> WithColumn(string columnName)
{
return Table.WithColumn(columnName);
}
public ITableAndColum<ITable, IColumn> WithType(string typeName)
{
Column.WithType(typeName);
return this;
}
public override string ToString()
{
return Table.ToString();
}
}
class Column : IColumn
{
public string ColumnName { get; set; }
public string TypeName { get; set; }
public IColumn WithType(string typeName)
{
TypeName = typeName;
return this;
}
}
class TableBuilder : ITable
{
public string TableName { get; set; }
List<Column> Columns;
TableBuilder() { Columns = new List<Column>(); }
public static ITable Create() { return new TableBuilder(); }
public ITable WithName(string tableName)
{
TableName = tableName;
return this;
}
public ITableAndColum<ITable, IColumn> WithColumn(string columnName)
{
Column thisColumn = new Column() { ColumnName = columnName };
Columns.Add(thisColumn);
return new TableAndColumn() { Table = this, Column = thisColumn };
}
public override string ToString()
{
return TableName + "(" + string.Join(",", Columns.Select(c => (c.TypeName != null ? c.TypeName + " " : "") + c.ColumnName)) + ")";
}
}
class Example
{
public Example()
{
var t = TableBuilder.Create()
.WithName("test")
.WithColumn("col1").WithType("Int32")
.WithColumn("col2").WithType("String")
.WithColumn("col3");
var tdef = t.ToString();
}
}
有两个接口是ITable
和IColumn
与那里实现Table
和Colum
。他们公开适合他们类型的适当方法。第三个接口ITableAndColumn
结合了其他接口,它的实现TableAndColumn
持有对表实例和列实例的引用。该界面公开了ITable
和IColumn
的选定方法并调用相应的实例。
这种方法是否复杂?扩展方法是以这种方式吗?
出于好奇,你为什么要反对使用设计您的API使用传统的风格? – Dai
这个问题的答案会非常有偏见,但我的评论也是如此 - 作为个人喜好,我希望将'WithType'方法称为'AndType',以便获得'WithColumn(“col1”)。AndType “Int32”)'我宁愿使用实际的'Type's而不是字符串来定义类型。 –
我想让我的API更具可读性。当然,只有在代码的正确缩进和换行符以及连锁不会太长时间的情况下才能正常工作,但我可以忍受这两种退步。我知道我可以使用更简单的方法链接构造函数初始值设定项和名称参数。但我仍然想知道一些API如何在我的示例代码中进行说明。 – Sascha