Подтвердить что ты не робот

Каков лучший класс класса С# для работы с read + write и readonly

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


Дизайн классов 1 - предоставить всю функциональность в базовом классе, а затем публично публиковать применимые функциональные возможности в подклассах

public abstract class RepositoryBase
{
    protected virtual void SelectBase() { // implementation... }
    protected virtual void InsertBase() { // implementation... }
    protected virtual void UpdateBase() { // implementation... }
    protected virtual void DeleteBase() { // implementation... }
}

public class ReadOnlyRepository : RepositoryBase
{
    public void Select() { SelectBase(); }
}

public class ReadWriteRepository : RepositoryBase
{
    public void Select() { SelectBase(); }
    public void Insert() { InsertBase(); }
    public void Update() { UpdateBase(); }
    public void Delete() { DeleteBase(); }
}

Class Design 2 - класс чтения-записи наследуется от класса только для чтения

public class ReadOnlyRepository
{
    public void Select() { // implementation... }
}

public class ReadWriteRepository : ReadOnlyRepository
{
    public void Insert() { // implementation... }
    public void Update() { // implementation... }
    public void Delete() { // implementation... }
}

Является ли один из этих проектов более сильным, чем другой? Если да, то какой и почему?

P.S. Если это звучит как вопрос о домашнем задании, это не так, но вы можете использовать его как один, если хотите:)

4b9b3361

Ответ 1

Как насчет третьего варианта, тесно связанного с первым, но используя вместо него интерфейсы:

public interface IReadRepository {
    public void Select();
}

public interface IWriteRepository {
    public void Insert();
    public void Update();
    public void Delete();
}

// Optional
public interface IRepository : IReadRepository, IWriteRepository {
}

public class Repository : IRepository {
   // Implementation
}

Таким образом, реализация (или может быть) реализована в одном месте, а различие выполняется только с помощью интерфейса, на который вы смотрите.

Ответ 2

( Изменить: Я думаю, что Eric Petroelje предлагает очень приятное решение на основе интерфейса в своем ответе. Вероятно, я проголосовал бы за его предложение, прежде всего.)

Из ваших двух вариантов я бы четко проголосовал за дизайн # 2.

С дизайном №1 я думаю, что нет смысла иметь класс "только для чтения", который внутренне не доступен только для чтения:

  • Класс только для чтения "тяжелее", чем должен быть.

  • Любой может быть получен из вашего класса только для чтения, а затем вызывать любые методы модификации базового класса. По крайней мере, с дизайном №1, вы должны сделать класс только для чтения sealed.

С дизайном №2 он намного яснее, чем класс только для чтения, это уменьшенная версия (базовый класс) полнофункционального класса или выраженная иначе.

Ответ 3

Сначала позвольте мне признать, что я делаю некоторые предположения о том, что вы могли бы сделать. Если это пропустит точку, тогда дайте мне знать.

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

Лучше всего предоставить общий интерфейс, а затем бросить исключения, если вы попытаетесь записать в репозиторий, когда он будет readony, а ваш код обработает исключения.

Ответ 4

Я бы сказал, дизайн # 2, но тогда вы должны изменить имя ReadOnlyRepository на что-то вроде ReadRepository.

Наследование определяет отношение IS-A между классами, а an говорит, что "ReadWriteRepository - это ReadOnlyRepository" не звучит логично. Но "ReadWriteRepository - это ReadingRepository" делает.

Ответ 5

Я бы сказал, что дизайн 2 самый сильный. Если вы хотите иметь реализацию только для чтения, ему не нужно ничего знать о написании. Имеет смысл расширить реализацию только для чтения с помощью методов вставки, обновления и удаления. Я также думаю, что этот дизайн является тем, который наиболее соответствует принципу Open-Closed.

Ответ 6

Я бы предложил иметь базовый класс ReadableFoo с запечатанным производным классом ImmutableFoo, чей конструктор принимает ReadableFoo и возможно наследуемый производный класс MutableFoo и, возможно, класс ReadableShadowFoo, конструктор которого примет ReadableFoo (который может или не может быть изменчивым), но который будет действовать как обертка только для чтения.

Ответ 7

Ответ Эрика означает SOLID-принцип ISP. Это так просто и удобно использовать.