【问题标题】:How do you abstract the information to be displayed in a screen?你如何抽象出要在屏幕上显示的信息?
【发布时间】:2017-09-29 20:59:53
【问题描述】:

我正在编写一个应用程序,需要我将信息写入 TFT 显示器(有点像 gameboy 显示器)。 我将信息逐行输出到显示器。我现在这样做的方式要求我为每个不同的屏幕提供一个功能。 喜欢:

void displayWelcomeMessage();
void displayInsertCoinMessage();
void displayGoodByeMessage();

每个函数都遵循这个逻辑:

void displaWelcomeMessage()
{
  writeline(0, "Hi David");
  writeline(1, "Welcome");
  writeline(2, "Back!");
}

问题:我讨厌每个屏幕都有不同的功能。它根本不可扩展,想象一下如果我有 500 个不同的屏幕。 如何抽象写入显示的过程?这样我就得到了一个负责写入显示器的通用函数。

谢谢


更新

按照“Useless”和 Michael.P 的建议,我最终可能会做的是将每条消息的格式存储在一个文件中:

DisplayMessages.cfg

WELCOME_MESSAGE_1 = "Hi %name"
WELCOME_MESSAGE_2 = "Welcome"
WELCOME_MESSAGE_3 = "back!"

在代码中我会做类似的事情:

using Message = std::vector<QString>;

void login(){

 //Do Stuff...

 QString line
 Message welcomeMessage;

 line=getMessageStructureFromCfg("WELCOME_MESSAGE_1").arg(userName); // loads "Hi %name" and replaces %name with the content of userName
 welcomeMessage.pushBack(line); // pushes the first line to welcomeMessage

 line=getMessageStructureFromCfg("WELCOME_MESSAGE_2"); // loads "Welcome"
 welcomeMessage.pushBack(line); // pushes the second line to welcomeMessage

 line=getMessageStructureFromCfg("WELCOME_MESSAGE_3"); // loads "back!"
 welcomeMessage.pushBack(line); // pushes the third line to welcomeMessage

 displayMessage(welcomeMessage);

}

void displayMessage(Message const &msg) {
 int i = 0;
 for (auto &line : msg) {
   writeline(i, line);
   i++;
 }
}

感谢大家的帮助!

PS:如果包含消息结构的文件使用 JSON 而不是纯文本,则可以进行进一步的改进。这样你就可以迭代每条消息的子成员(行)并相应地处理

【问题讨论】:

  • 在任何情况下,您都会在许多函数(方法)或许多类中编写代码,但您可以定义一个名为Displayer 的接口(纯虚拟类),其中包含一个方法示例:display 然后你在许多类中实现它,例如:WelcomeMessageDisplayer,'InsertCoinMessageDisplayer' ...然后你把所有的对象都当作Displayer
  • 问题是,目前,我有 50 种不同的显示信息(50 种不同的功能)。这意味着我将有 50 个不同的课程。必须有更好的方法来做到这一点
  • 您可以将这些消息存储在一个文件中吗?然后,您可以将它们放入向量中,并根据需要遍历它们中的任意数量
  • 我喜欢这个主意。这样我就不必每条消息都有一个函数(或每条消息一个类)。我更新了我的帖子
  • 请注意,您仍然有一些交错的数据和逻辑(getMessageStructureFromCfg/push_back 行)。您的目标可能是只使用 fetchAndDisplay("WELCOME_MESSAGE") 为您自动执行该循环。

标签: c++ architecture abstraction reusability


【解决方案1】:

你如何抽象出要在屏幕上显示的信息?

与抽象任何信息的方式相同 - 将数据从代码中移出并放入数据结构中。

您的displayXMessage() 函数对固定的硬编码字符串文字序列执行固定的调用序列。因此,通过将数据作为参数传递,以通常的方式从数据中拆分算法:

using Message = std::vector<std::pair<int, std::string>>;

void displayMessage(Message const &msg) {
  for (auto &line : msg) {
    writeline(line.first, line.second);
  }
}

并使用适当的数据调用它:

Message welcomeMsg { {0, "Hi David"}, 
                     {1, "Welcome"},
                     {2, "Back!"}
                   };
displayMessage(welcomeMsg);

【讨论】:

  • 真的很喜欢你的方法!谢谢。请查看我所做的更新
【解决方案2】:

我认为你会通过学习设计模式找到解决所有这些问题的方法。在这种情况下尤其如此。 Strucural patterns 似乎就是您要找的东西;然后,您必须选择最适合您尝试做的模式。

【讨论】:

  • 有人可以解释为什么不投票吗?设计模式正是为回答这类问题而设计的,例如类指数多重性等。它为常见问题提供了适应性强的解决方案。
  • 可能是因为设计模式不是应该帮助您设计代码:它们应该帮助您描述和交流您的设计想出了。它们是常见解决方案的名称,而不是要遵循的秘诀。
  • 经过进一步思考(尽管我没有投反对票),我还是看不出结构模式与这里的相关性。这实际上是一个简单的代码级重构,而不是架构。
  • 你说得对,尽管我仍然认为那些非常常见的解决方案显然适合他的问题以及他可能遇到的任何类似问题。因此,在我看来,学习这些名称和模式描述可能帮助他理解如何更好地抽象,并且可以为他提供工具来改进他构建代码的方式。我承认这可能会深入回答一个简单的问题。
  • 不一定太深,我只是觉得方法不对。模式提供了一种用于命名解决方案的语言,但您仍然必须首先实际解决您的问题。
猜你喜欢
  • 1970-01-01
  • 2015-10-08
  • 1970-01-01
  • 1970-01-01
  • 2018-12-08
  • 2020-02-09
  • 2020-04-25
  • 1970-01-01
  • 2011-09-27
相关资源
最近更新 更多