最好的方法来构造一个控制台菜单类hierachy? [英] Best way to construct a console menu class hierachy?

查看:170
本文介绍了最好的方法来构造一个控制台菜单类hierachy?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在C ++和Python中创建了一个控制台菜单,但是我想这个语言在这里不太重要,因为我在询问类的结构。



所以我想实现的是一个类似于MS-DOS的菜单,其中我可以有父菜单(文件夹)和操作菜单(文件)。

  [ - ]根目录
打开snakegame
[ - ]第一个子目录
打印出愚蠢的消息
[+]打开目录中的封闭目录
关闭计算机
[+]这些目录已关闭
[ +]您看不到其中的内容
退出菜单

,我在这里有两种类型的菜单:


  1. 目录(MS-DOS文件夹)菜单,当激活时,它们打开/关闭。例如:根目录现在打开,你可以看到里面的所有菜单。如果它被关闭, [ - ] 变成 [+] ,你不能看到任何其他

  2. 操作(MS-DOS文件)菜单,它们链接到一个功能。当激活时,他们调用它们链接的函数。例如:打开snakegame 可以链接到函数 startSnakeGame(),这将关闭菜单并启动蛇


  3. 我已经编码了两个工作实现来获得想要的结果,我只是想知道,我应该使用哪个?第一种方法是,我只有一个名为 Menu 的类,它将所有成员变量和方法编码到一个类中。另一种方式是,我把这两种不同类型的菜单分成两个类,共同的基类。






    这里有一些成员变量,我现在将它们分成三个部分(基类,目录类和动作类),但它们可以组合成一个类。



    基本菜单:




    • =一个菜单(目录一),它将 this / self 作为一个子元素放在列表/向量中(见下文)。

    • 标签 =显然打印菜单时显示的标签。




    目录菜单:code> =布尔值,告诉当前选择菜单




    • subMenus =保存其他菜单的列表或向量

    • open =告诉菜单是打开还是关闭的布尔值。



    操作菜单:




    • c $ c> =此菜单激活时调用的函数的指针。



    正如你所看到的,变量与其他类不同,并且可以设置为如果 action == 0 (无动作),则菜单自动更改 open false / true ,具体取决于它的当前值。这种方式动作菜单将被终止,只有动态菜单将保持 subMenus 关闭






    这可能是一个人的意见,但我一直在想这一段时间,找到一种优于其他方式,他们都有自己的优点和缺点,和两个都很好。所以我问你的意见,我很愿意听到,如果有人有任何理由,他们会选择一个在另一个。基本上我问的原因,我不在乎你的意见。



    除了文件夹和文件,没有其他菜单类型,所以基类可以

    正在使用菜单:



    Python只有一个类:

     #使用默认参数。这里设置action = None或action = toggleOpen()
    root = Menu(无,根目录)
    snake = Menu(root,Open snakegame,startSnakeGame)
    sub1 = Menu(root,First sub directory)
    printMsg = Menu(sub1,打印出愚蠢的消息)
    ...
    / pre>

    有多个类的Python:

      ,动作参数不再存在
    root = DirectoryMenu(无,根目录)
    snake = ActionMenu(root,Open snakegame,startSnakeGame)
    ...

    C ++带有一个类:

      Menu * root = new Menu(0,Root directory); 
    Menu * snake = new Menu(& root,Open snakegame,& startSnakeGame);
    ...

    多个类别的C ++:

      DirectoryMenu * root = new DirectoryMenu(0,Root directory); 
    ActionMenu * snake = new ActionMenu(& root,Open snakegame,& startSnakeGame);
    ...






    第二个编辑:我只实现了两种方式在Python中,只有一个类的方式在C + +。所以我开始在C ++中编写多类方法,只是为了有趣和练习,我遇到了一个问题;有一个基类,我不能向父类的 subMenus -vector中添加 this ,因为基类不拥有 subMenus ,并且基类不能知道 DirectoryMenu



    将必须通过这个,这是一个BIG减去我的方式。

      BaseMenu :: BaseMenu(BaseMenu * parent)
    : m_parent(parent)// works
    {
    m_parent-> addSubMenuk(this); // BaseMenu没有目录的addSubMenu()
    }


    解决方案

    这两种方法在性能等方面真的非常接近,所以很难弄清楚。
    然而,有一个原因,选择一个在另一个:逻辑和规则在OOP。我必须将其分为3个类: BaseMenu ActionMenu DirectoryMenu



    解决两个类无法知道对方问题在这里可以像建议使用iogane gamba puti fon gu 。但是,在 BaseMenu addSubMenu() removeSubMenu() $ c>会和只有一个类的规则一样多,所以这不是一个选项。



    我最后得到的是使用回调和重载指针( * )运算符。它现在返回一个指向另一个类的实例的指针,并根据类型调用它的方法。


    I've created a console menu in both C++ and Python, but I suppose the language isn't in too big role here, since I'm asking about the structure of classes.

    So what I'm trying to achieve, is a menu similiar to MS-DOS, where I can have parent menus (folders) and action menus (files). Here's what it could look like in the console, once printed:

    [-] Root directory
            Open snakegame
        [-] First sub directory
                Print out stupid messages
            [+] Closed directory in open directory
                Shutdown computer
        [+] These directories are closed
        [+] You can't see the content inside them
            Quit menu
    

    So as you see, I got two types of menus here;

    1. Directory (MS-DOS folder) menus, which hold other menus inside them. When activated, they open/close. For example: Root directory is now open and you can see all the menus inside it. If it gets closed, the [-] turns into [+] and you can't see any of the other menus.
    2. Action (MS-DOS file) menus, which are linked to a function. When activated, they call the function they're linked to. For example: Open snakegame could be linked to a function startSnakeGame(), which would close the menu and start the snake game.

    I've already coded two working implementations to get the wanted result, and I was just wondering, which one should I use? The first way is, where I only have one class called Menu, and it has all the member variables and methods coded into one class. The other way is, where I got these two different types of menus separated into two classes, with a common base class.


    Here are some member variables, I'll split them into three sections (base class, directory class and action class) for now, but they can be combined into one class.

    Base Menu:

    • parent = A menu (directory one) that holds this/self inside a list/vector as a child (see below).
    • label = Obviously the label which gets displayed when the menu is printed.
    • selected = Boolean value which tells wether the menu is currently selected (fe. pointed by mouse).

    Directory Menu:

    • subMenus = A list or a vector (in C++) that holds other menus inside it.
    • open = A boolean value which tells wether the menu is open or closed.

    Action Menu:

    • action = Pointer to the function which gets called when this menu gets activated.

    As you can see, there are just few variables which differ from the other class, and it could be set so that if action == 0 (no action) then the menu automatically changes open to false/true depending on it's current value. This way action menu would be terminated, and only down side would be that action menus would hold subMenus and closed without use.


    This might be all about one's opinion, but I've been thinking about this for a while, and couldn't find one way superior to other, they both have their advantages and downsides, and both work well. So I'm asking about your opinion, and I would love to hear if anyone has any reasons why they'd choose one over the other. Basically I'm asking for the reasons, I don't care about your opinion.

    There will be no other menu types than folder and file, so the base class could not be used for anything else.


    Edit: A simple Python and C++ example on how the menus are being used:

    Python with only one class:

    # Using default param. here to set "action = None" or "action = toggleOpen()"
    root = Menu(None, "Root directory")
    snake = Menu(root, "Open snakegame", startSnakeGame)
    sub1 = Menu(root, "First sub directory")
    printMsg = Menu(sub1, "Print out stupid messages")
    ...
    

    Python with multiple classes:

    # With multiple classes, action parameter no longer exists
    root = DirectoryMenu(None, "Root directory")
    snake = ActionMenu(root, "Open snakegame", startSnakeGame)
    ...
    

    C++ with one class:

    Menu* root = new Menu(0, "Root directory");
    Menu* snake = new Menu(&root, "Open snakegame", &startSnakeGame);
    ...
    

    C++ with multiple classes:

    DirectoryMenu* root = new DirectoryMenu(0, "Root directory");
    ActionMenu* snake = new ActionMenu(&root, "Open snakegame", &startSnakeGame);
    ...
    


    2nd Edit: I had only implemented both ways in Python, and only the one-class way in C++. So I started to code the multi-class way in C++ too, just for fun and practice, and I ran into a problem; having one base class, I cannot add this to parent's subMenus-vector, since base class doesn't own subMenus, and base class cannot know DirectoryMenu.

    So I will have to hack my way through this, which is a BIG minus. Unless someone can think of a good way to implement it?

    BaseMenu::BaseMenu(BaseMenu* parent)
    : m_parent(parent) // works
    {
        m_parent->addSubMenuk(this); // BaseMenu doesn't have Directory's addSubMenu()
    }    
    

    解决方案

    The two ways are really close to each other in performance etc, so it was kinda hard to figure out. However, there was one reason to pick one over the other: Logic and rules in OOP. I had to split it into 3 classes: BaseMenu, ActionMenu and DirectoryMenu.

    Solving the "two classes cannot know each other" problem here could've been done like iogane gamba puti fon gu suggested. However, defining abstract methods addSubMenu() and removeSubMenu() in BaseMenu would be just as much against rules as having only one class would, so that's not an option over the other way.

    What I ended up with, is using callbacks and overloading the pointer(*) operator. It now returns a pointer to the instance of the other class and calls it's methods depending on the type.

    这篇关于最好的方法来构造一个控制台菜单类hierachy?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆