Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++;重构怪物类的帮助 我有C背景,是C++上的Neb。我有一个基本的设计问题。我有一个类(我将其称为“厨师”b/c,我的问题在复杂性和问题方面似乎与此非常类似)基本上是这样工作的 class chef { public: void prep(); void cook(); void plate(); private: char name; char dish_responsible_for; int shift_working; etc... }_C++_Refactoring_Anti Patterns_Oop - Fatal编程技术网

C++;重构怪物类的帮助 我有C背景,是C++上的Neb。我有一个基本的设计问题。我有一个类(我将其称为“厨师”b/c,我的问题在复杂性和问题方面似乎与此非常类似)基本上是这样工作的 class chef { public: void prep(); void cook(); void plate(); private: char name; char dish_responsible_for; int shift_working; etc... }

C++;重构怪物类的帮助 我有C背景,是C++上的Neb。我有一个基本的设计问题。我有一个类(我将其称为“厨师”b/c,我的问题在复杂性和问题方面似乎与此非常类似)基本上是这样工作的 class chef { public: void prep(); void cook(); void plate(); private: char name; char dish_responsible_for; int shift_working; etc... },c++,refactoring,anti-patterns,oop,C++,Refactoring,Anti Patterns,Oop,在伪代码中,这是按照以下方式实现的: int main{ chef my_chef; kitchen_class kitchen; for (day=0; day < 365; day++) { kitchen.opens(); .... my_chef.prep(); my_chef.cook(); my_chef.plate();

在伪代码中,这是按照以下方式实现的:

   int main{
    chef my_chef;
    kitchen_class kitchen;
    for (day=0; day < 365; day++)
         {
         kitchen.opens();
         ....

         my_chef.prep();
         my_chef.cook();
         my_chef.plate();

         ....

         kitchen.closes();
         }
   }

等等

不可否认,我仍在努力解决如何在运行时实现它,因此,例如,如果plater(或“以plater身份的厨师”)决定在晚餐服务中途回家,那么厨师必须换班

这似乎与我的一个更广泛的问题有关,即如果在本例中,同一个人总是做准备、烹饪和电镀,那么使用这种层次结构的类来模拟单个厨师的工作,真正的实际优势是什么?我猜这会遇到“害怕添加类”的问题,但同时,现在或在可预见的将来,我不认为维护整个chef类是非常麻烦的。我还认为,对于一个天真的代码读者来说,在chef对象中看到三种不同的方法并继续前进,在真正意义上是非常容易的

我知道,如果我们添加“cut_onions()”和“cut_carrots()”等方法,可能会变得很笨拙,也许每个方法都有自己的数据,但似乎可以通过使prep()函数更模块化来处理这些问题。此外,SRP的逻辑结论似乎将创建一个“洋葱切肉机”、“胡萝卜切肉机”等类别。。。我仍然很难看出这一点的价值,因为该计划必须确保同一名员工切割洋葱和胡萝卜,这有助于在不同方法中保持状态变量不变(例如,如果员工切割洋葱时切手指,他就不再有资格切割胡萝卜),而在monster object chef类中,似乎所有这些都得到了处理

当然,我知道这就不再是有意义的“面向对象设计”了,但在我看来,如果我们必须为厨师的每项任务都有单独的对象(这似乎是不自然的,因为同一个人在完成所有三项功能),那么这似乎会优先考虑软件设计而不是概念模型。我觉得如果我们想让“肉厨师”、“副厨师”、“三星厨师”等不同的人,那么面向对象的设计在这里是很有帮助的。此外,与运行时问题相关的是,在严格应用单一责任原则的情况下,似乎存在复杂性方面的开销,即必须确保构成基类employee的底层数据得到更改,并且此更改将反映在后续时间步骤中


因此,我很想让它或多或少保持原样。如果有人能澄清为什么这是一个坏主意(如果你对如何最好地继续下去有建议),我将非常感激。

为了避免现在和将来滥用阶级继承权,你真的应该只在存在关系时才使用它。作为你自己,“烹饪食物是厨房工人吗?”。它显然在现实生活中没有意义,在代码中也没有意义。“cook_food”是一个action,因此创建action类并将其子类可能是有意义的

拥有一个新类只是为了添加新方法,比如
cook()
prep()
并不是对原始问题的真正改进,因为您所做的只是将方法包装在一个类中。您真正想要的是做一个抽象来执行这些操作中的任何一个,所以回到action类

class action {
    public:
        virtual void perform_action()=0;
}

class cook_food : public action {
    public:
        virtual void perform_action() {
            //do cooking;
        }
}
然后,可以向厨师提供一个要按指定顺序执行的操作列表。例如,一个队列

class chef {
    ...
        perform_actions(queue<action>& actions) {
            for (action &a : actions) {
                a.perform_action();
            }
        }
    ...
}
另一个可能适用于此的密切相关模式是

这些模式还可以减少反模式的使用,因为很容易忘记调用某些方法,或者按正确的顺序调用它们,特别是在多次调用时。你也可以考虑把你的厨房。OpenSe和CouthSe()放入一个类似的模板方法中,而不是你需要担心的是关闭()被调用。
在为洋葱切肉机和胡萝卜切肉机创建单独的类时,这并不是SRP的逻辑结论,但事实上违反了SRP——因为您正在创建负责切割的类,并保存一些有关它们切割的信息。切割洋葱和胡萝卜都可以抽象为一个单独的切割动作,您可以指定要切割的对象,如果您需要每个对象的特定代码,还可以为每个单独的类添加重定向

class cutting_action : public action {
    private:
        cuttable* object;
    public:
        cutting_action(cuttable* obj) : object(obj) { }
        virtual void perform_action() {
            //common cutting code
            object->cut(); //specific cutting code
        }
}
一个步骤是创建一个抽象来表示某些东西是可裁剪的。子类化的关系是候选关系,因为胡萝卜是可切割的

class cuttable {
    public:
        virtual void cut()=0;
}

class carrot : public cuttable {
    public:
      virtual void cut() {
          //specific code for cutting a carrot;
      }
}
切割动作可以选择一个可切割对象并执行适用于所有可切割对象的任何普通切割动作,还可以应用每个对象的特定切割行为

class cutting_action : public action {
    private:
        cuttable* object;
    public:
        cutting_action(cuttable* obj) : object(obj) { }
        virtual void perform_action() {
            //common cutting code
            object->cut(); //specific cutting code
        }
}


有时,将现实世界中的角色/职责/任务映射到代码中的对象是行不通的。也许你需要一些通用的函数来处理一个人和一个动作。该函数让用户在每个类接口上应用action.module,是否可以提供更多线索?比如说一个盘子能做什么?厨师食物能做什么?他们需要继承还是仅仅是一项技能(函数调用)?看看组合方法。或者你需要一个状态模式?非常感谢大家的建议,他们给了我很好的起点!谢谢你。我本想再问一个问题。因此,如果我们遵循策略模式方法,假设每个厨师都有许多数据成员(例如,品尝汤匙、盐瓶等),用于cook\u food()和plate\u dish()类。看来班主任需要厨师,而厨师需要班主任。如何避免circ
class cuttable {
    public:
        virtual void cut()=0;
}

class carrot : public cuttable {
    public:
      virtual void cut() {
          //specific code for cutting a carrot;
      }
}
class cutting_action : public action {
    private:
        cuttable* object;
    public:
        cutting_action(cuttable* obj) : object(obj) { }
        virtual void perform_action() {
            //common cutting code
            object->cut(); //specific cutting code
        }
}