可选功能的设计模式?

发布于 2024-07-20 02:50:30 字数 1053 浏览 13 评论 0原文

我有一个派生子类继承的基本类,它携带在所有派生类中应该相同的基本函数:

class Basic {
public:
    Run() {
        int input = something->getsomething();
        switch(input)
        {
            /* Basic functionality */
            case 1:
                doA();
                break;
            case 2:
                doB();
                break;
            case 5:
                Foo();
                break;
        }
    }
};

现在,基于派生类,我想向 switch '添加'更多 case 语句。 我在这里有什么选择? 我可以声明虚拟函数,并且只在要使用它们的派生类中定义它们:

class Basic {
protected:
    virtual void DoSomethingElse();
public:
    Run() {
        int input = something->getsomething();
        switch(input)
        {
            /* Basic functionality */
            ...

            case 6:
                DoSomethingElse();
        }
    }
};


class Derived : public Basic {
protected:
    void DoSomethingElse() { ... }
}

但这意味着当更改任何派生类中的函数时,我必须编辑我的基类以反映这些更改。

有没有专门针对此类问题的设计模式? 我购买了一些关于设计模式的书籍,但我正在“按需要”学习它们,所以我不知道是否有我正在寻找的这种模式。

I have a basic class that derived subclasses inherit from, it carries the basic functions that should be the same across all derived classes:

class Basic {
public:
    Run() {
        int input = something->getsomething();
        switch(input)
        {
            /* Basic functionality */
            case 1:
                doA();
                break;
            case 2:
                doB();
                break;
            case 5:
                Foo();
                break;
        }
    }
};

Now, based on the derived class, I want to 'add' more case statements to the switch. What are my options here? I can declare virtual functions and only define them in the derived classes that are going to use them:

class Basic {
protected:
    virtual void DoSomethingElse();
public:
    Run() {
        int input = something->getsomething();
        switch(input)
        {
            /* Basic functionality */
            ...

            case 6:
                DoSomethingElse();
        }
    }
};


class Derived : public Basic {
protected:
    void DoSomethingElse() { ... }
}

But this would mean when changing functions in any derived class, I would have to edit my base class to reflect those changes.

Is there a design pattern specifically for this kind of issue? I purchased a number of books on Design Patterns but I'm studying them on "by-need" basis, so I have no idea if there is such a pattern that I am looking for.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

坏尐絯℡ 2024-07-27 02:50:30

您可能会发现阅读责任链模式并重新考虑您的解决方案很有用那样。

您还可以将“doRun”声明为受保护方法并在基本默认情况下调用它。

default:
   doRun(input);

并在派生类中定义doRun。

这就是所谓的模板方法模式

You may find useful to read about Chain of responsibility pattern and rethink your solution in that way.

Also you can declare 'doRun' as protected method and call it in the base default case.

default:
   doRun(input);

And define doRun in derived classes.

This is so called Template Method pattern

转角预定愛 2024-07-27 02:50:30

我认为您需要的模式是责任链或者可能是策略与动态调用表相结合......

I think the pattern you need is Chain Of Responsibility or maybe Strategy combined with a dynamic call table...

偏闹i 2024-07-27 02:50:30

处理这个问题的正常方法是使用工厂。 概述:

  • 创建提供功能的相关类的层次结构。
  • 创建一个工厂类,该工厂类接受输入并根据输入创建正确种类的类的实例

现在添加奖励点:

  • 创建一个在工厂中注册类的方案 - 您将需要指定输入和类的类型 。

现在,当需要新输入时,您只需派生一个新类并将其注册到工厂即可 对 switch 语句的需要消失了。

The normal way of dealing with this is to use a factory. In outline:

  • create a hierarchy of related classes that provide the functionality.
  • create a factory class that takes the input and creates an instance of the right kindf of class depending on the input

Now for added bonus points:

  • create a scheme that reghisters classes withn the factory - you will need to specify the input and the type of the class to deal with it

Now when a need for a new input comes along, you just derive a new class and register it with the factory. The need for the switch statement disappears.

假情假意假温柔 2024-07-27 02:50:30

如果您的选择器值只是小整数,我会用查找表替换 case 语句。 (案例中的每个操作都需要编码为函数,因此您可以将函数指针放入表中)。 然后继承的类只需向表中添加条目即可。 (我猜该表必须是实例属性,它不能是静态的)。

科林

If your selector values are just small integers, I would replace the case statement by a lookup table. (The actions in the case will each need to be coded as a function, so you can put function pointers in the table). Then inherited classes can just add entries to the table. (I guess the table would have to be an instance property, it can't be static).

Colin

绝不服输 2024-07-27 02:50:30

但这意味着当改变时
任何派生类中的函数,我
必须将我的基类编辑为
反映这些变化。

为什么这是真的?

我根据你的评论 - 那么如果你选择这种方法,你就会遇到这些问题。 其他人已经发布了建议其他解决方案的答案 - 我会检查这些内容,看看它们是否对您有帮助。

But this would mean when changing
functions in any derived class, I
would have to edit my base class to
reflect those changes.

Why would this be true?

I light of your comment - then if you choose this approach you'll have these issues. Others have posted answers that suggest other solutions - I'd check these out to see if they help you.

菩提树下叶撕阳。 2024-07-27 02:50:30

一个简单的解决方案:

class Basic {
  public:
    void Run() {
      const int input = ...
      if (!(BaseProcess(input) || Process(input))) ...
    }

    vitual bool Process(int input) { return false; }

    bool BaseProcess(int input) {
      switch(input) {
    ...
        default: return false;
      }
      return true;
    }
...

...然后在子类的 Process() 中实现其他情况。
如果您需要支持超过 2 个级别(即子子类添加更多案例),那么您将需要一个动态调度表。

А simple solution:

class Basic {
  public:
    void Run() {
      const int input = ...
      if (!(BaseProcess(input) || Process(input))) ...
    }

    vitual bool Process(int input) { return false; }

    bool BaseProcess(int input) {
      switch(input) {
    ...
        default: return false;
      }
      return true;
    }
...

...and then implement additional cases in subclass' Process().
If you need to support more than 2 levels (i.e. sub-subclass adding even more cases), then you'll need a dynamic dispatch table.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文