C#对象体操第一Class集合规则示例?
Example of the Object Calisthenics First Class Collection rule in C#?
我正在玩对象健美操规则,我在使用 C# 时遇到了一些麻烦,不知道何时使用第一个 class 集合。
我的意思是我几乎看不到什么时候应该使用它,例如很难将该规则应用于 EF DbContext
。
比方说,我们设计了一个 Board class。
public class Board
{
public IList<BoardRow> Rows { get; }
public IList<BoardColumn> Columns { get; }
public Board()
{
Rows = new List<BoardRow>();
Columns = new List<BoardColumn>();
}
}
所以根据那个规则,我们必须把上面的代码变成:
// Is it really that better than just using List<BoardRow>?
public class BoardRowCollection : IEnumerable<BoardRow>
{
public void Add(BoardRow row) { /*...*/ }
public void Remove(BoardRow row) { /*...*/ }
// IEnumerable<BoardRow> Impl goes here...
}
// Is it really that better than just using List<BoardColumn>?
public class BoardColumnCollection : IEnumerable<BoardColumn>
{
public void Add(BoardColumn column) { /*...*/ }
public void Remove(BoardColumn column) { /*...*/ }
// IEnumerable<BoardRow> Impl goes here...
}
public class Board
{
public BoardRowCollection Rows { get; }
public BoardColumnCollection Column { get; }
// Rest of the impl, ctor, etc.
}
当您已经有了可以用来实现目标的基础 classes 时,我不确定是否理解这条规则的要点。
也许上面的代码不是最好的,但我想看一个例子,它可以阐明该规则的目的。
背景
假设你有一个 class Foo
并且出于任何原因它需要 Rows
来自 Board
.
现在 Foo
需要在 Rows
中找到第 5 个项目。几天后你需要一个 class Buu
它应该在 Rows
.
中找到第 8 个项目
Foo
和 Buu
都有自己的关于如何在 Rows
中查找项目的实现。
// ...
Foo foo = new Foo(board.getRows());
Buu buu = new Buu(foo.getRows());
BoardRow row5 = foo.find5thRow();
BoardRow row8 = buu.find8thRow();
只有集合本身应该知道如何对其进行操作
Application of this rule is simple: any class that contains a collection should contain no other
member variables. Each collection gets wrapped in its own class, so now behaviors related to
the collection have a home. You may find that filters become a part of this new class. Also,
your new class can handle activities like joining two groups together or applying a rule to each
element of the group.
如果我们要为 Rows 创建第一个 Class 集合,我们可以将它的一个实例传递给 Foo
和 Boo
并在其上调用一个方法:
class Foo {
RowCollection rowCollection;
// constructor and more ...
public BoardRow find5thRow() {
rowCollection.findByIndex(5);
}
}
总结
第一个 Class 集合应涵盖创建、读取、更新、删除、过滤、合并等操作。传递 First Class Collection 的实例而不是它自己的集合。优点是您只需将方法委托给您的第一个 Class 集合,而不是编写一个新的操作副本。
我正在玩对象健美操规则,我在使用 C# 时遇到了一些麻烦,不知道何时使用第一个 class 集合。
我的意思是我几乎看不到什么时候应该使用它,例如很难将该规则应用于 EF DbContext
。
比方说,我们设计了一个 Board class。
public class Board
{
public IList<BoardRow> Rows { get; }
public IList<BoardColumn> Columns { get; }
public Board()
{
Rows = new List<BoardRow>();
Columns = new List<BoardColumn>();
}
}
所以根据那个规则,我们必须把上面的代码变成:
// Is it really that better than just using List<BoardRow>?
public class BoardRowCollection : IEnumerable<BoardRow>
{
public void Add(BoardRow row) { /*...*/ }
public void Remove(BoardRow row) { /*...*/ }
// IEnumerable<BoardRow> Impl goes here...
}
// Is it really that better than just using List<BoardColumn>?
public class BoardColumnCollection : IEnumerable<BoardColumn>
{
public void Add(BoardColumn column) { /*...*/ }
public void Remove(BoardColumn column) { /*...*/ }
// IEnumerable<BoardRow> Impl goes here...
}
public class Board
{
public BoardRowCollection Rows { get; }
public BoardColumnCollection Column { get; }
// Rest of the impl, ctor, etc.
}
当您已经有了可以用来实现目标的基础 classes 时,我不确定是否理解这条规则的要点。
也许上面的代码不是最好的,但我想看一个例子,它可以阐明该规则的目的。
背景
假设你有一个 class Foo
并且出于任何原因它需要 Rows
来自 Board
.
现在 Foo
需要在 Rows
中找到第 5 个项目。几天后你需要一个 class Buu
它应该在 Rows
.
Foo
和 Buu
都有自己的关于如何在 Rows
中查找项目的实现。
// ...
Foo foo = new Foo(board.getRows());
Buu buu = new Buu(foo.getRows());
BoardRow row5 = foo.find5thRow();
BoardRow row8 = buu.find8thRow();
只有集合本身应该知道如何对其进行操作
Application of this rule is simple: any class that contains a collection should contain no other member variables. Each collection gets wrapped in its own class, so now behaviors related to the collection have a home. You may find that filters become a part of this new class. Also, your new class can handle activities like joining two groups together or applying a rule to each element of the group.
如果我们要为 Rows 创建第一个 Class 集合,我们可以将它的一个实例传递给 Foo
和 Boo
并在其上调用一个方法:
class Foo {
RowCollection rowCollection;
// constructor and more ...
public BoardRow find5thRow() {
rowCollection.findByIndex(5);
}
}
总结
第一个 Class 集合应涵盖创建、读取、更新、删除、过滤、合并等操作。传递 First Class Collection 的实例而不是它自己的集合。优点是您只需将方法委托给您的第一个 Class 集合,而不是编写一个新的操作副本。