Пример правила коллекции предметов первого класса в C #? - PullRequest
0 голосов
/ 29 ноября 2018

Я играю с правилами 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.
}

Я не совсем понимаю смысл этого правила, когда у вас уже есть базовые классы, которые можно использовать для достижения ваших целей.

Может быть, кодвыше, не самый лучший, но я хотел бы увидеть один пример, который может пролить свет на цель этого правила.

1 Ответ

0 голосов
/ 30 ноября 2018

Фон

Предположим, у вас есть класс Foo и по какой-либо причине ему нужно Rows из Board.

Теперь Foo необходимо найти 5-й элемент в Rows.Несколько дней спустя вам нужен класс 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();

Только сама Коллекция должна знать, как выполнять над ней операции

Из Объектов по художественной гимнастике :

ПрименениеЭто правило простое: любой класс, содержащий коллекцию, не должен содержать других переменных-членов.Каждая коллекция упакована в свой собственный класс, так что теперь поведение, связанное с коллекцией, имеет свои особенности.Вы можете обнаружить, что фильтры становятся частью этого нового класса.Кроме того, ваш новый класс может обрабатывать такие действия, как объединение двух групп или применение правила к каждому элементу группы.

Если бы мы создали коллекцию первого класса для строк, мы могли бы передать ее экземпляр Foo и Boo и вызвать для него метод:

class Foo {
    RowCollection rowCollection;

    // constructor and more ...

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

Резюме

Коллекция первого класса должна охватывать такие операции, как создание, чтение, обновление, удаление, фильтрация, слияние и многое другое.Передайте экземпляр коллекции первого класса вместо самой коллекции.Преимущество состоит в том, что вам нужно только делегировать методы в коллекцию первого класса, а не писать новую копию операции.

...