Chinaunix首页 | 论坛 | 博客
  • 博客访问: 427037
  • 博文数量: 177
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 20
  • 用 户 组: 普通用户
  • 注册时间: 2014-05-22 19:16
文章分类

全部博文(177)

文章存档

2017年(1)

2016年(12)

2015年(112)

2014年(52)

我的朋友

分类: C/C++

2015-05-18 10:07:42

昨天下午开了一个Code Review的会议。主要Review我写的一个模块代码。此模块从设计到实现用了将近两个月的时间。本想没啥大的问题,但却讨论到了一个设计中的问题。

问题引入:

在模块中设计了一个公用的库以使多个模块使用,此库的作用是是提供一个Pool来存储所有的Server。并根据调用者的需求实时选择一个Server返回给调用者,调用者需要使用该Server来进行下一步工作(请求服务等)。 实现此Pool的一个原因是我们需要在Server之间实现fail-over和load-balance。即调用者上次使用server A 去处理事情,下一此可能会将请求提交给server B。并且在某个server down掉的情况下能够选择另一个server。大体设计如图1所示,这里选择逻辑会体现出fail-over和load-balance:

1


这里我们姑且将server称之为object,其有可用和不可用属性。其中一个重要逻辑上在选择过程中发现一个object不可用,需要将其加入Cache。为了便于追踪object的信息,我在模块中加入了log功能,即一个object在加入cache时就将一个log记录下来,便于用户查看。


讨论的焦点在于:

对于pool来说,加入cache属于一个事件,当事件触发时就去做某一件事情。那如果用户希望事件触发的行为不是pool提供的log呢?所以触发事件后的行为是交由pool来默认做呢,还是交由使用pool的模块来做呢?

 

其实各有各的好处,对于上图这样的设计,我最初的想法是使用者不需要关心pool内部的行为,不需要知道pool内部会触发事件,对其来说只是一个提供管理功能的黑箱子。这样做到的是对用户的完全封装。这样的缺点是丢掉了一些灵活性。经过最后的商量,觉得开放该灵活性给用户,这也遵循了积木式原则,充分相信使用该库的后来开发者能够自由组合发挥。所以该pool提供回调函数callback的设置接口。当事件触发时,则会回调用户定义的函数来表现不同的行为。结构如图2所示。

图 2
所以在软件代码设计过程中,封装是应该的,但不能太过于封闭而丢失灵活性,应给使用者提供足够的能力,使其在已有接口无法满足需求时,能够通过自由组合满足需求。达到既有简洁性又有灵活性。


阅读(990) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~