软件设计原则


设计篇之软件设计原则(一)
                    ---设计思想
                                                        
                                                   


     

1前言

         

上一篇我们提到在软件开发中语言只是一种工具,编程思想才是最核心的。有了思想的指导,不管 什么语言,只不过是实现方式的不同而已。下面我们就来具体阐述为什么掌握编程思想如此的重要。

2小试牛刀

     

我们以制造工厂的生产场景为例: 假设现有一台上位机(PC) A,一台生产设备(PC) B,A负责接收设备上报的数据,采集完后对数据做一次业务转换,然后存入数据库。那么可以设计三个模块,一个是业务模块,一个是通信模块,一个是数据持久化模块。在领域驱动设计(后面文章会详细讲解)里面,业务模块属于领域层,通信和持久化属于基础设施层,因次调用关系如下:

业务模块与通信模块以及持久化模块是依赖和被依赖的关系,在代码中体现为程序集的引用顺序。

那么问题来了,A接收完设备数据后需要把数据传递给业务层,但是通讯模块相对于业务模块是被依赖的,总不能再去直接调用业务层的接口,这样的话就形成循环依赖了,这在软件设计里面是禁止的 。

要解决这个问题,就要用到回调的思想了,通俗来讲就是我不去找你,你主动来告诉我。

举个例子:你去某公司面试,面试完后每天去找HR询问结果怎么样,HR被你烦的不耐烦了,就跟你说,你不要再来问我,一有消息我就通知你。原先你需要主动去问,现在是被动接受消息就好了,是不是方便很多。

回调实现:在C++里使用的是回调函数,在C#里使用的是委托,在Java使用的是函数式接口

3代码实现

C++实现:

业务层实现回调函数主体

  1. void MyBussniess::ConvertData(void* para, string message)

  2. {

  3.    MyBussniess * mb = (MyBussniess*)para;

  4.    //do somesing

  5.    printf_s("[业务层] convert date to %s\r\n", message.c_str());

  6.    mb->m_db.WriteToDb(message);

  7. }

通信层添加回调函数的宿主函数,在这里回调函数被使用

  1. #include "stdafx.h"

  2. #include "Communicator.h"

  3. Communicator::Communicator()

  4. {

  5.    ReceivMessage();

  6. }

  7. Communicator::~Communicator()

  8. {

  9. }

  10. void Communicator::RegisterCallback(void* param, lpFunc callback)

  11. {

  12.    this->m_context = param;

  13.    this->m_mycallback = callback;

  14. }

  15. void Communicator::ReceivMessage()

  16. {

  17.    thread recvthd(&Communicator::ReceiveThread,this);

  18.    recvthd.detach();

  19. }

  20. void Communicator::ReceiveThread()

  21. {

  22.    while (true)

  23.    {

  24.        try

  25.        {

  26.            //std::lock_guard<std::mutex> mtx_locker(m_mtx);

  27.            m_mtx.lock();

  28.            if (m_messageQueue.empty() == 0)

  29.            {

  30.                string recv = m_messageQueue.front();

  31.                m_messageQueue.pop();

  32.                printf_s("[通信层]receiv message data:%s\r\n", recv.c_str());

  33.                //调用回调函数

  34.                m_mycallback(m_context, recv);

  35.            }

  36.            m_mtx.unlock();

  37.            std:this_thread::sleep_for(chrono::seconds(2));

  38.        }

  39.        catch (exception e)

  40.        {

  41.        }

  42.    }

  43. }

  44. void Communicator::SendThread()

  45. {

  46.    while (true)

  47.    {

  48.        //std::lock_guard<std::mutex> mtx_locker(m_mtx);

  49. LOL凯特琳新皮肤-电玩女神凯特琳普通版与至臻版对比

  50. EQ驱动!
  51. 6件拖累宝宝免疫力的事情,家长们千万别再这样做了!
  52. 最伤宝宝眼睛的不是手机,而是父母做错的这6件事!
  53. 黑洞是相对论推导出的一个数学概念,却与量子力学发生了激烈矛盾
  54. 傅园慧父女芒果台秀溺爱谈养生,老爸的溺爱成就了“洪荒之力”
  55. 积木育儿︱孩子不跟同龄人玩儿,不合群,背后原因让人沉默
  56. 带着256g的胃,在这里吃遍世界美食!
  57. 今日NBA球星上脚:流口水的实战鞋
  58. 家居装修--酒柜选用哪种材质好