保护类不变量

时间:2014-05-23 13:54:24

标签: c#

我目前正在重构代码库的GUI层,并且在以下设计中强制执行类不变量时遇到了一些麻烦:

public interface IScreen {
  void Open();
  void Close();
  bool IsOpen { get; }
  ...
}

// class invariant: only the screen at the top of the stack should be open
public interface IScreenStack {
  void Push(IScreen screen);
  IScreen Pop();
  IScreen Peek();
}

IScreenStack的天真(?)实现可能会调用IScreen.Open()IScreen.Close()来尝试强制执行其不变量。但是,这并不能防止其他各方调用这些功能(从而打破不变量)。

我探索的一些可能的解决方案,取得了有限的成功:

  1. 使用internal关键字在Open()实施中隐藏Close() / IScreen,然后使IScreenStack依赖于该实施。这似乎是一个糟糕的主意,导致界面不完整(IScreen仍包含IsOpen,但不包含Open() / Close())。
  2. 通过在其构造函数中注入IScreen,使Stack<IScreen>的特定实现直接管理堆栈。这不会阻止第三方篡改堆栈。
  3. 介绍某种第三方(IScreenController?),以便在IScreenIScreenStack之间进行协调。这仍然不排除其他第三方破坏不变量。
  4. 非常感谢任何想法/指示!

1 个答案:

答案 0 :(得分:0)

C#中,如果您需要基础interface,并且还提供在其中所有子项之间共享的一些自定义逻辑,则最适合使用abstract类。

使用抽象类,您可以定义必须覆盖的抽象方法,以及可以正确处理内部逻辑的非抽象方法。

public abstract class AbsScreenStack {

    //child HAS to override this for it's own implementation
    public abstract void DoSomething(); 

    public AbsScreenStack Pop() {

       .......
       //HANDLE STACK AND APPLIED TO IT RULES HERE. 
       //THIS IS SHARED FOR ALL CHILDREN OF THIS CLASS
    }

}