软件开发中的矛盾——一个简单的例子

原创 2002年08月12日 11:33:00

在以前的文章中,我曾经提到过软件开发中充满了矛盾,一些原则本身就是彼此矛盾的,需要不断在这些矛盾中寻求折中、平衡。这里给出一个源自实际的简单例子,希望能给大家一点启示,只是不知道是否贴切(说明:程序用C++语言描述,T为每个数据类型)。

在定义某个类的接口时,需要定义两个相关变量a和b的getter/setter函数。为了使接口尽量精简,我们采用第一种方法,用一对getter/setter来处理:

getAB(T* pa, T* pb);
setAB(T a, T b);

但是,如果有时只想对其中一个变量进行存取时,调用getAB/setAB就需要额外的工作,client方的代码就会很累赘。

为了获取a的值,不得不定义一个额外的变量b:
T a, b;
getAB(&a, &b);
cout << a; // only get a

为了设置a的值而保留b的值,不得不额外调用getAB:
T a, b;
getAB(&a, &b);
a = 10;
setAB(a, b); // only set a

为此,我们采用第二种方法,将之拆成两对函数:

T getA();
T getB();
void setA(T a);
setB(T b);

这样,接口就一下扩展了一倍。但是,事情并未就此结束。有时,像getAB/setAB这样的方式并非只起到了简化接口的作用。在调用setAB的时候,我们可以从a和b相关的角度来考察a和b的合法性,比如:a,b代表某个值域的上下限,那么假定如果a > b时,设置就不合理,就应该拒绝。而这种合法性检查用第二种方法实现的时候就不是那么顺利了,粗看起来代码应该如下:

void setA(T a)
{
  if (a > m_b)
    return; // error
  else
    m_a = a;
}

void setB(T b)
{
  if (b < m_a)
    return; // error
  else
    m_b = b;
}

如果只是设置a、b中的一个值,倒不会有任何麻烦,这种方法完全胜任。但是,如果同时设置呢?暂且不考虑a、b的初值应该如何取,比如某次对a、b的设置使a、b分别等于5、10,而再次试图重设a、b为15、20时,问题就产生了:

setA(15);
setB(20);

结果变成了a = 5, b = 20(completely error)。

如果要得到正确结果,则需要颠倒调用setA和setB的次序。但是,如果a、b要分别设成1、6呢?亦即,为了保证成功设置,client代码需要十分小心,不同情况,采用不同的调用约定。对于上述情况,用第二种方法很难做到正确的合法性检查,因为函数的signature决定了它无法得知相关的另一个值,从而不能做出正确判断。

所以,事情的演变过程就是:
为了使接口精简,我们选择方法一;
为了不增加额外的客户代码,我们选择方法二;
为了进行合法性检查,我们又不得不选择方法一。
这里总共出现了两种方法,三个原则(“为了……”)。

而当我们最终决定选择方法二时,还是有可能背负着“增加额外的客户代码”这样的罪名。而如果你确实不想如此,或许你会将两种方法结合使用,即把getA/setA,getB/setB,getAB/setAB统统定义为接口。可是,你又可能会被人指责为“接口混乱”,而且对于setA/setB而言,合法性检查仍然是个问题。

结论:在有多种方法可供选择时,存在不同的原则(选择依据),针对实际的情况,我们需要作出决定。这种决定往往不会做到满足所有原则,但一般它应该是最大限度的适合大多数情形。如果,实际的情况不能足以使你作出很肯定的判断,那么,恐怕只有习惯和直觉可以影响你的决定了。只是,或许以后你还会修改你的决定。

ps:为了说明方便,所以这里选用了一个极为简单的例子。坦白讲,可能有夸大之嫌。实际情况下,对于这样的“getter/setter”问题,你多半不会像文中说得那样处于如此为难的境地,除非你是个完美主义者。你可以很快作出决定,因为即使无法满足某条原则,其代价也不会很高。否则,那些软件开发人员,每天就不用写几行代码了,而且会深陷于矛盾的痛苦之中。但是,在这样细微的地方都会存在矛盾,可以想见,用“矛盾重重”来形容软件开发过程,可能是不算夸张的。

实践论与矛盾论---读毛泽东选集(第一卷)札记

一、实践论         认识和实践的关系也就是知和行的关系。所谓读万卷书,行万里路;         人们要想得到工作的胜利即得到预想的结果,一定要使自己的思想合于客观外界的规律性,若不合,就会在...
  • ggf123456789
  • ggf123456789
  • 2013年02月11日 10:23
  • 2328

为什么开发与测试老掐架呢

让我们思考几个常见的问题:软件测试的目的是什么?开发人员能否构建出没有Bug的完美软件?测人人员和开发人员:……...
  • foruok
  • foruok
  • 2016年04月11日 07:22
  • 11637

【Qt5开发及实例】19、一个简单的画图程序

一个简单的画图程序 Qt的双缓冲 双缓冲就是在绘制控件的时候,首先把要绘制的内容放到一个图片上,然后再将图片一次性画到控件上   设计目标     设计步骤   1、绘图区的实现 ...
  • cutter_point
  • cutter_point
  • 2015年01月24日 19:03
  • 8405

构建自己的代码库及软件开发不能是加工作坊--及一个简单的Linux C程序开发框架—linux-dev-framework

对于我这样一个C语言的程序员来说,编写C++的机会其实不太多。但是我还是比较喜欢写C++语言,原因主要有几个方面:(1)自己学C++语言的时间比较长了,也比较了解,如果从大一的时候算起,现在也有小十年...
  • benpaobagzb
  • benpaobagzb
  • 2016年02月29日 21:37
  • 1130

软件开发与项目管理易理——简单项目管理

项目管理中的范围三角包括时间、成本、质量。我们从另一个角度——计划、资源、风险——来观察项目管理。一个项目,首先要有资源,包括人力资源、资金资源、技术资源等;计划指项目实施的时间表,包括各个阶段的资源...
  • donhao
  • donhao
  • 2011年01月24日 21:31
  • 718

软件开发与项目管理易理——简单与灵活

“是故百战百胜,非善之善者也;不战而屈人之兵,善之善者也。” ——《孙子兵法·谋攻篇》一场战役,以多胜少与以少胜多相比,后者更为胜。软件开发犹如一场战役,投入的资源好比是兵马,所要开发的软件好比是要打...
  • donhao
  • donhao
  • 2011年01月30日 13:47
  • 485

Android软件开发之通讯录——添加联系人以及SQLite工具的简单使用

关于通讯录获取联系人信息以及联系人信息的存储结构,下面链接的博客的博主已经简单说明: http://blog.csdn.net/snwrking/article/detail/7601794 --...
  • Poulfei
  • Poulfei
  • 2016年04月27日 15:10
  • 2075

简单的C/S结构软件开发笔记(1)——环境与c#链接数据库

环境搭建应用VS2008及SQL server进行开发。关于vs2008自带sql server 2005的问题 使用windos用户验证方式 的数据库服务名是 计算机名\SQLEXPRESS...
  • Intangible_moon
  • Intangible_moon
  • 2016年12月28日 17:07
  • 427

简单之美——软件开发实践者的思考

  • 2012年11月06日 08:46
  • 6.77MB
  • 下载

《简单之美——软件开发实践者的思考》

  • 2011年01月18日 18:21
  • 5.79MB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:软件开发中的矛盾——一个简单的例子
举报原因:
原因补充:

(最多只允许输入30个字)