我正在用C++编写一个库,客户可以使用它与硬件进行接口。我需要支持很多不同的设备。
为了简单起见,假设我有两个小部件,WidgetA和WidgetB,它们是物理设备。这两个小部件使用相同的协议进行通信,并且有很多共同之处。它们都支持20个相同的通用配置设置。但是,WidgetA支持10个唯一的配置设置,WidgetB支持不同的10个唯一配置设置。WidgetB也有一些独特的功能。
我的库的用户可能会预先知道他们在使用什么Widget (例如。如果用户只购买了一个Widget,并且想使用我的库与它通信,他们可能会使用它,因为他们知道只需要与WidgetA通信)。但是,还有其他一些场景,用户希望编写一个处理各种小部件的应用程序。Widget的类型必须在运行时通过询问实际设备来确定。
所以我的问题是:这个图书馆的设计应该是什么?我在考虑以下几种选择:
1)只需强行执行并将所有函数放入泛型Widget类中即可。运行命令之前将检查物理Widget,如果试图使用设备不支持的函数,则会发生错误。这最终会成为1类中的许多函数,在未来需要支持新的小部件时,这是遥不可及的。
class Widget
{
void setAddress(int); //generic config setting
void setUniqueOption1(int); //config only supported by physical WidgetA's
void setUniqueOption2(int); //config only supported by physical WidgetB's
... //repeat for all config and functions supported by any Widget!
}2)为每个Widget (或每个具有独特特性的Widget )添加一个单独的类。这似乎是个好主意,但用户必须首先创建一个通用Widget,然后确定他们正在与之交谈的物理设备的类型,然后创建特定的WidgetA类来访问该功能。
class Widget
{
void setAddress(int); //generic config setting
}
class WidgetA : public Widget
{
void setUniqueOption1(int); //config only supported by physical WidgetA's
}
class WidgetB: public Widget
{
void setUniqueOption2(int); //config only supported by physical WidgetB's
}3)创建一个纯虚拟ConfigOption类。为包含用户一次性设置的选项的每个Widget创建配置类。用户只使用泛型Widget类,它有一个函数setCustomConfig,它接受这些定制的小部件配置类。
class Widget
{
void setAddress(int); //generic config setting
void setCustomConfig(const ConfigOption&); //used to set all custom config settings
}
class ConfigOption = 0;
class WidgetA_Config : public ConfigOption
{
//user sets all the options, then sends the object to the Widget::setCustomConfig
int optionA1;
int optionA2;
int optionA3;
}
class WidgetB_Config : public ConfigOption
{
int optionB1;
int optionB2;
}这是我第一次尝试编写一个好的接口来与硬件接口,这对我用来编写代码的正常逻辑造成了很大的影响。这些想法中有哪些是正确的方法吗?还是我错过了什么设计?
实际上,这些小部件大约有30个,而且每天都有更多的潜力。其中一些功能与我所认为的"Base“有99%的相似之处,而另一些则具有这些独特的特性(配置和功能)。
发布于 2015-01-10 20:50:51
我认为,您可能会被困在试图使类层次结构符合现实世界的分类法上,而这并不总是最好的方法。
首先,在这种情况下,对象几乎总是由某种工厂创建的。调用一个probe函数,该函数返回已实例化的与系统连接的所有Widgets的列表。然后你就可以配置它了。
我看到的最常用于硬件设备的模型是一个功能的数据结构。以老鼠为例。他们都至少有两个按钮和至少两个轴,但有些更多。它们没有一个带有派生类(如Mouse )的基类ThreeButtonWithScroll,它们都有一个Axes集合和一个Buttons集合。类的用户不允许添加或移除轴或按钮,但他可以在每个属性上设置属性。
假设你有一种没有按钮的奇怪的鼠标。它的Buttons集合将是空的,因此是不可配置的。您没有公开任何不允许使用的接口。
如果您的功能列表非常庞大,您只需要在任何给定的设备上使用其中的一小部分,那么您可以在您的Features类中创建一个Widget数组。在这里,Feature可能是一些老鼠的独特之处,比如Vibration或BacklightColor。它们也可以是相对通用的,比如BooleanFeature("Vibration", disabled, callback)。
https://softwareengineering.stackexchange.com/questions/269673
复制相似问题