代码之家  ›  专栏  ›  技术社区  ›  devuxer

哪个是处理读写和只读的更好的C类设计

  •  13
  • devuxer  · 技术社区  · 14 年前

    我正在考虑两种不同的类设计来处理这样一种情况:一些存储库是只读的,而另一些是读写的。(我不认为需要只写存储库。)


    课堂设计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... }
    }
    

    这些设计中的一个明显强于另一个吗?如果是,哪一个?为什么?

    另外,如果这听起来像是一个家庭作业问题,它不是,但如果你想的话,可以随意使用它。)

    7 回复  |  直到 9 年前
        1
  •  26
  •   Eric Petroelje    14 年前

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

    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
  •  5
  •   stakx - no longer contributing Saravana Kumar    14 年前

    ( 编辑: 我认为EricPetrolje在他的答案中提供了一个非常好的基于接口的解决方案。首先,我可能会投票赞成他的建议。)

    从你的两个选择中,我肯定会投赞成票 设计方案2。

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

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

    2. 任何人都可以从只读类派生,然后调用任何基类的修改方法。至少,对于Design 1,您应该将其设置为只读类。 sealed .

    设计2 它比只读类更清楚,它是全功能类的简化版(基类),或者用不同的措辞。

        3
  •  1
  •   Henk Holterman    14 年前

    我会说设计2,但然后您应该将readOnlyrepository的名称更改为类似readRepository的名称。

    继承定义了类之间的is-a关系,说“读写存储库是一个readonlyrepository”听起来不合乎逻辑。但“readwriterepository是一个readingrepository”确实如此。

        4
  •  1
  •   Chris Taylor    14 年前

    首先,让我承认,我正在对你可能会做什么做一些假设。如果这没有抓住要点,请告诉我。

    我不确定这些类在您的两个选项中有多有用。我假设您有一个调用代码,它将使用只读存储库的实例,而在其他时候使用读/写存储库的实例,但是接口不匹配,所以无论如何您必须在代码中进行不同的关联?

    如果您试图在存储库是只读的时写入它,并让您的代码处理这些异常,那么最好提供一个公共接口,然后抛出异常。

        5
  •  0
  •   driis    14 年前

    我肯定会说设计2是最强的。如果您想要一个只读实现,它不需要知道任何关于编写的内容。使用插入、更新和删除方法扩展只读实现是非常有意义的。我也认为这个设计最符合 Open-Closed principle .

        6
  •  0
  •   supercat    14 年前

    我建议使用一个基类readablefoo,其中包含一个密封的派生类immutablefoo(其构造函数采用readablefoo),一个可能继承的派生类mutablefoo,以及一个类readableshadowfoo(其构造函数采用readablefoo(可能是也可能不是mutable),但它将作为只读包装器。

        7
  •  0
  •   Gabriel Simas    9 年前

    Eric给出的答案是固体原理ISP。它使用起来非常简单和基本。