哪个是更好的C#类设计来处理read + write和readonly

时间:2010-05-10 18:15:07

标签: c# design-patterns architecture class-design

我正在考虑两种不同的类设计来处理某些存储库是只读而其他存储库是读写的情况。 (我预见不需要只写存储库。)


类设计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(); }
}

类设计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。如果这听起来像是一个家庭作业问题,那就不是,但如果你愿意,可以随意使用它:)

7 个答案:

答案 0 :(得分:26)

第三个选项如何与第一个选项密切相关,但使用接口代替:

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
}

这种方式实现(或可以)在一个地方,并且区别仅取决于您正在查看的接口。

答案 1 :(得分:5)

编辑>我认为Eric Petroelje在他的回答中提供了一个非常好的基于界面的解决方案。我可能会投票给他的建议,首先。) < / p>

从你的两个选择中,我会明确投票给设计#2。

对于设计#1,我认为拥有一个内部不是只读的“只读”类是没有意义的:

  1. 只读类比它需要的“更重”。

  2. 任何人都可以从您的只读类派生,然后调用任何基类的修改方法。至少,使用设计#1,您应该制作只读课程sealed

  3. 对于设计#2,它比只读类更清晰,是全功能类的简化版(基类),或用不同的措辞。

答案 2 :(得分:1)

首先让我承认我正在对你打算做什么做一些假设。如果这个错过了重点,请告诉我。

我不确定这两个选项中的任何一个类都有多大用处。我假设您将调用将使用只读存储库实例的代码,并在其他情况下使用读/写存储库的实例,但接口不匹配,因此您不得不在代码中进行区分?

提供一个公共接口,然后在尝试在存储库中写入存储库并让代码处理异常时,可能会更好地抛出异常。

答案 3 :(得分:1)

我会说设计#2,但是你应该将ReadOnlyRepository的名称改为ReadRepository。

继承定义了类之间的IS-A关系,并且说'ReadWriteRepository是ReadOnlyRepository'听起来不合逻辑。但'ReadWriteRepository是一个ReadingRepository'。

答案 4 :(得分:0)

我当然会说设计2是最强的。如果您想要一个只读实现,它不需要知道任何有关写入的知识。使用insert,update和delete方法扩展只读实现非常有意义。我也认为这个设计最符合Open-Closed principle

答案 5 :(得分:0)

我建议有一个基类ReadableFoo,一个密封的派生类ImmutableFoo,其构造函数采用ReadableFoo,一个可能继承的派生类MutableFoo,可能还有一个类ReadableShadowFoo,其构造函数将采用ReadableFoo(可能是也可能不是是可变的),但它将作为它的只读包装。

答案 6 :(得分:0)

Eric的答案意味着SOLID Principle ISP。它非常简单易用。