Какая классовая структура более желательна? - PullRequest
3 голосов
/ 08 апреля 2009

Я не уверен, какой из этих двух «шаблонов» является лучшим. В настоящее время я использую опцию A (совместно с провайдером для реализации персистентности), но теперь я ошибаюсь в направлении B, особенно в свете модульных тестов, которые могут использовать модель «внедрения зависимости».

Вариант A:

class ClassA
{
   ClassA() { }
   Save();
   static List<ClassA> GetClassAs();   
}    

Вариант B:

class ClassA
{
   ClassA() { }
   Save();
}

class ClassARepository
{
    ClassARepository() { }
    List<ClassA> GetClassAs();    
}

Я думаю, что я спрашиваю, является ли хорошей практикой для класса выставлять статические методы, которые возвращают коллекции своих экземпляров?

Редактировать

Похоже, существует общее мнение, что вариант B является лучшим выбором. Похоже, у меня впереди много рефакторинга: S

Ответы [ 6 ]

4 голосов
/ 08 апреля 2009

Опция B немного похожа на шаблон ActiveRecord (я предполагаю, что метод Save в ClassA будет использовать ClassARepository?), Что хорошо в некоторых ситуациях, но, если у вас довольно сложная модель предметной области Я бы не использовал шаблон «ActiveREcord».

Вместо этого я бы использовал такую ​​модель:

public class ClassA
{
   public int Id {get; private set;}
   public string Name {get; set;}
}

public class ClassARepository
{
    public ClassA Get( int id );

    public void Save( ClassA item );
}

Это означает, что вся связанная с постоянством логика помещена в класс ClassARepository, а ClassA также не имеет прямого доступа к хранилищу.

2 голосов
/ 08 апреля 2009

Вы либо полностью отделяете постоянство объекта от данных и логики, либо сохраняете все в одном классе. Переместите «Сохранить» в «ClassARepository» или оставьте «GetClassAs» внутри «ClassA».

1 голос
/ 08 апреля 2009

Вариант B выглядит лучше, потому что A смешивает две идеи, два вида функциональности. Есть реальная функция класса А и отдельная функция управления коллекцией А.

По мере роста приложения также вероятно, что вам понадобятся дополнительные функции в вашем хранилище - findById, получение подмножеств и т. Д. Обувать это в класс А будет грязно.

И, как вы заметили, вариант B легче тестировать.

0 голосов
/ 08 апреля 2009

Я думаю, что я спрашиваю, является ли хорошей практикой для класса выставлять статические методы, которые возвращают коллекции своих экземпляров?

Обычно нет - такие коллекции часто являются синглетонами, и если они (как в вашем примере), то обычные причины для синглетонов считаются антипаттерном , а также причины, по которым статический считается вредным .

0 голосов
/ 08 апреля 2009

Вариант B более гибкий.

  • Позволяет иметь несколько репозиториев.
  • Позволяет разделить класс хранилища на подклассы.
  • Он позволяет передавать хранилище в качестве аргумента другому классу или функции, вместо того чтобы этот класс или функция были явно связаны с глобальной статической переменной.
0 голосов
/ 08 апреля 2009

Нет, я бы не считал эту плохую практику жестким и быстрым правилом, хотя я предполагаю, что это для какого-то отслеживания экземпляров или мониторинга ресурсов? Если так, просто помните, что за кулисами должна быть логика, чтобы гарантировать, что объекты, которые иначе были бы вне области видимости, не оставались в вашей статической коллекции. Я не уверен, какой язык вы используете, но если это C #, вы можете хранить его внутри как List<WeakReference>.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...