【问题标题】:OOP, enforcing method call orderOOP,强制方法调用顺序
【发布时间】:2015-05-06 00:32:12
【问题描述】:

问题:

这是一个关于 OOP 实践的问题。我在使用 API 时遇到了一种情况,其中需要按特定顺序调用一系列方法。

案例:

控制智能传感器的操作。

交互的简化版本如下所示:首先必须将 API 配置为通过 TCP 与传感器交互,下一个命令开始扫描过程,然后接收多个项目的输入,直到给出停止命令。那时必须给出类似的一系列断开命令。如果这些被乱序执行,则会引发异常。

我在这里看到了模块化和封装概念之间的冲突。每个步骤都是一个离散的操作,因此应该封装在单独的方法中,但它们也依赖于正确的执行顺序。

我是从后来从事此代码的开发人员的角度考虑的。似乎有人必须对这个系统有很高的理解才能处理这个代码,这让人觉得它很脆弱。我可以添加有关此调用顺序的警告 cmets,但我希望有一些可能适合我的情况的原则或设计模式。

这是一个例子:

class RemoteTool
{
    public void Config();
    public void StartProcess();
    public void BeginListen();

    public void StopProcess();
    public void StopListening();
}

class Program
{
    static void Main(string[] args)
    {
        RemoteTool MyRemoteTool = new RemoteTool();

        MyRemoteTool.Config();
        MyRemoteTool.StartProcess();
        MyRemoteTool.BeginListen();

        // Do some stuff

        MyRemoteTool.StopListening();
        MyRemoteTool.StopProcess();
    }
}

我能想到的最接近的方法是使用布尔标志并在每个函数中签入它们以确保已经调用了必备函数,但我想我希望有更好的方法。

【问题讨论】:

  • 你应该考虑看看Continuation Tasks
  • 我正在为这个问题的广泛性而苦苦挣扎。如果你有函数ABC,并且每次调用CAB都必须事先立即调用,然后你就换行了他们在一个函数中调用ABC 之前。如果您可以调用C,只要在某个时候调用AB(即ABCCC 等),您只需在对象构造函数中调用 AB 并添加 reconfigurereboot 函数以再次调用它们。恕我直言,这个问题没有足够的细节来提供可靠的答案。所以,这取决于
  • 它可能需要一些重构,但解决这个问题的一种方法可能是为每个状态创建一个类。 (即tool.start_process() 返回一个Process 对象,该对象有一个.stop() 方法 - 大概返回tool 需要的任何数据)。
  • 另外,如果所有逻辑都需要放在一个地方,这可以全部建立在State Machine之上

标签: oop design-patterns


【解决方案1】:

这是我在寻找答案时发现的一种方法。这很简单,它有帮助,但并没有解决我的问题。

基本上这个类是在问题中创建的,但是依赖的函数被创建为受保护的,并且创建了一个公共成员来保持它们的顺序,如下所示:

class RemoteTool
{
    public bool Running = false;
    public void Run()
    {
        Config();
        StartProcess();
        BeginListen();

        Running = true;
    }

    public void Stop() {
        StopListening();
        StopProcess();

        Running = false;
    }

    protected void Config();
    protected void StartProcess();
    protected void BeginListen();

    protected void StopProcess();
    protected void StopListening();
}

麻烦的是,你仍然需要按正确的顺序调用 Stop() 和 Run(),但它们更容易管理,模块化程度更高。

【讨论】:

    【解决方案2】:

    我认为问题与 RemoteTool 类的 contract 需要一些先决条件有关。例如: 方法 b() 必须在方法 a() 之后执行 ()。

    如果您的语言没有提供定义这些前置条件的机制,您需要自己实现一个。

    我同意你实现这个额外的功能(或这些特定的类契约特性) RemoteTool() 类内部可能会降低您当前的设计。一个简单的解决方案是使用另一个类,负责在调用 RemoteClass 的特定方法之前强制执行所需的前置条件。(RemoteToolProxy() 可以是一个合适的名称)

    通过这种方式,您可以将具体功能与说明如何使用它的合同解耦。

    称为Design by Contract 的软件设计方法提供了其他替代方案 这可以为您提供其他改进班级合同的方法。

    【讨论】:

      猜你喜欢
      • 2015-09-02
      • 1970-01-01
      • 2021-12-23
      • 2011-04-28
      • 1970-01-01
      • 2012-06-08
      • 2014-07-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多