【问题标题】:Example of the Object Calisthenics First Class Collection rule in C#?C# 中的 Object Calisthenics First Class Collection 规则示例?
【发布时间】:2019-05-01 07:30:30
【问题描述】:

我正在使用 Object Calisthenics 规则,但在查看使用 C# 时何时使用第一类集合时遇到了一些麻烦。

我的意思是我几乎看不到它应该在什么时候使用,例如,很难将该规则应用于 EF DbContext

假设我们设计了一个 Board 类。

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.
}

当您已经拥有可用于实现目标的基类时,我不确定是否明白这条规则的重点。

也许上面的代码不是最好的,但我希望看到一个可以阐明该规则目的的示例。

【问题讨论】:

  • 对我来说,这只是一种“指南”。有时这可能很好(但我对此持怀疑态度),有时根本不是。这取决于实际用例。总的来说,这些规则对我来说看起来很可疑。 “不要使用else 关键字”? “没有属性”?我不会相信这样的指导方针。无论如何,它在很大程度上是基于意见的。
  • @dymanoid 我可以在一定程度上得到无属性规则或者不使用 else 关键字,它可以帮助执行真正的 OO 编码。但是这个属性除了重域类型(比如 DDD 中的值对象/聚合)之外。

标签: c# oop design-patterns solid-principles


【解决方案1】:

背景

假设你有一个类 Foo 并且出于任何原因它需要来自 BoardRows

现在Foo 需要在Rows 中找到第5 项。几天后,您需要一个类Buu,它应该在Rows 中找到第8 项。

FooBuu 对于如何在 Rows 中查找项目都有自己的实现。

// ...
Foo foo = new Foo(board.getRows());
Buu buu = new Buu(foo.getRows());

BoardRow row5 = foo.find5thRow();
BoardRow row8 = buu.find8thRow();

只有 Collection 本身应该知道如何对其进行操作

来自Objects Calisthenics

这条规则的应用很简单:任何包含集合的类都不应包含其他 成员变量。每个集合都包装在自己的类中,因此现在与 该系列有一个家。您可能会发现过滤器成为这个新类的一部分。还, 您的新班级可以处理诸如将两个小组连接在一起或对每个小组应用规则等活动 组的元素。

如果我们要为 Rows 创建一个 First Class Collection,我们可以将它的一个实例传递给 FooBoo 并在其上调用一个方法:

class Foo {
    RowCollection rowCollection;

    // constructor and more ...

    public BoardRow find5thRow() {
        rowCollection.findByIndex(5);
    }
}

总结

一流的集合应涵盖创建、读取、更新、删除、过滤、合并等操作。传递一个 First Class Collection 的实例,而不是它自己的集合。优点是您只需将方法委托给您的 First Class Collection,而不是编写一个新的操作副本。

【讨论】:

    猜你喜欢
    • 2011-08-25
    • 1970-01-01
    • 2010-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多