行业动态

当前位置:首页>>新闻中心>>行业动态 发布时间:2017-08-17 04:59:19

工厂设计模式在多串口通信中的应用

时间:2017-08-17 04:59:19 来源:本站 点击数:692

设计模式/软件设计模式Oesign pattern)是软件设计过程中的经验总结。可 以让程序代码易重用、易理解、更稳定。目前总结出来的模式有23种之多文中主要涉及工厂模式在多串口通信软件开发中的应用。作者针对衡器称重系统中常用的仪表、一机一

秤、一机多秤等应用场景提出相应的解决方案。

1.引言

在软件开发过程中,常常会碰到相似问题 做重复的工作。如何提高效率保证代码的可靠 性,可重用性昵?前人总结出了很多软件开发模 式,来解决相应的问题。文中将针对“软件设计 模式”工厂模式”在多串口通信软件开发中 的应用展开描述。

2.设计模式简介

设计模式(Oesign patten)是一套被反复使用 的、多数人知晓的、经过分类编目的、代码设计 经验的总结。使用设计模式是为了重用代码、让 代码更容易被他人理解、保证代码可靠性。最早 提出设计模式思想是在1994年,由Erich Gamma 等人,在其所著的《面象对象的可复用元素》一 书中提出的。总结出三大类别创建型模式、结 构型模式、行为型模式,六大原则(开闭原则、 里氏原则、依赖倒置原则、接口隔离原则、迪米 特法则、合成复用原则,23种设计模式俱体内 容请参看相关书籍。本文将重点介绍:工厂设计 模式。它属于创建型模式即在创建对象的过 程中,隐藏创建逻辑,这使得程序在创建给定实 例对象时,可以提供灵活的判断。

3.衡器软件中的问题

作者长期从事衡器称重软件的设计。在长期 的工作经历中,参与了很多项目,其中多数都会 用到串口通信。会遇到以下几种典型的应用问题:

1)在使用衡器仪表时,串口是常见的对外通 信方式。称重仪表厂家多,型号不一,通信格式 各不相同。能不能使用统一的开发模式,进行管 理,减少重复性的工作昵?

2)地磅称重管理中,有一机一秤也有 机多秤的模式。在多秤同时使用时,仪表型 号可能相同,也可能不同,有没有简洁、高效的 扩展软件代码的方法昵?

4.工厂设计模式

针对上述问题,作者通过实践和总结,觉得软件开发模式的中的工厂模式”比较适合解决 这类问题。

什么是工厂模式?顾名思义,就是客户提 订单交给工厂生产,最后得到“产 品”工厂模式模拟了这个过程。“工厂模 式”分为三种子类别:简单工厂、工厂方法、抽 象工厂。这三种方法,本质相同,但各有其应用 场景,简单来说,如下:

1)简单工厂:一个工厂生产多种不同产品。

2)工厂方法:多个工厂,每个工厂生产一种 产品。是对简单工厂的改进,因为“简单工 厂”不符合开闭原则”。

3)抽象工厂:多个工厂,每个工厂生产一种 或多种产品。可以根据订单需求,生产“产 品”订单中可能存在多种不同的产品”需 求,可以交给不同的“工厂生产”。

这三种模式都能解决衡器软件中的仪表串口 通信问题。文中重点讲解简单工厂“抽象 工厂”这两种模式,这两种模式比较容易理解, 其它的模式也可依此类推。

5.面向对象的实现过程

设计模式的运用与编程语言无关。作者以常 用的C++语言为例,说明面向对象的封装过程。

首先,作者封装了一组串口通信类,将串口 通信过程中,常用的的方法,封装在一个类族里, 为后期模式设计提供基础如图1所示。

云网客1.jpg

串口类库可根据需要不断扩展,封装好后, 与下文的设计模式类隔离,减少代码耦合。这个 类族中的底层子类,相当于工厂”里生产的产品

1)简单工厂的实现过程

简单工厂模式如图2所示,将产品”实例的创建放到工厂方法中完成,从而为产品的选择提供灵活性。这里的产品就是仪表型号,工厂就是 TMeterFactory 类,其方法 CreateMeter 可以创建各种仪表的实例。

云网客2.jpg

主要部分的伪代码如下:

#include

classTM eterfactory//仪表工厂类

{

Private:

m apm _m eter;// 管理 所有的仪表对象 public

TM eterfactory0;

ICommO bject*C reateM eter (char*strM eter- Name);//创建仪表实例方法

~TM eterFactoryO;//销毁仪表类实例

}

ICommObject*TM eterFactory::CreateM eter (char*strM eterN am e)

{ //检查仪表实例是否存在 ifm _m eter.end )!=m _m eter.find (strM eterN am e)) return m_m eter.find strM eterN am e)->second; //创建新的仪表实例 ICommO bject*pM eter=N ULL; if(!strcm p "X K 3190A 9",strM eterN am e)) pM eter=new TXK3190A9 0; else return NULL;

...//继续添加代码,创建其他仪表型号 m_meter.insert std ^pa ir rM eterN am e,pM eter)); return pMeter;

}

客户端调用代码如下 charweight[10]={0};

TMeterFactory*pFactory=new TMeterFactory;

 

ICommObject*pMeter=pFactory->CreateMe-

 

ter(“XK3190A9”);

 

strcpy(weight,pMeter->read());// 读取重量,中间省略 open,write,close 等方法代码

 

上述过程中,可以看到:在使用简单工厂模式 (或其它模式) 时,并不一定能减少代码量,但是易于后期扩展和理解。从客户端的调用代码可以看出:模式提供了统一的接口,调用者只要给出仪表型号,就能得到相应的类实例。实例创建过程封装到其他代码块中,只要那部分代码没有问题,调用者就能得到正确的结果,相当于黑盒操作。这种方式,适合多人分工合作,共同开发软件。

 

(2) 抽象工厂的实现过程

 

简单工厂模式适合一机一秤的称重软件开发。抽象工厂模式适合解决一机多秤的称重模式。他将仪表实例创建过程推迟到子类中完成,从而为订单中的多种产品组合提供机会。以下是一机一秤一机两秤类图如图 3 所示。

云网客3.jpg

由上图可以看出,每一个工厂代表一种称重模式,可以从一机一秤,扩展到一机 n 。而每一种称重模式中,可以用同一种型号的仪表,也可以用不同种型号的仪表组成系统。具

 

体实施时,可根据需求选择。C++ 伪代码如下: class ICommObject;

 

class IFactory // 抽象工厂

 

{

 

public:

virtual ICommObject * CreateMeter1()=0; // 创建仪表 1,此处为纯虚方法

 

virtual ICommObject * CreateMeter2 ()=0; // 创建仪表 2

 

// 可以继续添加 protected:

 

IFactroy();

 

};

 

Class TOne_pc_and_one_scale:public IFactory// 具体工厂:实现一机一秤功能

 

{

 

public:

 

ICommObject * CreateMeter1 () {return new TXK3190A9;}

 

};

 

Class TOne_pc_and_two_scale:public IFactroy// 具体工厂:实现一机两秤功能

 

{

 

public:

 

ICommObject * CreateMeter1(){return new

 

T8142pro;}

 

ICommObject * CreateMeter2(){return new

 

XK3180;}

 

};

 

客户端调用代码如下: // 一机一秤调用方法

char weight_A9[10]={0};// 重量字符串

 

IFactory * pScale=new TOne_pc_and_one_scale;

 

ICommObject * pA9=pScale->CreateMeter1();

 

strcpy(weight,pA9->read());// 读取重量到 weight

 

中,中间省略 open,write,close 等方法代码

 

 

// 一机两秤调用方法 char weight_8142[10]={0},weight_3180[10]={0};//

重量字符串

 

IFactory * pScale=new TOne_pc_and_two_scale; // 创建工厂实例

ICommObject * p3180=pScale->CreateMeter1(); ICommObject * p8142=pScale->CreateMeter2(); strcpy (weight_3180,p3180->read ());// 读取重量

到 weight_A9 中,中间省略 open,write,close 等方法代码

 

strcpy (weight_8142,p8142->read ()); // 读取重量到 weight_814

 

使用抽象工厂模式,在添加新的工厂时,并不影响已有的工厂代码,已有的代码基本不需改动,提高了程序的稳定性,符合

闭原则,因此成为 23 种软件设计模式之一。

 

6.工厂模式在称重传感器温度测试软件中的应用

 

作者在编写 《传感器温度测试软件》 的过程中,使用了数据采集板,每个板上有一个串口,多块板同时向上位机发送传感器的实时温度测量数据。利用抽象工厂设计模式,很好的完成了软件编写。原来在其他软件中的通信代码 (即图 1),移植过来使用,进行部分扩展,实现了代码重用。软件可以对每一个串口的通信数据和通信参数,进行单独的管理。如下图:

云网客6.jpg

7.相关问题讨论

Windows 系统中,某个串口设备,在某一时刻,只能被一个软件使用 (虚拟串口设备除外)。多个进程或线程同时使用,会产生冲突。冲突的情况分为三种:

(1) 两个 (或两个以上) 不同的软件,同时打开同一个串口

(2) 同一个软件,运行两次实例 (或两次以上) 在内存中,同时打开同一个串口

(3) 同一个软件,运行一次,但在软件内部两次(或两次以上) 打开同一个串口

②两种情况涉及不同进程之间的资源抢占的冲突,可以考虑用进程互斥的方法解决,不属于软件模式的解决范畴

对于第③种情况,可用“单例模式解决软件内部多次、同时读、写同一个串口冲突的问题。

单例模式的目标就是:每个类只能创建一个实例。类的构造函数拷贝构造函数设为私有保护权限,类实例由其静态成员函数创建。

文中的工厂模式也涉及到串口的调用,因此可能有人会问:工厂模式能否结合单例模式同时使用呢?答案是否定的。单例模式封装的对象是串口硬件实体。本文中的工厂模式是以称重仪表为对象,进行封装。两者的出发点和角度不同,虽然都用到了串口通信,但是功能需求不同。物理串口,同一时刻,只能被一个实例使用,因此用单例模式比较合理。而称重仪表类,则存在多台相同型号的仪表同时使用的情况,所以需要创建同一个类的多个实例。这些属于面对的编程思想,需要结合实践去体会他们的异同。

8.总结

在软件设计过程中,不仅衡器称重软件一机多秤(即一台上位机,多台称重仪表同时工作),可以使用工厂模式来设计,其它类似的涉及多台仪表,多个串口同时工作的软件,都可参考这种模式。软件模式的使用,使代码易于阅读,管理,能提高代码的重用效率。实际软件开发中,具体使用哪种模式,是一种模式,还是多种模式混合使用?对于开发者来说,需要有一定行业经验,总结出用户的需求,整理出规律性的内容,再选择合适开发模式,才能找到一条正确的道路。