Board logo

Subject: 对代码的建议。 [Print This Page]

Author: leeon    Time: 2003-12-9 20:23     Subject: 对代码的建议。

编程大师如是说:

  一个程序应当是轻盈的、灵活的,它的子程序就像一串珍珠一样连接着。它的精神和意图应该贯穿始终。在程序中,内容既不应太多,也不应太少;既不应该有不需要的循环结构,也不该有冗余的变量;既不缺乏结构性,又不过分僵化。



我实在很喜欢这个开发包,它凝结大家的智慧和精华,可能我这个人有点完美主义,嘿嘿。比如组件选取专家,我经常用这个,因为我弄的界面真的很乱。我也看看代码,不过重复的地方不少,我有个习惯,如果一组代码重复出现两次,我就定义一个方法来用。

如选取某一个字段的时候,两个ListBox之间的ADD和Delete其实是一样的。

procedure TCnComponentSelectorForm.actDeleteExecute(Sender: TObject);
var
  i: Integer;
begin
  BeginUpdateList;
  try
    for i := 0 to lbDest.Items.Count - 1 do // 只有当前过滤列表中有的才加入到左边
      if lbDest.Selected[i] and (CurrList.IndexOf(lbDest.Items[i]) >= 0) then
        lbSource.Items.AddObject(lbDest.Items[i], lbDest.Items.Objects[i]);
    for i := lbDest.Items.Count - 1 downto 0 do
      if lbDest.Selected[i] then
        lbDest.Items.Delete(i);
  finally
    UpdateSourceOrders;
    EndUpdateList;
  end;
end;

只不过处理的对象对调了,那就弄一个方法如下:

procedure MoveFieldToOther(aLstSource, aLstDest: TListBox);
var
  i: Integer;
begin
  BeginUpdateList;
  try
    for i := 0 to aLstSource.Items.Count - 1 do // 只有当前过滤列表中有的才加入到左边
      if aLstSource.Selected[i] and (CurrList.IndexOf(aLstSource.Items[i]) >= 0) then
        aLstDest.Items.AddObject(aLstSource.Items[i], aLstSource.Items.Objects[i]);
    for i := aLstSource.Items.Count - 1 downto 0 do
      if aLstSource.Selected[i] then
        aLstSource.Items.Delete(i);
  finally
    UpdateSourceOrders;
    EndUpdateList;
  end;
end;

调用的时候

需要这么写而已

add的Action

MoveFieldToOther(lbSource, lbDest: TListBox);

delete的Action

MoveFieldToOther(lbDest, lbSource: TListBox);

是的,有一些小区别,(CurrList.IndexOf(aLstSource.Items[i]) >= 0)

但是区别不大,那可以用开关参数定义他们。

是的,类似上面所说:上下移动的方法也是有重复的。写成方法主要是减少代码量,代码重复copy,以及最大的优点就是,能一定的防止代码写错。易于管理。

正如编程大师所说:它的子程序就像一串珍珠一样连接着。

而且我相信,以后对于两个ListBox相互移动的地方肯定不少,为什么不定好几个方法呢。

定义好了一些方法扔到另一个pas文件里面,然后主窗体调用,这样就做到了UI分离了。

嘿嘿,一点小建议。

[ 本贴由 leeon 于 2003-12-9 20:59 最后编辑 ]
Author: zjy    Time: 2003-12-10 21:45

非常感谢!

以前我一直认为自己已经是比较追求完美的程序员了,没想到最近又见识了很多更追求完美的人,汗颜。。。

组件选择专家是我一年前写的了,感觉一年来虽然也有些进步,但代码编写方面好象变化不大:(

如果您有兴趣,不如您来优化改进吧?如果没空,就还是我们来改吧。
Author: shenloqi    Time: 2003-12-12 16:04

说一下我现在的看法(不是针对这个例子的,只是提到这个方面就随便说说。关于ListBox等的常用函数在RxLib中早就有现成的封装了,我个人如果要使用的话,一般也会考虑这些现成的东西:)自己也是没有办法的时候才写):
很多东西,我们需要的是一个新的函数(或对象的方法)而不是复制代码,但是对于一些特殊的地方,我觉得不见得非要追求所谓的简洁而强行封装,比如说关于开关,少量的开关的确是可以为函数增加应用的范围,但是在函数设计之初就能够考虑到那么多的应用范围么?而且开关的增加也会导致理解的复杂度,我个人现在的做法是采用set来处理这种问题,而且尽量少使用重载。
Author: leeon    Time: 2003-12-12 17:26

嗬嗬,讨论是必须的而且有成效的,我喜欢把相同的或者相近的代码放在一起,不在控件的各个事件里面写大量的代码,而是易于理解和管理的过程,如果写过多的代码,不易于管理。

我说的仅仅是一个开发习惯而已。不是考虑的范围,随着看新同事的代码越多,我对我的开发习惯感到很自信。我花的时间比他们少,效率却比他们高。:〉

相同的代码多了,写成子函数,子函数多了弄个子文件。这样就是模块化设计了。处理相同数据类型的函数封装在一个类里面,就由模块化组成为了对象化。尽管大的方面需要对象化。但是小的方面,用的多的,还是模块化的设计。模块化的设计会让自己的思路清晰明了。

就像写字,就像弹琴。当适应了规范化之后才是无规范无序无模式的使用。写字就如楷书到行书,弹琴就如有调式曲子到无调式即兴的演奏。其实看上去无规范的东西还是有规范的习惯。外形不规范,其实里面还是规范的,因为已经形成了习惯。

有些东西相通的,写代码给我的感觉可以用写字来类比,好的开发习惯,会省却很多时间,而且能写得更出色。

其实习惯真得很可怕,用在好的地方倒是好,但是一旦成为坏习惯……而且习惯几乎没有折中的地步,就是好与坏两个极端。

所以说荀子说得很好:君子博学而日参省乎己,则知明而行无过矣。

有关代码优化,不过最近十天太忙,几乎天天都得和组件选取这个小工具打交道几十次,真得很方便,以前用Shift选啊选啊…… 如果失败了就惨不忍睹了!现在好了,大大节省时间,就这么一个小东西而已。嘿嘿,真的很喜欢。真的非常感激这个小东西。
Author: leeon    Time: 2003-12-12 21:52

我现在用空闲时间优化一下那个组件选取专家的代码,

嘿嘿,苦活我来干干吧。算是做一些贡献。
Author: leeon    Time: 2003-12-13 18:37

已经优化组件选取专家的部分代码。我花了今天整整一天。

嘿嘿,我感觉我的上司都快被我气死了。

他是个很开朗的人,不过这个项目确实很急。:〉

YYGW,代码我已经通过Email给你发过去了,你看看如何。

等我有空闲时间的时候再看看,我经常Check out代码看看。

                                      cheers
Author: zjy    Time: 2003-12-14 01:02

多谢多谢!!

还是工作要紧,不过有时候我也是这样,工作上太烦闷了,就写一下 CnPack 当作调剂,呵呵:)
Author: leeon    Time: 2003-12-14 10:05

嗬嗬,看看我写的是否符合你们的规范吗?

我准备把ListBox改成ListView,你的排序可能就不需要了。

只是今天早上在床上的打算。。。。。。




Welcome to CnPack Forum (http://bbs.cnpack.org/) Powered by Discuz! 5.0.0