Delphi更高效率的编程方式的思考【二】

  谈论了很多关于目前环境的话题,现在是否可以开始讨论主要的题目了?

  好吧,是需要理清楚思路的。

  在开发里面,我常常在想,如何提高编程的速度和编程的质量。

  我考虑了面向对象的模式,但是我发现,它并不能够解决任何问题,相反会带来很多问题。

  于是我把编程开发提升到设计开发上面,效率会如何呢,我们来看下。

  姑且不讨论这种模式的各方面问题。

  因为有美术设计的经验,我们是否可以借鉴一下设计的模式来设计编程开发???

  首先我们定义概念,这个是个什么样的软件,功能定性?或者是市场定性??

  针对什么样子的市场???居于什么样的概念???

  很复杂,算了,简单一点。

  说功能。

  一个软件包含很多功能,这些功能主要处理各种问题,对吧。

  于是我们得出,软件里面分出主模块和次模块。

  主模块是程序整个运行的主要功能表现。次模块主要处理主模块在运行的时候会遇到的各种情况。

  于是我们就可以采用思维导图的模式来建模了。

  把主模块画出来,然后画次模块逻辑。

  整个流程都绘制出来了,详细标注各个模块的特性。

  之后,按照整个流程图进行代码编码,把软件制作出来。

  可是,这个跟高效开发显然不太贴边啊,因为最后你还要大量大量地编写各种代码。

  显然我们只是做了大多数时候做的事情,并没有解决任何实质性的东西。

  累还是累。

  显然,我们还得在上面的思维导图里面抽象出或者说归纳出共享的模块,这样就减小了代码的重复编写。

  另外我们把初始化的变量分出来作为一个结构,使用它的指针方式,运行后,释放掉这部分的内存。

  涉及到次处理窗体,采用动态创建的方式,这样可以随时释放该对象。

  显然这些做法只是针对资源处理,但是有了这些前提就能够优化我们的程序设计,对吧。

  于是,我们又把功能模块设计提升到逻辑设计上面,对不??

  最后的结果是,按照资源的合理分配和逻辑功能的特点进行整个程序的框架设计。

  于是,我们按照具体的流程把代码编写出来,最后完成。

  这样会不会快很多????

  对于一些人来说,万一客户需求改变呢?整个时候如何处理??

  显然,程序模块功能的抽象性,还是要的。它应该是处理这些某种状态下的功能,而不指定很固定的状态。

  这些不是模式编程,而是模态编程。就好像无类型指针,你可以传入任何对象的指针,而不指定特定的对象,而处理呢,就必须处理跟对象有关的逻辑了,显然还是带有一定范围限制的,对吧。

  Delphi有种模式叫做匿名函数。我们看看它的具体实现是什么一回事,我们是否需要它。

  我感觉这个功能很实用,现在转载一下万一的【Delphi 2009 中的匿名方法(reference to)】

  地址是:http://www.cnblogs.com/del/archive/2008/08/15/1268301.html

  1 之前我们可以定义方法类型, 然后通过方法类型的变量来使用方法, 譬如:
  2 --------------------------------------------------------------------------------
  3  
  4 unit Unit1;
  5 
  6 interface
  7 
  8 uses
  9   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 10   Dialogs;
 11 
 12 type
 13   TForm1 = class(TForm)
 14     procedure FormCreate(Sender: TObject);
 15   end;
 16 
 17 var
 18   Form1: TForm1;
 19 
 20 implementation
 21 
 22 {$R *.dfm}
 23 
 24 Type
 25   TFun = function(const num: Integer): Integer; {先定义一个方法类型}
 26 
 27   function MySqr(const num: Integer): Integer;  {再创建一个吻合上面类型的一个方法}
 28   begin
 29     Result := num * num;
 30   end;
 31 
 32 {测试}
 33 procedure TForm1.FormCreate(Sender: TObject);
 34 var
 35   fun: TFun;  {方法变量}
 36   n: Integer;
 37 begin
 38   fun := MySqr;             {给变量赋值为相同格式的方法}
 39   n := fun(9);              {现在这个方法变量可以使用了}
 40   ShowMessage(IntToStr(n)); {81}
 41 end;
 42 
 43 end.
 44 ----------------------------之所以这样做, 是因为有时需要把 "方法" 当作参数, 譬如:
 45 --------------------------------------------------------------------------------
 46  
 47 unit Unit1;
 48 
 49 interface
 50 
 51 uses
 52   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 53   Dialogs;
 54 
 55 type
 56   TForm1 = class(TForm)
 57     procedure FormCreate(Sender: TObject);
 58   end;
 59 
 60 var
 61   Form1: TForm1;
 62 
 63 implementation
 64 
 65 {$R *.dfm}
 66 
 67 Type
 68   TFun = function(const num: Integer): Integer; {先定义一个方法类型}
 69 
 70   function MySqr(const num: Integer): Integer;  {再创建一个吻合上面类型的一个方法}
 71   begin
 72     Result := num * num;
 73   end;
 74 
 75   {把方法当作参数的方法}
 76   procedure MyProc(var x: Integer; fun: TFun);
 77   begin
 78     x := fun(x);
 79   end;
 80 
 81 {测试}
 82 procedure TForm1.FormCreate(Sender: TObject);
 83 var
 84   n: Integer;
 85 begin
 86   n := 9;
 87   MyProc(n, MySqr);
 88   ShowMessage(IntToStr(n)); {81}
 89 end;
 90 
 91 end.
 92 -------------现在 Delphi 2009 可以使用匿名方法了(使用 reference 定义方法类型, 然后在代码中随用随写方法), 譬如:
 93 --------------------------------------------------------------------------------
 94  
 95 unit Unit1;
 96 
 97 interface
 98 
 99 uses
100   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
101   Dialogs;
102 
103 type
104   TForm1 = class(TForm)
105     procedure FormCreate(Sender: TObject);
106   end;
107 
108 var
109   Form1: TForm1;
110 
111 implementation
112 
113 {$R *.dfm}
114 
115 Type
116   TFun = reference to function(const num: Integer): Integer; {用 reference 定义匿名方法类型}
117 
118 procedure TForm1.FormCreate(Sender: TObject);
119 var
120   fun: TFun;
121   n: Integer;
122 begin
123   {求平方}
124   fun := function(const a: Integer): Integer {注意本行最后不能有 ; 号}
125   begin
126     Result := a * a;
127   end;
128 
129   n := fun(9);
130   ShowMessage(IntToStr(n)); {81}
131 
132   {求倍数}
133   fun := function(const a: Integer): Integer
134   begin
135     Result := a + a;
136   end;
137 
138   n := fun(9);
139   ShowMessage(IntToStr(n)); {18}
140 end;
141 
142 end.
143 --------------------------------------------------------------------------------把匿名方法当作其他方法的参数:
144 --------------------------------------------------------------------------------
145  
146 unit Unit1;
147 
148 interface
149 
150 uses
151   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
152   Dialogs;
153 
154 type
155   TForm1 = class(TForm)
156     procedure FormCreate(Sender: TObject);
157   end;
158 
159 var
160   Form1: TForm1;
161 
162 implementation
163 
164 {$R *.dfm}
165 
166 Type
167   TFun = reference to function(const num: Integer): Integer;
168 
169   function FunTest(const n: Integer; fun: TFun): string;
170   begin
171     Result := Format('%d, %d', [n, fun(n)]);
172   end;
173 
174 procedure TForm1.FormCreate(Sender: TObject);
175 var
176   f: TFun;
177   s: string;
178 begin
179   f := function(const a: Integer): Integer {注意本行最后不能有 ; 号}
180   begin
181     Result := a * a;
182   end;
183 
184   s := FunTest(9, f);
185 
186   ShowMessage(s); {9, 81}
187 end;
188 
189 end.

  如果采用这种方式,由于函数处理方式的不同,那么最终输出的结果显然是不同的,而你输出的函数可以带几种不同功能的“函数参数”,所以我认为这种方式有利于函数功能多态实现的功能。

  这种想法的确很伟大,性能如何,未知。呵呵。

  如果只是为了减少主模块的代码编写,也可以采用一条函数作为调用函数的主函数体,然后按照传入的参数来决定调用那个函数,这样会怎么样??

  

1 procedure MySelf(Const Value:Integer);
2 begin
3      Case  Value of
4        0:  MyProc(n, MySqr);
5        1:  MyProc(M, NewSqr);
6        3: ...........
7      end;
8 end;

  显然,这些没有面向对象的东西,没有继承,但是有多态。

  然而采用这种方式,会导致程序缺乏具体的语义性,如果不加以注释,很难令人明白函数的意义。

  类型化还是需要的,合适的类的编写还是需要,记住不要排斥任何已有的经验。

  编程是利用你掌握的东西来架构你认为合适的模块。而不是去重新学习东西。

  我们看了很多文章,很多作者不是在引导我们提高编程效率,而大多数在叫我们去学习他的模式。

  而大多数的情况是,这些浪费了我们大量的精力和时间。

  我们 需要你在提出问题,然后告诉我们解决方案,而不是去了解你的哲学。

  你的哲学没有什么是可以学习的,清楚就好。

  所以这些要说清楚的是:这些不需要你学习什么,你可以了解我们的编程思路,就那么多。

  

  通常情况下,当我们声明一个对象,系统就得为我们分配该对象拥有的成员变量和函数所需要的内存开销。

  是不是这样???

  那么就是说,不管需要的或者不需要的,凡是涉及的变量和函数都必须分到一块内存,对不对??

  那么就是说,很多时候,我们需要的只是该对象很少的功能,或者只有一两个功能,显然我们得为这些功能付出大量的代价??

  是不是这样???

  那么在调用这些对象方法的时候,系统需要通过该对象的指针,它本来就是指针,然后才寻址到调用函数的内存地址上面,之后才运行。

  需要一些CPU的时间开销,是不是这样????

  如果当前对象没有该函数代码,就需要到父类去寻找,是不是这样???

  如果当时没有为这个函数开辟内存那么寻找到后,是否需要为它开辟内存,应该开辟吧,没有内存,你运行啥啊???

  是不是这样?

  如果当前的父类没有,就得到父类的父类里面去找,哈哈,真过瘾。

  是不是这样??

  太复杂了。呵呵。

  如果这些都是事实,那么在编写类型的时候,是否需要注意各个模块尽量紧凑一些,不要过于分散。

  其实还是没有解决我们的问题。

  还要思考啊。