设备数据链路的设计模式
Design pattern for device data link
我有三种类型的设备(USB、COM和无线)和一个用于连接它们的PC软件。每个设备都具有从RS485网络连接、读取和写入数据的功能。在PC软件上,我必须实现应用层类才能使用设备。我正在寻找一些设计模式来编写应用层和传输层之间的连接。第一个想法是编写抽象类DataLink,每个设备都将继承抽象类接口(纯OOP):
class DataLink {
public:
virtual bool read() = 0;
virtual bool write() = 0;
};
class USBDevice : public DataLink {
public:
bool read() { /* some code */ }
bool write() { /* some code */ }
bool specificUSBFunction() { /* some code */ }
};
class COMDevice : public DataLink {
public:
bool read() { /* some code */ }
bool write() { /* some code */ }
bool specificCOMFunction(){ /* some code */ }
};
DataLink *dl = new COMDevice();
dl->read();
dl->write();
现在,如果我想使用特定的USB或COM功能,我必须使用丑陋的铸造。另一个问题是,这个类必须是singleton,因为我们只有一个可用的设备,所以我们不能创建多个对象。我正在寻找一种使用C++(可以是v11或v14)实现这一点的好方法。
首先,由于您有一个抽象类,我强烈建议您考虑定义一个抽象构造函数。
class DataLink {
public:
virtual bool read() = 0;
virtual bool write() = 0;
virtual ~DataLink() {}
};
现在创建这些设备引发了一些问题。你的多态设计更倾向于使用参数化的工厂方法,其中参数(配置数据?)会告诉你是要创建COM、USB还是WIFI设备:
DataLink *dl = CreateDevice("COM"); // For example. COuld use an enum as well
但你增加了另一个限制:
这个类必须是singleton,因为我们有只有一个设备可用,因此我们无法创建多个对象。
事实上,singleton的目的不仅是确保单个实例,而且还确保对它的全局访问点。如果你不需要这样的全局访问,我强烈建议不要在这里使用singleton。
顺便说一句,你的限制提出了其他问题:你有每种类型的设备吗?或者你有一个设备,不管它是什么类型的?最重要的是,难道有一天你必须支持几个设备吗?
因此,从概念上讲,即使您目前只有一个设备,唯一性也不是通用设备类的属性,也不是其具体实现。这只是您当前创建DataLink的用例。因此,我建议您实现一个工厂,并派生一个特定于应用程序的工厂来实现您的创造性约束;
class DeviceFactory { // application independent
public:
enum DeviceType { COMDevice, USBDevice, ... };
DataLink *CreateDevice(std::string devicename, DeviceType t);
};
class MySpecificFactory : public DeviceFactory { // application specific constraints
std::map<std::string,DataLink*> objects;
public:
DataLink *CreateDevice(std::string devicename, DeviceType t) {
if (objects.count(devicename)!=0) {
// device already exists, either report an error, or
// return the previously created object with the same name (provided it has the same type)
...
}
else {
DataLink* dl = DeviceFactory::CreateDevice(devicename,t);
if (dl)
objects[devicename]=dl;
return dl;
}
}
};
链接特定功能的处理与创建问题正交。最简单、最安全的方法当然是动态播放:
if (COMDevice* cd=dynamic_cast<COMDevice>(dl)) // nullptr if it isn't a COMDevice
cd->COMFunction();
else ...
如果不知道链接特定函数的用途以及它们在应用程序上下文中的关系,很难就更具体的模式提供建议。
您有几个选择,但我个人的经验来自中间件方法。因此,我将推荐这种方法(即使你不是在写"中间件","想法"仍然有用)
我们有几种不同的"物理连接":军用无线电1、军用无线电2、Wifi、USB到以太网等。每种连接都可以被认为与您的不同连接类型相似。
利用桥接模式。。。
旨在"将抽象与其实现解耦,以便两者可以独立变化"。桥接器使用封装、聚合,并且可以使用继承将职责划分为不同的类。
1) 定义所有连接都将使用的接口。
2) 将每个连接类型的基本原子操作封装到"helper"类中。(打开()、关闭()、读取()、写入(字节[]数据)等)
3) 编写一个桥接类,将通用接口转换为每个连接类型的"helper类"实现。
4) 有一些逻辑来确定在给定时间哪个"连接"应该是"活动的",并将"连接接口"与网桥impl相关联。所使用的连接类型。(或连接列表,如果这是多播发送等)
这样就可以了。你有一个单独的接口,你的应用程序的"其余部分"可以从中写入/读取。并且"impl.details"隐藏在原子操作"helper"类和/或桥接器类中。
示例接口://显然非常简单的示例
interface IConnection{
byte[] read(int size);
void write(byte[] data);
bool open();
bool close();
}
还有一个实现类:
class usb_wrapper{
// this is completely made up, but made up methods to show pattern as an example
// these methods are extreme exaggerations and not 'real' at all
int open(String connectionName, int id){
// returns connection_id of new connection
}
int close(int connection_id){...} // returns a flag if connection was closed
bool write128byte(byte[] data) {...} // you can only write 128 byte chunks
byte[] read128byte(){...} // you can only read 128 byte chunks
}
正如你所看到的,上面的片段有"相似之处",但实际的方法有不同的参数、不同的要求等。
桥梁等级:
class usbConnectionBridge implements IConnection{
usb_connection conn = new usb_connection();
// Here is where you have the IConnection methods, inside these methods you
// have the logic to 'adapt' from these methods ... to the 'conn' object
byte[] read(int size){...}
void write(byte[] data){...}
bool open(){...}
bool close(){...}
// possibly additional helper methods below, etc.
}
因此,"bridge"类将包装(封装)usb_wrapper,并使其能够与接口交互。从而允许接口(抽象)与其实现(usb_wrapper)解耦,以便两者可以独立变化"这是定义的桥接模式。
- 派生类是否可以在抽象工厂设计模式中具有数据成员
- 资源管理设计模式
- 用于在回调中调用解析器的设计模式
- 设计帮助 - 为不同类型的消息处理通用接口的设计模式
- 在这种情况下我应该使用哪种设计模式
- C++中物体改变识别的设计模式?
- 确保所有构造函数调用相同的函数 c++ 设计模式
- 需要实例化不同类/对象并在启动时确定的硬件插槽的设计模式
- 设计模式,以避免不必要地添加抽象函数以适应新功能
- 工厂设计模式优化
- 使用C++模板的数据映射器设计模式
- 为什么以及如何使用原型设计模式
- 具有多个继承共享一个资源的对象 - 寻找良好的设计模式
- 在C++中创建观察器设计模式的好方法
- 现代C++在多大程度上消除了对设计模式的需求?
- 对于存储另一个类所需信息的类,例如其构造,是否有设计模式?
- 下面抽象工厂设计模式的实现是正确的吗
- sql记录集函数的状态设计模式
- 是否有可以处理方法调用依赖关系的设计模式?
- 设备数据链路的设计模式