以下代码,想用多态方式来替换if else,网上说的最多的是 if 判断的时候是判断类(class)的类型
而非整形或者数字类型。
如果 if 判断的是类类型,确实容易用多态实现。
下面的例子是整型值判断。我想求教下各位,这样能不能用多态的方式实现,或者给写建议,谢谢各位了
procedure TForm1.proc1();
begin
ShowMessage('proc1');
end;procedure TForm1.proc2();
begin
ShowMessage('proc2');
end;procedure TForm1.proc3();
begin
ShowMessage('proc3');
end;procedure TForm1.ExtractedMethod1;
begin
if ComboBox1.ItemIndex = 0 then
begin
proc1;
end
else if ComboBox1.ItemIndex = 1 then
begin
proc2;
end
else if ComboBox1.ItemIndex = 2 then
begin
proc3;
end;
end;
而非整形或者数字类型。
如果 if 判断的是类类型,确实容易用多态实现。
下面的例子是整型值判断。我想求教下各位,这样能不能用多态的方式实现,或者给写建议,谢谢各位了
procedure TForm1.proc1();
begin
ShowMessage('proc1');
end;procedure TForm1.proc2();
begin
ShowMessage('proc2');
end;procedure TForm1.proc3();
begin
ShowMessage('proc3');
end;procedure TForm1.ExtractedMethod1;
begin
if ComboBox1.ItemIndex = 0 then
begin
proc1;
end
else if ComboBox1.ItemIndex = 1 then
begin
proc2;
end
else if ComboBox1.ItemIndex = 2 then
begin
proc3;
end;
end;
procedure proc(index:integer);
Begin
case index of
0:;
1:;
end;
end;
判断index值就可以了。如果感觉index不直观,可以声明成枚举类型。
1 可以看成网络控制
2 可以看成USB控制这些控制的实现都是比较复杂的,另外程序的很多地方都用到了类似的判断。所有我想做些重构,先从if判断开始。可能我是为了重构而重构,不过程序的代码有比较多的地方有用到同一判断,只是这些判断是作为其他函数的一部分。
TCustomExternalController = class(TObject)
protected
procedure Step1; virtual; abstract;
procedure Step2; virtual; abstract;
.... //自己按需要加方法,这里只是随便给个例子
public
procedure Execute;
end; TNetController = class(TCustomExternalController)
protected
procedure Step1; override;
procedure Step2; override;
end; TUSBController = class(TCustomExternalController)
protected
procedure Step1; override;
procedure Step2; override;
end; TSerialPortController = class(TCustomExternalController)
protected
procedure Step1; override;
procedure Step2; override;
end;implementationprocedure TCustomExternalController.Execute;
begin
//如果这些东西执行的过程类似,可以把执行过程抽象到这个方法里,子类覆盖具体步骤即可
//关键字:模板模式。可参考TStream的实现方式。
Step1;
Step2;
end;
var
AList: TObjectList;
i: integer;
begin
AList := TObjectList.Create; //关闭窗体时自己释放掉这个LIST
AList.Add(TSerialPortController.Create);
AList.Add(TUSBController.Create);
AList.Add(TNetController.Create);
for i := 0 to ComboBox.Count - 1 do
ComboBox.Items.Objects[i] := AList[i];
end;
procedure ComboBox.OnSelect(Sender: TObject);
begin
(ComboBox.Items.Objects[ComboBox.ItemIndex] as TCustomExternalController).Execute;
end;
一般思路就是这样!
1.
先写一个抽象类,来抽取子类的公用功能、公用函数以及公有成员(做成抽象类就是为了使终端程序员不要实现这个类,实现也没什么意义)
2.子类继承抽象类
3.应用反射机制,直接用Combobox中的名字生成对象
Harryfin
我一会儿去单位看下。
p:array [1..3] of TProcedure; //定义指向过程的指针数组
...
初始化数组:
p[1]:= @TForm1.proc1;
p[2]:= @TForm1.proc2;
p[3]:= @TForm1.proc3;
...
调用:
p[ComboBox1.ItemIndex+1];
1.非常感谢,你的设计和精妙,说实话我是似曾看过,好像是第三方控件里看到过类似的写法。
2.TypeInfo真的需要好好学习了,谢谢你的建议
感谢你的面向过程的设计来解决问题,不过我还是希望多态的方式来实现,目的是为了学习。
楼上Harryfin和liangpei2008的回答已经可以解决我的问题,非常感谢!